diff options
596 files changed, 27258 insertions, 3021 deletions
diff --git a/.gitlab/issue_templates/default.md b/.gitlab/issue_templates/default.md new file mode 100644 index 00000000..bca6c09e --- /dev/null +++ b/.gitlab/issue_templates/default.md @@ -0,0 +1,2 @@ +**Please use https://jira.automotivelinux.org for issues.** +See also: https://docs.automotivelinux.org/ chapter "How to contribute". diff --git a/.gitlab/issue_templates/mytemplate.md b/.gitlab/issue_templates/mytemplate.md new file mode 100644 index 00000000..25d91d81 --- /dev/null +++ b/.gitlab/issue_templates/mytemplate.md @@ -0,0 +1,3 @@ +**Please use https://gerrit.automotivelinux.org for code contributions.** +See also: https://docs.automotivelinux.org/ chapter "How to contribute". + diff --git a/.gitlab/merge_request_templates/default.md b/.gitlab/merge_request_templates/default.md new file mode 100644 index 00000000..5b02effe --- /dev/null +++ b/.gitlab/merge_request_templates/default.md @@ -0,0 +1,2 @@ +**Please use https://gerrit.automotivelinux.org for code contributions.** +See also: https://docs.automotivelinux.org/ chapter "How to contribute". diff --git a/.gitlab/merge_request_templates/mytemplate.md b/.gitlab/merge_request_templates/mytemplate.md new file mode 100644 index 00000000..25d91d81 --- /dev/null +++ b/.gitlab/merge_request_templates/mytemplate.md @@ -0,0 +1,3 @@ +**Please use https://gerrit.automotivelinux.org for code contributions.** +See also: https://docs.automotivelinux.org/ chapter "How to contribute". + diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..e8758f89 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Different components of the AGL layers are under different licenses (a mix +of MIT and GPLv2). See LICENSE.GPL-2.0-only and LICENSE.MIT for further +details of the individual licenses. + +All metadata (e.g. .bb, .bbappend, .bbclass, .inc, templates/* and similar) +is MIT licensed unless otherwise stated. +Source code included in tree for individual recipes (e.g. patches) are under +the LICENSE stated in the associated recipe (.bb file) unless otherwise stated. + +License information for any other files (scripts) is either explicitly stated +or defaults to GPL version 2 only. + +Individual files can contain the following style tags instead of the full +license text to identify their license: + + SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: MIT + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ diff --git a/LICENSE.GPL-2.0-only b/LICENSE.GPL-2.0-only new file mode 100644 index 00000000..5db3c0a2 --- /dev/null +++ b/LICENSE.GPL-2.0-only @@ -0,0 +1,288 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + +Note: +Individual files contain the following tag instead of the full license text. + + SPDX-License-Identifier: GPL-2.0-only + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ diff --git a/LICENSE.MIT b/LICENSE.MIT new file mode 100644 index 00000000..a6919eb7 --- /dev/null +++ b/LICENSE.MIT @@ -0,0 +1,25 @@ +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. + +Note: +Individual files contain the following tag instead of the full license text. + + SPDX-License-Identifier: MIT + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ @@ -0,0 +1 @@ +README.md
\ No newline at end of file diff --git a/README.md b/README.md index 847c773b..aa4823c5 100644..120000 --- a/README.md +++ b/README.md @@ -1,161 +1 @@ -**README.md for the 'meta-agl-demo' layer.** - -**See README-AGL.md for general information about Automotive Grade Linux.** - - -meta-agl-demo, the reference UI layer for the DEMO platform of Automotive Grade Linux -================================================================================= - -The layer 'meta-agl-demo' provides a reference/demo platform and applications -for the AGL Distribution. - -AGL is creating an automotive specific Linux distribution (AGL UCB) that unifies -the software that has been written in a number of places already, -such as GENIVI and Tizen IVI. - -The AGL community appreciates feedback, ideas, suggestion, bugs and -documentation just as much as code. Please join the irc conversation -at the #automotive channel on irc.freenode.net and our mailing list. - -For infomation for subscribing to the mailing list - [automotive-discussions](http://lists.linuxfoundation.org/mailman/listinfo/automotive-discussions) -For information about AGL Distribution, see the - [AGL Distribution](https://wiki.automotivelinux.org/agl-distro) -For information abount Getting started with AGL - [here](https://wiki.automotivelinux.org/start/getting-started) -For information about contributing to the AGL Distro - [here](https://wiki.automotivelinux.org/agl-distro/contributing) - - -Quick start guide ------------------ -See README-AGL.md - - -Layer Dependencies ------------------- - -* Base dependencies [agl-demo]: - -URI: git://git.yoctoproject.org/poky -> branch : jethro -> tested revision: 40376446904ae3529be41737fed9a0b650ed167d - -URI: https://gerrit.automotivelinux.org/gerrit/AGL/meta-agl -> branch: master - -URI: git://git.openembedded.org/meta-openembedded -> layer : meta-openembedded -> branch : jethro -> tested revision: 8ab04afbffb4bc5184cfe0655049de6f44269990 - -Specifically out of meta-openembedded these sub-layers are used: - - - meta-openembedded/meta-oe - - meta-openembedded/meta-multimedia - - meta-openembedded/meta-efl - - meta-openembedded/meta-networking - - meta-openembedded/meta-python - - meta-openembedded/meta-ruby - -URI: https://github.com/meta-qt5/meta-qt5.git -> branch: jethro (b/c of qt-5.5.x) -> tested revision: ea37a0bc987aa9484937ad68f762b4657c198617 - -* Hardware dependencies: - -The Renesas R-Car Gen2 (Porter) board depends in addition on: - -URI: https://gerrit.automotivelinux.org/gerrit/AGL/meta-renesas -> branch: agl-1.0-bsp-1.8.0 -> tested revision: 82611ccadef36ab0b8a6fd6fb1cf055e115f1ef5 -> (or later) - -* Extra feature dependencies: - - * The feature `agl-appfw-smack` has these dependencies - * `meta-intel-iot-security` - > URI: https://github.com/01org/meta-intel-iot-security - > branch : jethro - > tested revision: c5906a1553513ef192a58231700357c5f14f4ae4 - - * `meta-agl-extra/meta-app-framework` - > URI: https://gerrit.automotivelinux.org/gerrit/gitweb?p=AGL/meta-agl-extra.git - > branch : master - - * The feature `agl-sota` has these dependencies: - * `meta-updater` - > URI: https://github.com/advancedtelematic/meta-updater/ - > branch : thud - > tested revision: e4dd74565f429b576e84972d12cc1ae2048be119 - - * `meta-updater-qemux86-64` - > URI: https://github.com/advancedtelematic/meta-updater-qemux86-64/ - > branch : thud - > tested revision: 214e14c4c45625842e542eebd696f903060d488f - - * `meta-openembedded` - > layer : meta-openembedded - > branch : thud - > tested revision: 9b3b907f30b0d5b92d58c7e68289184fda733d3e - - * specifically: - * `meta-openembedded/meta-filesystems` - * `meta-openembedded/meta-oe` - * `meta-openembedded/meta-python` - - * The feature `agl-netboot` has these dependenies: - * `meta-agl/meta-netboot` - - > URI: https://gerrit.automotivelinux.org/gerrit/gitweb?p=AGL/meta-agl.git - > branch : master - - -Packagegroups -------------- - -AGL Demo Platform's package group design: - -* packagegroup-agl-demo-platform - -This is for generating the image 'agl-demo-platform' which is a full image -for the IVI profile of the AGL distro. - -As meta-agl's design of packagegroups, ``agl-demo-platform.bb`` contains -only ``packagegroup-agl-demo-platform`` and the packages of the DEMO applications. - -``agl-demo-platform`` has 4 packagegroups in it, -``packagegroup-agl-image-minimal``, ``packagegroup-agl-image-ivi``, -``packagegroup-ivi-common-core``, and ``packagegroup-agl-demo-platform``. - -* packagegroup-agl-appfw* - -These packagegroups contains packages for application framework of AGL Distro. -Subsystem should maintain ``packagegroup-agl-appfw-[subsystem].bb`` which -should hold sufficient packages for application framework of AGL Distro. - -Subsystems also can maintain their own packagegroups under appropriate -``recipes-*/``. - -For example, Qt5 has 2 packagegroups in ``meta-agl-demo``, -``packagegroup-agl-appfw-native-qt5`` and ``packagegroup-agl-demo-qt-examples`` -which are under ``recipes-qt/``. - -The ``packagegroup-agl-appfw-native-qt5`` is included by -``packagegroup-agl-appfw-native`` because Qt5 belongs to native application -framework of AGL Distro. - -The ``packagegroup-agl-demo-qt-examples`` is added to local.conf if needed -because they are not mandatory for AGL application framework and AGL Demo -Platform. - -Supported Machines ------------------- - -See `README-AGL.md` in meta-agl layer. - -Supported Target of bitbake ------------------------- - -* `agl-demo-platform` is the full image of the AGL Demo Platform with all applications - +meta-agl-demo.md
\ No newline at end of file diff --git a/classes/agl-graphical.bbclass b/classes/agl-graphical.bbclass new file mode 100644 index 00000000..8b5fbf6b --- /dev/null +++ b/classes/agl-graphical.bbclass @@ -0,0 +1,5 @@ +WESTONUSER ??= "display" +WESTONGROUP ??= "display" +WESTONARGS ?= "--idle-time=0 --tty=7" +WESTONLAUNCHARGS ??= "--tty /dev/tty7 --user ${WESTONUSER}" +DISPLAY_XDG_RUNTIME_DIR ??= "/run/platform/${WESTONUSER}" diff --git a/conf/include/agl-container-guest-demo.inc b/conf/include/agl-container-guest-demo.inc new file mode 100644 index 00000000..9c3e19e0 --- /dev/null +++ b/conf/include/agl-container-guest-demo.inc @@ -0,0 +1,5 @@ +# enable the extention +AGL_FEATURES:append = " agl-container-guest-demo" +AGL_DEFAULT_IMAGE_FSTYPES = "" +AGL_EXTRA_IMAGE_FSTYPES:append = " ext4" +VIRTUAL-RUNTIME_rngd = "" diff --git a/conf/include/agl-demo-preload.inc b/conf/include/agl-demo-preload.inc index a17d1403..23f600cf 100644 --- a/conf/include/agl-demo-preload.inc +++ b/conf/include/agl-demo-preload.inc @@ -1,4 +1,4 @@ -DISTRO_FEATURES_append = " agl-demo-preload" +AGL_FEATURES:append = " agl-demo-preload" -# Use demo device mapping for low-can that enables sllin0 -PREFERRED_RPROVIDER_virtual/low-can-dev-mapping = "dev-mapping-demo" +# Demo uses AGL reference hardware, which is CAN FD +CANBUS_NETWORK_CONFIG = "${@bb.utils.contains('AGL_FEATURES', 'agl-refhw-h3', 'canbus-can-fd.network', 'canbus-can.network', d)}" diff --git a/conf/include/agl-demo.inc b/conf/include/agl-demo.inc index 5a70196c..caba58cc 100644 --- a/conf/include/agl-demo.inc +++ b/conf/include/agl-demo.inc @@ -1,7 +1,26 @@ IMAGE_FEATURES =+ "debug-tweaks" -# disable the webruntime -#DISTRO_FEATURES_append = " webruntime " -DISTRO_FEATURES_append = " automount " +DISTRO_FEATURES:append = " automount " -IMAGE_INSTALL_append = " screen mc " +# convenience +IMAGE_INSTALL:append = " screen mc " + +# Include all kernel modules here for ease-of-use during development. +# Note that this is conditional on virtual/kernel not being linux-dummy +# in order to allow building the demo images as containers. +# Comment this out to switch to selecting the kernel modules +# individually. +IMAGE_INSTALL:append = " ${@'kernel-modules' if d.getVar('PREFERRED_PROVIDER_virtual/kernel') != 'linux-dummy' else ''}" + +# enable the layer +AGL_FEATURES:append = " agldemo" + +# install virtualbox drivers for vmdk +#IMAGE_INSTALL:append = "${@bb.utils.contains_any('IMAGE_FSTYPES', 'wic.vmdk wic.vmdk.xz', ' open-vm-tools vboxguestdrivers', '', d)}" + +# It is not clear these definitions affect image generation in a robust +# way, but define them to both show our intent and quiet the warnings +# that get spammed otherwise. +PREFERRED_RPROVIDER_kuksa-val-certificates-ca = "kuksa-certificates-agl" +PREFERRED_RPROVIDER_kuksa-val-certificates-server = "kuksa-certificates-agl" +PREFERRED_RPROVIDER_kuksa-val-certificates-client = "kuksa-certificates-agl" diff --git a/conf/include/agl-kvm.inc b/conf/include/agl-kvm.inc new file mode 100644 index 00000000..fadb345d --- /dev/null +++ b/conf/include/agl-kvm.inc @@ -0,0 +1,15 @@ +DISTRO_FEATURES:append = " virtualization" + +BBMULTICONFIG = "agl-kvm-guest" + +AGL_FEATURES:append = " agl-kvm" + +# Override remote display network configuration to use KVM demo's +# network configuration +REMOTING_OUTPUT_HOST = "172.16.10.3" + +# Override cluster dashboard VIS server host for KVM demo's network +# configuration +CLUSTER_DEMO_VSS_HOSTNAME = "172.16.10.1" + +include mc-conf-${BB_CURRENT_MC}.inc diff --git a/conf/include/mc-conf-agl-kvm-guest.inc b/conf/include/mc-conf-agl-kvm-guest.inc new file mode 100644 index 00000000..6777b2c6 --- /dev/null +++ b/conf/include/mc-conf-agl-kvm-guest.inc @@ -0,0 +1,3 @@ +# Override the default virtio-can configuration, as we do not have +# a backend to be able to use it. +CANBUS_NETWORK_CONFIG:virtio-all = "canbus-can.network" diff --git a/conf/include/mc-conf-default.inc b/conf/include/mc-conf-default.inc new file mode 100644 index 00000000..c60c999b --- /dev/null +++ b/conf/include/mc-conf-default.inc @@ -0,0 +1,3 @@ +# We don't want the app framework bits (specifically the user session) in +# the KVM host image. +AGL_FEATURES:remove = "agl-app-fw" diff --git a/conf/layer.conf b/conf/layer.conf index d62e61b9..7556a864 100644 --- a/conf/layer.conf +++ b/conf/layer.conf @@ -5,8 +5,15 @@ BBPATH =. "${LAYERDIR}:" BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ ${LAYERDIR}/recipes-*/*/*.bbappend" -BBFILE_COLLECTIONS += "agl-demo" -BBFILE_PATTERN_agl-demo = "^${LAYERDIR}/" -BBFILE_PRIORITY_agl-demo = "7" +BBFILE_COLLECTIONS += "agldemo" +BBFILE_PATTERN_agldemo = "^${LAYERDIR}/" +BBFILE_PRIORITY_agldemo = "70" -LAYERSERIES_COMPAT_agl-demo = "zeus" +BBFILES_DYNAMIC += " \ + aglcontainermc:${LAYERDIR}/dynamic-layers/meta-agl-ic-container/*/*/*.bb \ + aglcontainermc:${LAYERDIR}/dynamic-layers/meta-agl-ic-container/*/*/*.bbappend \ +" + +LAYERSERIES_COMPAT_agldemo = "scarthgap" + +LAYERDEPENDS_agldemo = "aglcore qt5-layer openembedded-layer networking-layer multimedia-layer flutter-layer meta-app-framework" diff --git a/conf/multiconfig/agl-kvm-guest.conf b/conf/multiconfig/agl-kvm-guest.conf new file mode 100644 index 00000000..478bc5ff --- /dev/null +++ b/conf/multiconfig/agl-kvm-guest.conf @@ -0,0 +1,24 @@ +TMPDIR = "${TOPDIR}/tmp-${BB_CURRENT_MC}" + +MACHINE = "virtio-aarch64" + +# Avoid parse errors caused by linux-renesas, and all the other +# random bbappends in meta-rcar-gen3. +BBMASK += "meta-rcar-gen3/ meta-rcar-gen3-adas/ meta-agl-refhw-gen3/" + +DISTRO_FEATURES:append = " kvm virtualization" + +# Use our own wks file +WKS_FILE = "directdisk.wks.in" + +# We only need ext4 images for guests for now +AGL_DEFAULT_IMAGE_FSTYPES = "ext4" +AGL_EXTRA_IMAGE_FSTYPES = "" + +# Need to run QEMU with virtio-gpu device +#PACKAGECONFIG:append:pn-qemu-system-native = " virglrenderer glx gtk+" +PACKAGECONFIG:append:pn-qemu-system-target = " virglrenderer glx" + +# Until aglsetup.sh potentially changes to split features per multiconfig, +# remove problematic ones from the host build here +AGL_FEATURES:remove = "agl-refhw-h3" diff --git a/docs/devguides-book.yml b/docs/devguides-book.yml deleted file mode 100644 index 5a580980..00000000 --- a/docs/devguides-book.yml +++ /dev/null @@ -1,13 +0,0 @@ -type: books -books: -- - id: meta-agl-demo - title: Meta AGL Demo - description: Meta AGL Demo documentation - keywords: - author: "AGL" - version: master - chapters: - - url: ../meta-agl-demo.md - destination: meta-agl-demo.md - name: meta-agl-demo diff --git a/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/basic.in b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/basic.in new file mode 100644 index 00000000..1fd9f347 --- /dev/null +++ b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/basic.in @@ -0,0 +1,9 @@ +# lxc basic setting +lxc.rootfs.path = dir:/var/lib/machines/ivi-demo +lxc.signal.halt = SIGRTMIN+3 +lxc.signal.reboot = SIGTERM +lxc.uts.name = "ivi" +lxc.tty.max = 1 +lxc.pty.max = 1 +lxc.cap.drop = sys_module mac_admin mac_override sys_time + diff --git a/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/environment.in b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/environment.in new file mode 100644 index 00000000..632252d5 --- /dev/null +++ b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/environment.in @@ -0,0 +1,8 @@ +# lxc environment variable setting +lxc.environment = QT_QPA_PLATFORM=wayland +lxc.environment = QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/plugins/ +lxc.environment = QML_IMPORT_PATH=/usr/lib/qml/ +lxc.environment = QML2_IMPORT_PATH=/usr/lib/qml/ +lxc.environment = QT_WAYLAND_SHELL_INTEGRATION=xdg-shell +lxc.environment = PIPEWIRE_RUNTIME_DIR=/var + diff --git a/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/misc.in b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/misc.in new file mode 100644 index 00000000..9b4f4883 --- /dev/null +++ b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/misc.in @@ -0,0 +1,3 @@ +# lxc misc setting +lxc.start.auto = @LXC_AUTO_START@ + diff --git a/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/mount.in b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/mount.in new file mode 100644 index 00000000..262f09bd --- /dev/null +++ b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/mount.in @@ -0,0 +1,17 @@ +# lxc mount setting +lxc.mount.entry = /var/lib/lxc/ivi-demo/system.conf etc/systemd/system.conf.d/10-environment.conf none bind,optional,create=file + +lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed +lxc.mount.entry = shm /dev/shm tmpfs defaults 0 0 +lxc.mount.entry = /sys/kernel/security sys/kernel/security none ro,bind,optional 0 0 +lxc.mount.entry = tmpfs run tmpfs defaults +lxc.mount.entry = /run/udev/data run/udev/data none ro,bind,optional,create=dir + +lxc.cgroup.devices.allow = c 226:* rwm +lxc.mount.entry = /dev/dri dev/dri none bind,optional,create=dir + +lxc.mount.entry = /run/drm-lease-manager/lease-ivi var/display/drm-lease-manager/lease none bind,create=file + +lxc.cgroup.devices.allow = c 13:* rwm +lxc.mount.entry = /dev/input dev/input none bind,optional,create=dir +lxc.mount.entry = /run/pipewire/pipewire-0 var/pipewire-0 none bind,optional,create=file diff --git a/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/network.in b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/network.in new file mode 100644 index 00000000..573f4796 --- /dev/null +++ b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/network.in @@ -0,0 +1,3 @@ +# lxc network setting +lxc.net.0.type = empty + diff --git a/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/system.conf.agl-demo-platform.in b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/system.conf.agl-demo-platform.in new file mode 100644 index 00000000..de7c6cdd --- /dev/null +++ b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform/system.conf.agl-demo-platform.in @@ -0,0 +1,9 @@ +[Manager] +DefaultEnvironment = DLM_RUNTIME_PATH=/var/display/drm-lease-manager +DefaultEnvironment = DRM_LEASE_DEVICE=@DRM_LEASE_DEVICE@ +DefaultEnvironment = QT_QPA_PLATFORM=wayland +DefaultEnvironment = QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/plugins/ +DefaultEnvironment = QML_IMPORT_PATH=/usr/lib/qml/ +DefaultEnvironment = QML2_IMPORT_PATH=/usr/lib/qml/ +DefaultEnvironment = QT_WAYLAND_SHELL_INTEGRATION=xdg-shell +DefaultEnvironment = PIPEWIRE_RUNTIME_DIR=/var diff --git a/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform_1.0.bb b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform_1.0.bb new file mode 100644 index 00000000..049c8ab8 --- /dev/null +++ b/dynamic-layers/meta-agl-ic-container/recipes-container/lxc-config/lxc-config-agl-demo-platform_1.0.bb @@ -0,0 +1,7 @@ +DESCRIPTION = "AGL IVI demo container LXC config" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9" + +inherit lxc-config + +LXC_AUTO_START ??= "0" diff --git a/dynamic-layers/meta-agl-ic-container/recipes-platform/images/agl-lxc-demo-platform.bb b/dynamic-layers/meta-agl-ic-container/recipes-platform/images/agl-lxc-demo-platform.bb new file mode 100644 index 00000000..b8402294 --- /dev/null +++ b/dynamic-layers/meta-agl-ic-container/recipes-platform/images/agl-lxc-demo-platform.bb @@ -0,0 +1,31 @@ +SUMMARY = "LXC host demo image" +LICENSE = "MIT" + +require recipes-platform/images/lxc-host-image-minimal.bb + +CONTAINER_IMAGES ?= "agl-container-cluster:guest-image-cluster-demo \ + agl-container-ivi:agl-demo-platform \ + " + +IMAGE_INSTALL += " \ + kernel-modules \ + alsa-utils \ + packagegroup-pipewire \ + pipewire-ic-ipc \ + wireplumber-config-agl \ +" + +# packages required for network bridge settings via lxc-net +IMAGE_INSTALL += " \ + lxc-networking \ + iptables-modules \ + dnsmasq \ + systemd-netif-config \ + kernel-module-xt-addrtype \ + kernel-module-xt-multiport \ +" + +# network manager to use +VIRTUAL-RUNTIME_net_manager = "systemd" + +IMAGE_INSTALL:append:rcar-gen3 = " kernel-module-gles " diff --git a/meta-agl-demo.md b/meta-agl-demo.md index f7c8adf6..521ebad8 100755 --- a/meta-agl-demo.md +++ b/meta-agl-demo.md @@ -18,7 +18,7 @@ The `meta-agl-demo` layer has the following base dependencies: * Yocto Project Release: - URI: git://git.yoctoproject.org/poky - - Branch: "thud" + - Branch: "dunfell" - Tested Revision: See the [`default.xml`](https://github.com/leon-anavi/AGL-repo/blob/master/default.xml) manifest file for the `AGL-repo` repository for revision information.<br/><br/> @@ -46,20 +46,11 @@ The `meta-agl-demo` layer has the following base dependencies: [OpenEmbedded Layer Index](https://layers.openembedded.org/layerindex/branch/master/layers/): - URI: https://github.com/meta-qt5/meta-qt5.git - - Branch: "thud" + - Branch: "dunfell" - Tested Revision: See the [`default.xml`](https://github.com/leon-anavi/AGL-repo/blob/master/default.xml) manifest file for the `AGL-repo` repository for revision information.<br/><br/> -### Hardware Dependencies - -Aside from the previously listed base dependencies, if you are using a -[supported Renesas board](../getting_started/reference/getting-started/machines/renesas.html) -supported Renesas board, these dependencies exist: - -* AGL's `meta-renesas` Layer: - - - URI: https://gerrit.automotivelinux.org/gerrit/AGL/meta-renesas ### Feature Dependencies @@ -85,17 +76,17 @@ dependencies: * Here Technologies' `meta-updater` Layer: - URI: https://github.com/advancedtelematic/meta-updater/ - - Branch: "thud"<br/><br/> + - Branch: "dunfell"<br/><br/> * Here Technologies' `meta-updater-qemux86-64` Layer: - URI: https://github.com/advancedtelematic/meta-updater-qemux86-64/ - - Branch: "thud"<br/><br/> + - Branch: "dunfell"<br/><br/> * OpenEmbedded's `meta-openembedded` Layer: - URI: https://github.com/openembedded/meta-openembedded - - Branch: "thud" + - Branch: "dunfell" - Tested Revision: See the [`default.xml`](https://github.com/leon-anavi/AGL-repo/blob/master/default.xml) manifest file for the `AGL-repo` repository for revision information. @@ -113,48 +104,13 @@ dependencies: - URI: https://gerrit.automotivelinux.org/gerrit/gitweb?p=AGL/meta-agl.git - Branch: "master" +## Maintenance -## Packagegroups - -AGL DEMO Platform's -[packagegroups](https://www.yoctoproject.org/docs/2.4.4/dev-manual/dev-manual.html#usingpoky-extend-customimage-customtasks) -consist of the following: - -### packagegroup-agl-demo-platform - -This packagegroup is used for generating the `agl-demo-platform` image, -which is the full image for the AGL distributions IVI profile. -You can see the recipe (i.e. `agl-demo-platform.bb`) that installs -the `packagegroup-agl-demo-platform` packagegroup -[here](https://git.automotivelinux.org/AGL/meta-agl-demo/tree/recipes-platform/images/agl-demo-platform.bb). - -As meta-agl's design of packagegroups, the `agl-demo-platform.bb` recipe installs -only `packagegroup-agl-demo-platform` and the packages of the DEMO applications. - -``agl-demo-platform`` contains the following three packagegroups: - - * `packagegroup-agl-image-minimal` - * `packagegroup-agl-image-ivi` - * `packagegroup-agl-demo-platform` - -### packagegroup-agl-appfw* - -These packagegroups contain packages for the AGL distribution's -Application Framework. -Subsystem should maintain `packagegroup-agl-appfw-[subsystem].bb`, which -should hold sufficient packages for the Application Framework. - -Subsystems also can maintain their own packagegroups using appropriate -`recipes-*/`. -For example, Qt5 has two packagegroups in `meta-agl-demo`: -`packagegroup-agl-appfw-native-qt5` and `packagegroup-agl-demo-qt-examples`, -which are under `recipes-qt/`. - -The `packagegroup-agl-appfw-native-qt5` is included by -`packagegroup-agl-appfw-native` because Qt5 belongs to native application -framework of AGL Distro. +All patches must be submitted via the AGL Gerrit instance at +<https://gerrit.automotivelinux.org>. See this wiki page for +details: -Because the `packagegroup-agl-demo-qt-examples` is not mandatory for -the AGL Application Framework and the AGL DEMO, the packagegroup is added -to the layer's `local.conf` file only when needed. +<https://wiki.automotivelinux.org/agl-distro/contributing> +Layer maintainers: +* Jan-Simon Möller <jsmoeller@linuxfoundation.org> diff --git a/recipes-apis/agl-service-can-high-level-viwi/agl-service-can-high-level-viwi.bb b/recipes-apis/agl-service-can-high-level-viwi/agl-service-can-high-level-viwi.bb deleted file mode 100644 index 7cc58dd7..00000000 --- a/recipes-apis/agl-service-can-high-level-viwi/agl-service-can-high-level-viwi.bb +++ /dev/null @@ -1,19 +0,0 @@ -SUMMARY = "High level ViWi service" -DESCRIPTION = "AGL High Level service using ViWi protocol to expose CAN API." -HOMEPAGE = "https://git.automotivelinux.org/apps/agl-service-can-high-level-viwi/" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=5de84541278ea4e62cacfdc0f890c459" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-service-can-high-level-viwi;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "4.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# Run-time dependencies -RDEPENDS_${PN} += "agl-service-can-low-level" - -inherit cmake aglwgt - -AGLWGT_AUTOINSTALL_${PN} := "0" diff --git a/recipes-config/agl-login-manager/agl-login-manager_%.bbappend b/recipes-config/agl-login-manager/agl-login-manager_%.bbappend deleted file mode 100644 index fe3a9031..00000000 --- a/recipes-config/agl-login-manager/agl-login-manager_%.bbappend +++ /dev/null @@ -1 +0,0 @@ -LOGIN_USER ?= "1001" diff --git a/recipes-config/agl-users/agl-users_%.bbappend b/recipes-config/agl-users/agl-users_%.bbappend new file mode 100644 index 00000000..7ed894f0 --- /dev/null +++ b/recipes-config/agl-users/agl-users_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agl-container-guest-demo', 'agl-users_agl-container-guest-demo.inc', '', d)} diff --git a/recipes-config/agl-users/agl-users_agl-container-guest-demo.inc b/recipes-config/agl-users/agl-users_agl-container-guest-demo.inc new file mode 100644 index 00000000..cb21d079 --- /dev/null +++ b/recipes-config/agl-users/agl-users_agl-container-guest-demo.inc @@ -0,0 +1,10 @@ +# Allow input device for agl-driver +GROUPADD_PARAM:${PN} = "\ + --system video ; \ + --system input ; \ + --system pipewire ; \ + -g 1001 agl-driver ; \ +" +USERADD_PARAM:${PN} = "\ + -g 1001 -u 1001 -G video,input,pipewire -o -d /home/agl-driver -m -K PASS_MAX_DAYS=-1 agl-driver ; \ +" diff --git a/recipes-config/cluster-demo-config/cluster-demo-config_1.0.bb b/recipes-config/cluster-demo-config/cluster-demo-config_1.0.bb new file mode 100644 index 00000000..48b7965e --- /dev/null +++ b/recipes-config/cluster-demo-config/cluster-demo-config_1.0.bb @@ -0,0 +1,31 @@ +SUMMARY = "AGL cluster demo configuration file" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI += " \ + file://AGL.conf.default \ + file://AGL.conf.flutter \ +" + +inherit allarch update-alternatives + +do_install() { + install -D -m 0644 ${WORKDIR}/AGL.conf.default ${D}${sysconfdir}/xdg/AGL.conf.default + install -m 0644 ${WORKDIR}/AGL.conf.flutter ${D}${sysconfdir}/xdg/ +} + +ALTERNATIVE_LINK_NAME[AGL.conf] = "${sysconfdir}/xdg/AGL.conf" + +PACKAGE_BEFORE_PN += "${PN}-flutter" + +FILES:${PN} += "${sysconfdir}/xdg/AGL.conf.default" +RPROVIDES:${PN} = "AGL.conf" +RCONFLICTS:${PN} = "${PN}-flutter" +ALTERNATIVE:${PN} = "AGL.conf" +ALTERNATIVE_TARGET_${PN} = "${sysconfdir}/xdg/AGL.conf.default" + +FILES:${PN}-flutter += "${sysconfdir}/xdg/AGL.conf.flutter" +RPROVIDES:${PN}-flutter = "AGL.conf" +RCONFLICTS:${PN}-flutter = "${PN}" +ALTERNATIVE:${PN}-flutter = "AGL.conf" +ALTERNATIVE_TARGET_${PN}-flutter = "${sysconfdir}/xdg/AGL.conf.flutter" diff --git a/recipes-config/cluster-demo-config/files/AGL.conf.default b/recipes-config/cluster-demo-config/files/AGL.conf.default new file mode 100644 index 00000000..dd8a912c --- /dev/null +++ b/recipes-config/cluster-demo-config/files/AGL.conf.default @@ -0,0 +1,2 @@ +[dashboard] +animation=false diff --git a/recipes-config/cluster-demo-config/files/AGL.conf.flutter b/recipes-config/cluster-demo-config/files/AGL.conf.flutter new file mode 100644 index 00000000..dbd9f370 --- /dev/null +++ b/recipes-config/cluster-demo-config/files/AGL.conf.flutter @@ -0,0 +1,2 @@ +[receiver] +geometry=420x472+750,290 diff --git a/recipes-config/cluster-demo-network-config/cluster-demo-network-config_1.0.bb b/recipes-config/cluster-demo-network-config/cluster-demo-network-config_1.0.bb index a5386b40..8d737282 100644 --- a/recipes-config/cluster-demo-network-config/cluster-demo-network-config_1.0.bb +++ b/recipes-config/cluster-demo-network-config/cluster-demo-network-config_1.0.bb @@ -5,19 +5,29 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda inherit systemd allarch -SRC_URI = "file://cluster-demo-network-conf.service" +SRC_URI = "file://cluster-demo-network-conf@.service \ + file://cluster-demo-network-conf.sh \ +" + +# Network device for dedicated connection to cluster +AGL_CLUSTER_NET_DEVICE ?= "eth1" do_configure[noexec] = "1" do_compile[noexec] = "1" do_install() { - # Install cluster demo network configuration service unit + # Install helper script + install -d ${D}${sbindir} + install -m 0755 ${WORKDIR}/cluster-demo-network-conf.sh ${D}${sbindir}/ + + # Install service unit install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/cluster-demo-network-conf.service ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/cluster-demo-network-conf@.service ${D}${systemd_system_unitdir}/ # Add symlink to network.target.wants install -d ${D}${sysconfdir}/systemd/system/network.target.wants - ln -s ${systemd_system_unitdir}/cluster-demo-network-conf.service ${D}${sysconfdir}/systemd/system/network.target.wants/ + ln -s ${systemd_system_unitdir}/cluster-demo-network-conf@.service \ + ${D}${sysconfdir}/systemd/system/network.target.wants/cluster-demo-network-conf@${AGL_CLUSTER_NET_DEVICE}.service } -FILES_${PN} += "${systemd_system_unitdir}" +FILES:${PN} += "${systemd_system_unitdir}" diff --git a/recipes-config/cluster-demo-network-config/files/cluster-demo-network-conf.service b/recipes-config/cluster-demo-network-config/files/cluster-demo-network-conf.service deleted file mode 100644 index 1a6e2d8b..00000000 --- a/recipes-config/cluster-demo-network-config/files/cluster-demo-network-conf.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Configure dedicated link for cluster demo network -After=sys-subsystem-net-devices-eth1.device -Requires=sys-subsystem-net-devices-eth1.device -Before=network.target - -[Service] -# Note that this is done as opposed to using connman as configuring an -# interface on a second network separate from the rest of the interfaces -# is non-trivial in connman and needs further investigation. -ExecStart=/sbin/ifconfig eth1 192.168.20.93 -Type=oneshot - -[Install] -WantedBy=network.target diff --git a/recipes-config/cluster-demo-network-config/files/cluster-demo-network-conf.sh b/recipes-config/cluster-demo-network-config/files/cluster-demo-network-conf.sh new file mode 100644 index 00000000..3f538175 --- /dev/null +++ b/recipes-config/cluster-demo-network-config/files/cluster-demo-network-conf.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +CONNMAN_CONF=/etc/connman/main.conf +CLUSTER_ADDRESS=192.168.20.93 + +if [ -z "$1" ]; then + echo "Usage: $0 <network device>" + exit 1 +fi + +# Need to blacklist given device with connman if it isn't already, +# otherwise connman will over-ride address configuration. +if ! grep '^NetworkInterfaceBlacklist=' ${CONNMAN_CONF} | grep -q $1; then + sed -i "s/^\(NetworkInterfaceBlacklist=.*\)/\1,$1/" ${CONNMAN_CONF} +fi + +/sbin/ifconfig $1 ${CLUSTER_ADDRESS} diff --git a/recipes-config/cluster-demo-network-config/files/cluster-demo-network-conf@.service b/recipes-config/cluster-demo-network-config/files/cluster-demo-network-conf@.service new file mode 100644 index 00000000..5fc29b7a --- /dev/null +++ b/recipes-config/cluster-demo-network-config/files/cluster-demo-network-conf@.service @@ -0,0 +1,12 @@ +[Unit] +Description=Configure dedicated link for cluster demo network +After=sys-subsystem-net-devices-%i.device +Requires=sys-subsystem-net-devices-%i.device +Before=network.target + +[Service] +ExecStart=/usr/sbin/cluster-demo-network-conf.sh %i +Type=oneshot + +[Install] +WantedBy=network.target diff --git a/recipes-config/cluster-demo-simulator/cluster-demo-simulator.bb b/recipes-config/cluster-demo-simulator/cluster-demo-simulator.bb deleted file mode 100644 index 171ea167..00000000 --- a/recipes-config/cluster-demo-simulator/cluster-demo-simulator.bb +++ /dev/null @@ -1,31 +0,0 @@ -DESCRIPTION = "Simulate can messages of a driving car" -LICENSE = "GPLv2" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" - -SRC_URI = "\ - file://cluster-demo-simulator.service \ - file://simple_can_simulator.py \ -" - -inherit systemd - -SYSTEMD_PACKAGES = "${PN}" -SYSTEMD_SERVICE_${PN} = "cluster-demo-simulator.service" -SYSTEMD_AUTO_ENABLE_${PN} = "enable" - -do_configure[noexec] = "1" -do_compile[noexec] = "1" - -do_install() { - install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/cluster-demo-simulator.service ${D}${systemd_system_unitdir} - install -d ${D}${sbindir} - install -m 0755 ${WORKDIR}/simple_can_simulator.py ${D}${sbindir} -} - -FILES_${PN} += "${systemd_system_unitdir}" - -RDEPENDS_${PN} = " \ - can-utils \ - python3 \ -" diff --git a/recipes-config/cluster-demo-simulator/files/cluster-demo-simulator.service b/recipes-config/cluster-demo-simulator/files/cluster-demo-simulator.service deleted file mode 100644 index 04d41c6c..00000000 --- a/recipes-config/cluster-demo-simulator/files/cluster-demo-simulator.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Cluster demo driving simulator -After=sllin-demo.service sllin-demo-virtual.service cluster-lin-bridging.service -Requires=sllin-demo.service sllin-demo-virtual.service cluster-lin-bridging.service - -[Service] -Type=simple -Restart=always -RestartSec=1 -ExecStart=/usr/bin/python3 /usr/sbin/simple_can_simulator.py - -[Install] -WantedBy=multi-user.target diff --git a/recipes-config/cluster-lin-bridging-config/cluster-lin-bridging-config.bb b/recipes-config/cluster-lin-bridging-config/cluster-lin-bridging-config.bb deleted file mode 100644 index 2b6567a7..00000000 --- a/recipes-config/cluster-lin-bridging-config/cluster-lin-bridging-config.bb +++ /dev/null @@ -1,29 +0,0 @@ -DESCRIPTION = "Configure LIN to external CAN bridging" -LICENSE = "GPLv2" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" - -SRC_URI = "\ - file://cluster-lin-bridging.service \ -" - -inherit systemd - -SYSTEMD_PACKAGES = "${PN}" -SYSTEMD_SERVICE_${PN} = "cluster-lin-bridging.service" -SYSTEMD_AUTO_ENABLE_${PN} = "enable" - -do_configure[noexec] = "1" -do_compile[noexec] = "1" - -do_install() { - install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/cluster-lin-bridging.service ${D}${systemd_system_unitdir} -} - -FILES_${PN} += "${systemd_system_unitdir}" - -RDEPENDS_${PN} = " \ - can-utils \ - sllin \ - sllin-virtual \ -" diff --git a/recipes-config/cluster-lin-bridging-config/files/cluster-lin-bridging.service b/recipes-config/cluster-lin-bridging-config/files/cluster-lin-bridging.service deleted file mode 100644 index 1dde3378..00000000 --- a/recipes-config/cluster-lin-bridging-config/files/cluster-lin-bridging.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=LIN to CAN bridging -After=sllin-demo.service sllin-demo-virtual.service -Requires=sllin-demo.service sllin-demo-virtual.service - -[Service] -Type=simple -ExecStart=/usr/bin/candump -s 2 -B can0 sllin0 - -[Install] -WantedBy=multi-user.target diff --git a/recipes-config/dev-mapping-demo/dev-mapping-demo/dev-mapping.conf.demo b/recipes-config/dev-mapping-demo/dev-mapping-demo/dev-mapping.conf.demo deleted file mode 100644 index 93b0a020..00000000 --- a/recipes-config/dev-mapping-demo/dev-mapping-demo/dev-mapping.conf.demo +++ /dev/null @@ -1,6 +0,0 @@ -; Default CAN device mapping -; Format has to follow ini rules key="value", notice " around value. - -[CANbus-mapping] -hs="can0" -ls="sllin0" diff --git a/recipes-config/dev-mapping-demo/dev-mapping-demo_1.0.bb b/recipes-config/dev-mapping-demo/dev-mapping-demo_1.0.bb deleted file mode 100644 index 4a04ce13..00000000 --- a/recipes-config/dev-mapping-demo/dev-mapping-demo_1.0.bb +++ /dev/null @@ -1,18 +0,0 @@ -SUMMARY = "AGL demo device mapping configuration file" -DESCRIPTION = "This provide default dev-mapping.conf file \ - that defines mapping between kernel device and logical name \ - used in low-can binding for the AGL demo setup." - -LICENSE = "MIT" -LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" - -SRC_URI += "file://dev-mapping.conf.demo" - -inherit allarch - -do_install() { - install -d ${D}${sysconfdir} - install -m 0644 ${WORKDIR}/dev-mapping.conf.demo ${D}${sysconfdir}/dev-mapping.conf -} - -RPROVIDES_${PN} = "virtual/low-can-dev-mapping" diff --git a/recipes-config/qemu-config/files/agl-cluster-demo-platform-flutter.conf b/recipes-config/qemu-config/files/agl-cluster-demo-platform-flutter.conf new file mode 100644 index 00000000..99d1f10c --- /dev/null +++ b/recipes-config/qemu-config/files/agl-cluster-demo-platform-flutter.conf @@ -0,0 +1,5 @@ +QEMU_TASKSET_CPUS="4-7" +QEMU_SMP_OPT="-smp 2" +QEMU_MEM_OPT="-m 1G" +QEMU_NET_OPT="-netdev bridge,br=vmnet0,id=net0 -device virtio-net-device,mac=52:54:00:12:00:03,netdev=net0" +QEMU_KERNEL_CMDLINE_APPEND="root=/dev/vda rw mem=2048M video=Virtual-1:1920x1080" diff --git a/recipes-config/qemu-config/files/agl-cluster-demo-platform.conf b/recipes-config/qemu-config/files/agl-cluster-demo-platform.conf new file mode 100644 index 00000000..1ecefc47 --- /dev/null +++ b/recipes-config/qemu-config/files/agl-cluster-demo-platform.conf @@ -0,0 +1,5 @@ +QEMU_TASKSET_CPUS="4-7" +QEMU_SMP_OPT="-smp 4" +QEMU_MEM_OPT="-m 2G" +QEMU_NET_OPT="-netdev bridge,br=vmnet0,id=net0 -device virtio-net-device,mac=52:54:00:12:00:03,netdev=net0" +QEMU_KERNEL_CMDLINE_APPEND="root=/dev/vda rw mem=2048M video=Virtual-1:1920x1080" diff --git a/recipes-config/qemu-config/files/agl-demo-platform.conf b/recipes-config/qemu-config/files/agl-demo-platform.conf new file mode 100644 index 00000000..7ff32bc1 --- /dev/null +++ b/recipes-config/qemu-config/files/agl-demo-platform.conf @@ -0,0 +1,12 @@ +QEMU_TASKSET_CPUS="0-3" +QEMU_SMP_OPT="-smp 4" +QEMU_MEM_OPT="-m 4G" +# With touchscreen plugged into the bottom connector of the 2x USB 2.0 +# on the reference hardware +QEMU_INPUT_OPT="-device qemu-xhci -usb -device usb-host,hostbus=5,hostport=1" +# Fallback for touchscreen or other pointing device plugged in elsewhere +#QEMU_INPUT_OPT="-device virtio-tablet-device" +QEMU_AUDIO_OPT="-audiodev alsa,id=agl -device intel-hda -device hda-duplex,audiodev=agl" +QEMU_NET_OPT="-netdev bridge,br=vmnet0,id=net0 -device virtio-net-device,mac=52:54:00:12:00:02,netdev=net0" +QEMU_CAN_OPT="-object can-bus,id=canbus0 -object can-host-socketcan,id=canhost0,if=can0,canbus=canbus0 -device kvaser_pci,canbus=canbus0" +QEMU_KERNEL_CMDLINE_APPEND="root=/dev/vda rw mem=4196M video=Virtual-1:1920x1080" diff --git a/recipes-config/qemu-config/files/agl-ivi-demo-platform-flutter.conf b/recipes-config/qemu-config/files/agl-ivi-demo-platform-flutter.conf new file mode 100644 index 00000000..7ff32bc1 --- /dev/null +++ b/recipes-config/qemu-config/files/agl-ivi-demo-platform-flutter.conf @@ -0,0 +1,12 @@ +QEMU_TASKSET_CPUS="0-3" +QEMU_SMP_OPT="-smp 4" +QEMU_MEM_OPT="-m 4G" +# With touchscreen plugged into the bottom connector of the 2x USB 2.0 +# on the reference hardware +QEMU_INPUT_OPT="-device qemu-xhci -usb -device usb-host,hostbus=5,hostport=1" +# Fallback for touchscreen or other pointing device plugged in elsewhere +#QEMU_INPUT_OPT="-device virtio-tablet-device" +QEMU_AUDIO_OPT="-audiodev alsa,id=agl -device intel-hda -device hda-duplex,audiodev=agl" +QEMU_NET_OPT="-netdev bridge,br=vmnet0,id=net0 -device virtio-net-device,mac=52:54:00:12:00:02,netdev=net0" +QEMU_CAN_OPT="-object can-bus,id=canbus0 -object can-host-socketcan,id=canhost0,if=can0,canbus=canbus0 -device kvaser_pci,canbus=canbus0" +QEMU_KERNEL_CMDLINE_APPEND="root=/dev/vda rw mem=4196M video=Virtual-1:1920x1080" diff --git a/recipes-config/qemu-config/files/bridge.conf b/recipes-config/qemu-config/files/bridge.conf new file mode 100644 index 00000000..72c73f39 --- /dev/null +++ b/recipes-config/qemu-config/files/bridge.conf @@ -0,0 +1 @@ +allow vmnet0 diff --git a/recipes-config/qemu-config/files/connman-nodnsproxy.conf b/recipes-config/qemu-config/files/connman-nodnsproxy.conf new file mode 100644 index 00000000..9d7f74b8 --- /dev/null +++ b/recipes-config/qemu-config/files/connman-nodnsproxy.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=/usr/sbin/connmand -n --nodnsproxy diff --git a/recipes-config/qemu-config/files/dnsmasq-qemu.conf b/recipes-config/qemu-config/files/dnsmasq-qemu.conf new file mode 100644 index 00000000..4ab6ee3b --- /dev/null +++ b/recipes-config/qemu-config/files/dnsmasq-qemu.conf @@ -0,0 +1,4 @@ +interface=vmnet0 +dhcp-range=172.16.10.1,172.16.10.5,255.255.255.0,12h +dhcp-host=52:54:00:12:00:02,172.16.10.2 +dhcp-host=52:54:00:12:00:03,172.16.10.3 diff --git a/recipes-config/qemu-config/files/vmnet0.netdev b/recipes-config/qemu-config/files/vmnet0.netdev new file mode 100644 index 00000000..e2545317 --- /dev/null +++ b/recipes-config/qemu-config/files/vmnet0.netdev @@ -0,0 +1,3 @@ +[NetDev] +Name=vmnet0 +Kind=bridge diff --git a/recipes-config/qemu-config/files/vmnet0.network b/recipes-config/qemu-config/files/vmnet0.network new file mode 100644 index 00000000..600f8ac0 --- /dev/null +++ b/recipes-config/qemu-config/files/vmnet0.network @@ -0,0 +1,7 @@ +[Match] +Name=vmnet0 + +[Network] +Address=172.16.10.1/24 +IPForward=yes +IPMasquerade=yes diff --git a/recipes-config/qemu-config/qemu-config-agl-cluster-demo-platform-flutter.bb b/recipes-config/qemu-config/qemu-config-agl-cluster-demo-platform-flutter.bb new file mode 100644 index 00000000..159d3939 --- /dev/null +++ b/recipes-config/qemu-config/qemu-config-agl-cluster-demo-platform-flutter.bb @@ -0,0 +1,29 @@ +SUMMARY = "Setting files for agl-cluster-demo-plaform-flutter guest VM" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd allarch + +SRC_URI = "file://${QEMU_IMAGE}.conf" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +QEMU_IMAGE = "agl-cluster-demo-platform-flutter" +QEMU_UNIT = "agl-qemu-runner@${QEMU_IMAGE}.service" + +do_install() { + # Install template unit links + install -d ${D}${systemd_system_unitdir} + ln -sf agl-qemu-runner@.service ${D}${systemd_system_unitdir}/${QEMU_UNIT} + install -d ${D}${systemd_system_unitdir}/multi-user.target.wants + ln -sf ${systemd_system_unitdir}/${QEMU_UNIT} ${D}${systemd_system_unitdir}/multi-user.target.wants/${QEMU_UNIT} + + # Install conf file + install -d ${D}${sysconfdir}/agl-qemu-runner + install -m 0644 ${WORKDIR}/${QEMU_IMAGE}.conf ${D}${sysconfdir}/agl-qemu-runner/ +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "agl-qemu-runner qemu-config-vmnet0" diff --git a/recipes-config/qemu-config/qemu-config-agl-cluster-demo-platform.bb b/recipes-config/qemu-config/qemu-config-agl-cluster-demo-platform.bb new file mode 100644 index 00000000..8e2aeb3e --- /dev/null +++ b/recipes-config/qemu-config/qemu-config-agl-cluster-demo-platform.bb @@ -0,0 +1,29 @@ +SUMMARY = "Setting files for agl-cluster-demo-plaform guest VM" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd allarch + +SRC_URI = "file://${QEMU_IMAGE}.conf" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +QEMU_IMAGE = "agl-cluster-demo-platform" +QEMU_UNIT = "agl-qemu-runner@${QEMU_IMAGE}.service" + +do_install() { + # Install template unit links + install -d ${D}${systemd_system_unitdir} + ln -sf agl-qemu-runner@.service ${D}${systemd_system_unitdir}/${QEMU_UNIT} + install -d ${D}${systemd_system_unitdir}/multi-user.target.wants + ln -sf ${systemd_system_unitdir}/${QEMU_UNIT} ${D}${systemd_system_unitdir}/multi-user.target.wants/${QEMU_UNIT} + + # Install conf file + install -d ${D}${sysconfdir}/agl-qemu-runner + install -m 0644 ${WORKDIR}/${QEMU_IMAGE}.conf ${D}${sysconfdir}/agl-qemu-runner/ +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "agl-qemu-runner qemu-config-vmnet0" diff --git a/recipes-config/qemu-config/qemu-config-agl-demo-platform.bb b/recipes-config/qemu-config/qemu-config-agl-demo-platform.bb new file mode 100644 index 00000000..da85b7a7 --- /dev/null +++ b/recipes-config/qemu-config/qemu-config-agl-demo-platform.bb @@ -0,0 +1,29 @@ +SUMMARY = "Setting files for agl-demo-plaform guest VM" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd allarch + +SRC_URI = "file://${QEMU_IMAGE}.conf" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +QEMU_IMAGE = "agl-demo-platform" +QEMU_UNIT = "agl-qemu-runner@${QEMU_IMAGE}.service" + +do_install() { + # Install template unit links + install -d ${D}${systemd_system_unitdir} + ln -sf agl-qemu-runner@.service ${D}${systemd_system_unitdir}/${QEMU_UNIT} + install -d ${D}${systemd_system_unitdir}/multi-user.target.wants + ln -sf ${systemd_system_unitdir}/${QEMU_UNIT} ${D}${systemd_system_unitdir}/multi-user.target.wants/${QEMU_UNIT} + + # Install conf file + install -d ${D}${sysconfdir}/agl-qemu-runner + install -m 0644 ${WORKDIR}/${QEMU_IMAGE}.conf ${D}${sysconfdir}/agl-qemu-runner/ +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "agl-qemu-runner qemu-config-vmnet0" diff --git a/recipes-config/qemu-config/qemu-config-agl-ivi-demo-platform-flutter.bb b/recipes-config/qemu-config/qemu-config-agl-ivi-demo-platform-flutter.bb new file mode 100644 index 00000000..10c30445 --- /dev/null +++ b/recipes-config/qemu-config/qemu-config-agl-ivi-demo-platform-flutter.bb @@ -0,0 +1,29 @@ +SUMMARY = "Setting files for agl-ivi-demo-plaform-flutter guest VM" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd allarch + +SRC_URI = "file://${QEMU_IMAGE}.conf" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +QEMU_IMAGE = "agl-ivi-demo-platform-flutter" +QEMU_UNIT = "agl-qemu-runner@${QEMU_IMAGE}.service" + +do_install() { + # Install template unit links + install -d ${D}${systemd_system_unitdir} + ln -sf agl-qemu-runner@.service ${D}${systemd_system_unitdir}/${QEMU_UNIT} + install -d ${D}${systemd_system_unitdir}/multi-user.target.wants + ln -sf ${systemd_system_unitdir}/${QEMU_UNIT} ${D}${systemd_system_unitdir}/multi-user.target.wants/${QEMU_UNIT} + + # Install conf file + install -d ${D}${sysconfdir}/agl-qemu-runner + install -m 0644 ${WORKDIR}/${QEMU_IMAGE}.conf ${D}${sysconfdir}/agl-qemu-runner/ +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "agl-qemu-runner qemu-config-vmnet0" diff --git a/recipes-config/qemu-config/qemu-config-vmnet0.bb b/recipes-config/qemu-config/qemu-config-vmnet0.bb new file mode 100644 index 00000000..bc634bf3 --- /dev/null +++ b/recipes-config/qemu-config/qemu-config-vmnet0.bb @@ -0,0 +1,41 @@ +SUMMARY = "Setting files for QEMU networking for guest VMs" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd allarch + +SRC_URI = "file://vmnet0.netdev \ + file://vmnet0.network \ + file://bridge.conf \ + file://dnsmasq-qemu.conf \ + file://connman-nodnsproxy.conf \ +" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +QEMU_IMAGE = "agl-cluster-demo-platform" +QEMU_UNIT = "agl-qemu-runner@${QEMU_IMAGE}.service" + +do_install() { + # Install systemd-networkd vmnet0 configuration + install -d ${D}${systemd_unitdir}/network + install -m 0644 ${WORKDIR}/vmnet0.netdev ${D}${systemd_unitdir}/network/ + install -m 0644 ${WORKDIR}/vmnet0.network ${D}${systemd_unitdir}/network/ + + # Install QEMU bridge configuration + install -d ${D}${sysconfdir}/qemu + install -m 0644 ${WORKDIR}/bridge.conf ${D}${sysconfdir}/qemu/ + + # Configure dnsmasq to serve DHCP to the guests + install -d ${D}${sysconfdir}/dnsmasq.d + install -m 0644 ${WORKDIR}/dnsmasq-qemu.conf ${D}${sysconfdir}/dnsmasq.d/ + + # Disable ConnMan's local DNS proxy to not conflict with dnsmasq + install -d ${D}${systemd_system_unitdir}/connman.service.d/ + install -m 0644 ${WORKDIR}/connman-nodnsproxy.conf ${D}${systemd_system_unitdir}/connman.service.d/ +} + +FILES:${PN} += "${systemd_unitdir}/network ${systemd_system_unitdir}" + +RDEPENDS:${PN} += "agl-qemu-runner dnsmasq connman" diff --git a/recipes-config/unicens-config/files/55-inic.rules b/recipes-config/unicens-config/files/55-inic.rules deleted file mode 100644 index 2da65cb8..00000000 --- a/recipes-config/unicens-config/files/55-inic.rules +++ /dev/null @@ -1,4 +0,0 @@ -# OS81118 devices for Microchip UNICENS -KERNEL=="inic-usb-crx", SUBSYSTEM=="most_cdev_aim", GROUP="audio", SECLABEL{smack}="*" -KERNEL=="inic-usb-ctx", SUBSYSTEM=="most_cdev_aim", GROUP="audio", SECLABEL{smack}="*" -KERNEL=="inic-usb-itx1", SUBSYSTEM=="most_cdev_aim", GROUP="audio", SECLABEL{smack}="*" diff --git a/recipes-config/unicens-config/files/unicens-config.service b/recipes-config/unicens-config/files/unicens-config.service deleted file mode 100644 index 43c8a167..00000000 --- a/recipes-config/unicens-config/files/unicens-config.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Driver configuration for Unicens2 -After=systemd-modules-load.service -Requires=systemd-modules-load.service - -[Service] -Type=oneshot -ExecStart=/usr/bin/unicens-config.sh - -[Install] -WantedBy=multi-user.target diff --git a/recipes-config/unicens-config/files/unicens-config.sh b/recipes-config/unicens-config/files/unicens-config.sh deleted file mode 100644 index 1f7fd390..00000000 --- a/recipes-config/unicens-config/files/unicens-config.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/bash - -########################################################################## -# NOTE: This script is intentended to be used with the MOST starter-kit[1] -# in conjuction with the agl-service-unicens widget only. For other setups -# this script and also the UNICENS config settings need to be adapted -# accordingly. -# -# An optional approach to configure the driver is provided by the -# default_conf.ko kernel module that can be found in -# /lib/modules/`uname -r`/extra -# -# -# [1]: The starter-kit consists of one Network Interface Controller and -# three slim amplifier modules) -########################################################################## - - -########################################## -# interface: mdev0 -# chip: Vantage -# aim: cdev -# name: inic-usb-crx -echo rx > /sys/devices/virtual/most/mostcore/devices/mdev0/ep8f/set_direction 2>/dev/null -echo control > /sys/devices/virtual/most/mostcore/devices/mdev0/ep8f/set_datatype 2>/dev/null -echo 16 > /sys/devices/virtual/most/mostcore/devices/mdev0/ep8f/set_number_of_buffers 2>/dev/null -echo 64 > /sys/devices/virtual/most/mostcore/devices/mdev0/ep8f/set_buffer_size 2>/dev/null - -echo mdev0:ep8f:inic-usb-crx > /sys/devices/virtual/most/mostcore/aims/cdev/add_link 2>/dev/null - -#aim: cdev -#name: inic-usb-ctx -echo tx > /sys/devices/virtual/most/mostcore/devices/mdev0/ep0f/set_direction 2>/dev/null -echo control > /sys/devices/virtual/most/mostcore/devices/mdev0/ep0f/set_datatype 2>/dev/null -echo 16 > /sys/devices/virtual/most/mostcore/devices/mdev0/ep0f/set_number_of_buffers 2>/dev/null -echo 64 > /sys/devices/virtual/most/mostcore/devices/mdev0/ep0f/set_buffer_size 2>/dev/null - -echo mdev0:ep0f:inic-usb-ctx > /sys/devices/virtual/most/mostcore/aims/cdev/add_link 2>/dev/null - -########################################## -# interface: mdev1 -#aim: networking -#name: inic-usb-arx -echo rx > /sys/devices/virtual/most/mostcore/devices/mdev1/ep8e/set_direction 2>/dev/null -echo async > /sys/devices/virtual/most/mostcore/devices/mdev1/ep8e/set_datatype 2>/dev/null -echo 20 > /sys/devices/virtual/most/mostcore/devices/mdev1/ep8e/set_number_of_buffers 2>/dev/null -echo 1522 > /sys/devices/virtual/most/mostcore/devices/mdev1/ep8e/set_buffer_size 2>/dev/null - -echo mdev1:ep8e:inic-usb-arx > /sys/devices/virtual/most/mostcore/aims/networking/add_link 2>/dev/null -#aim: networking -#name: inic-usb-atx -echo tx > /sys/devices/virtual/most/mostcore/devices/mdev1/ep0e/set_direction 2>/dev/null -echo async > /sys/devices/virtual/most/mostcore/devices/mdev1/ep0e/set_datatype 2>/dev/null -echo 20 > /sys/devices/virtual/most/mostcore/devices/mdev1/ep0e/set_number_of_buffers 2>/dev/null -echo 1522 > /sys/devices/virtual/most/mostcore/devices/mdev1/ep0e/set_buffer_size 2>/dev/null - -echo mdev1:ep0e:inic-usb-atx > /sys/devices/virtual/most/mostcore/aims/networking/add_link 2>/dev/null -########################################### -## interface: mdev0 -## chip: Durango -##aim: cdev -##name: inic-usb-crx -echo rx > /sys/devices/virtual/most/mostcore/devices/mdev0/ep87/set_direction 2>/dev/null -echo control > /sys/devices/virtual/most/mostcore/devices/mdev0/ep87/set_datatype 2>/dev/null -echo 16 > /sys/devices/virtual/most/mostcore/devices/mdev0/ep87/set_number_of_buffers 2>/dev/null -echo 64 > /sys/devices/virtual/most/mostcore/devices/mdev0/ep87/set_buffer_size 2>/dev/null - -echo mdev0:ep87:inic-usb-crx > /sys/devices/virtual/most/mostcore/aims/cdev/add_link 2>/dev/null -#aim: cdev -#name: inic-usb-ctx -echo tx > /sys/devices/virtual/most/mostcore/devices/mdev0/ep07/set_direction 2>/dev/null -echo control > /sys/devices/virtual/most/mostcore/devices/mdev0/ep07/set_datatype 2>/dev/null -echo 16 > /sys/devices/virtual/most/mostcore/devices/mdev0/ep07/set_number_of_buffers 2>/dev/null -echo 64 > /sys/devices/virtual/most/mostcore/devices/mdev0/ep07/set_buffer_size 2>/dev/null - -echo mdev0:ep07:inic-usb-ctx > /sys/devices/virtual/most/mostcore/aims/cdev/add_link 2>/dev/null -########################################### -## interface: mdev1 -## chip: Durango -## aim: networking -##name: inic-usb-arx -echo rx > /sys/devices/virtual/most/mostcore/devices/mdev1/ep86/set_direction 2>/dev/null -echo async > /sys/devices/virtual/most/mostcore/devices/mdev1/ep86/set_datatype 2>/dev/null -echo 20 > /sys/devices/virtual/most/mostcore/devices/mdev1/ep86/set_number_of_buffers 2>/dev/null -echo 1522 > /sys/devices/virtual/most/mostcore/devices/mdev1/ep86/set_buffer_size 2>/dev/null - -echo mdev1:ep86:inic-usb-arx > /sys/devices/virtual/most/mostcore/aims/networking/add_link 2>/dev/null -#aim: networking -#name: inic-usb-atx -echo tx > /sys/devices/virtual/most/mostcore/devices/mdev1/ep06/set_direction 2>/dev/null -echo async > /sys/devices/virtual/most/mostcore/devices/mdev1/ep06/set_datatype 2>/dev/null -echo 20 > /sys/devices/virtual/most/mostcore/devices/mdev1/ep06/set_number_of_buffers 2>/dev/null -echo 1522 > /sys/devices/virtual/most/mostcore/devices/mdev1/ep06/set_buffer_size 2>/dev/null - -echo mdev1:ep06:inic-usb-atx > /sys/devices/virtual/most/mostcore/aims/networking/add_link 2>/dev/null - -########################################## -# interface: mdev2 -#aim: sound -#name: ep01-6ch.6x16 -echo tx > /sys/devices/virtual/most/mostcore/devices/mdev2/ep01/set_direction 2>/dev/null -echo sync > /sys/devices/virtual/most/mostcore/devices/mdev2/ep01/set_datatype 2>/dev/null -echo 16 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep01/set_number_of_buffers 2>/dev/null -echo 1008 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep01/set_buffer_size 2>/dev/null -echo 12 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep01/set_subbuffer_size 2>/dev/null -echo 42 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep01/set_packets_per_xact 2>/dev/null - -echo mdev2:ep01:ep01-6ch.6x16 > /sys/devices/virtual/most/mostcore/aims/sound/add_link 2>/dev/null - -# interface: mdev2 -# aim: sound -# name: ep81-1ch.1x16 -echo rx > /sys/devices/virtual/most/mostcore/devices/mdev2/ep81/set_direction 2>/dev/null -echo sync > /sys/devices/virtual/most/mostcore/devices/mdev2/ep81/set_datatype 2>/dev/null -echo 8 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep81/set_number_of_buffers 2>/dev/null -echo 2048 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep81/set_buffer_size 2>/dev/null -echo 2 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep81/set_subbuffer_size 2>/dev/null -echo 256 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep81/set_packets_per_xact 2>/dev/null - -echo mdev2:ep81:ep81-1ch.1x16 > /sys/devices/virtual/most/mostcore/aims/sound/add_link 2>/dev/null - -# interface: mdev2 -# aim: sound -# name: ep82-1ch.1x16 -echo rx > /sys/devices/virtual/most/mostcore/devices/mdev2/ep82/set_direction 2>/dev/null -echo sync > /sys/devices/virtual/most/mostcore/devices/mdev2/ep82/set_datatype 2>/dev/null -echo 8 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep82/set_number_of_buffers 2>/dev/null -echo 2048 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep82/set_buffer_size 2>/dev/null -echo 2 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep82/set_subbuffer_size 2>/dev/null -echo 256 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep82/set_packets_per_xact 2>/dev/null - -echo mdev2:ep82:ep82-1ch.1x16 > /sys/devices/virtual/most/mostcore/aims/sound/add_link 2>/dev/null - -##aim: cdev -##name: inic-usb-itx1 -echo tx > /sys/devices/virtual/most/mostcore/devices/mdev2/ep02/set_direction 2>/dev/null -echo isoc > /sys/devices/virtual/most/mostcore/devices/mdev2/ep02/set_datatype 2>/dev/null -echo 8 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep02/set_number_of_buffers 2>/dev/null -echo 7520 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep02/set_buffer_size 2>/dev/null -echo 188 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep02/set_subbuffer_size 2>/dev/null -echo 2 > /sys/devices/virtual/most/mostcore/devices/mdev2/ep02/set_packets_per_xact 2>/dev/null - -echo mdev2:ep02:inic-usb-itx1 > /sys/devices/virtual/most/mostcore/aims/cdev/add_link 2>/dev/null diff --git a/recipes-config/unicens-config/unicens-config.bb b/recipes-config/unicens-config/unicens-config.bb deleted file mode 100644 index 4dd20748..00000000 --- a/recipes-config/unicens-config/unicens-config.bb +++ /dev/null @@ -1,31 +0,0 @@ -DESCRIPTION = "Configure MOST driver" -LICENSE = "GPLv2" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" - -RDEPENDS_${PN} = "bash" - -SRC_URI = "\ - file://unicens-config.service \ - file://unicens-config.sh \ - file://55-inic.rules \ -" - - -inherit systemd - -SYSTEMD_PACKAGES = "${PN}" -SYSTEMD_SERVICE_${PN} = "unicens-config.service" -SYSTEMD_AUTO_ENABLE_${PN} = "enable" - -do_configure[noexec] = "1" -do_compile[noexec] = "1" - -do_install() { - install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/unicens-config.service ${D}${systemd_system_unitdir} - install -d ${D}${bindir} - install -m 0755 ${WORKDIR}/unicens-config.sh ${D}${bindir} - install -D -m 0644 ${WORKDIR}/55-inic.rules ${D}${sysconfdir}/udev/rules.d/55-inic.rules -} - -FILES_${PN} += "${systemd_system_unitdir}" diff --git a/recipes-connectivity/bluez-glib/bluez-glib_git.bb b/recipes-connectivity/bluez-glib/bluez-glib_git.bb new file mode 100644 index 00000000..625b65ac --- /dev/null +++ b/recipes-connectivity/bluez-glib/bluez-glib_git.bb @@ -0,0 +1,14 @@ +SUMMARY = "GLib BlueZ interface library" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = "systemd glib-2.0" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/bluez-glib;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "045d4a1ffc823665b068be96b5d8532e68838e18" +S = "${WORKDIR}/git" + +# PV needs to be modified with SRCPV to work AUTOREV correctly +PV = "1.0+git${SRCPV}" + +inherit meson pkgconfig diff --git a/recipes-connectivity/connman-glib/connman-glib.bb b/recipes-connectivity/connman-glib/connman-glib.bb new file mode 100644 index 00000000..20682bd6 --- /dev/null +++ b/recipes-connectivity/connman-glib/connman-glib.bb @@ -0,0 +1,15 @@ +SUMMARY = "GLib Connman interface library" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = "systemd glib-2.0" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/connman-glib;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "86ecfa16aeb5c4942990f0181dab7f60b4f45a83" + +S = "${WORKDIR}/git" + +# PV needs to be modified with SRCPV to work AUTOREV correctly +PV = "1.0+git${SRCPV}" + +inherit meson pkgconfig diff --git a/recipes-connectivity/connman/connman-conf.bbappend b/recipes-connectivity/connman/connman-conf.bbappend new file mode 100644 index 00000000..39792fd9 --- /dev/null +++ b/recipes-connectivity/connman/connman-conf.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'connman-conf_agldemo.inc', '', d)} diff --git a/recipes-connectivity/connman/connman-conf_agldemo.inc b/recipes-connectivity/connman/connman-conf_agldemo.inc new file mode 100644 index 00000000..7b736ec6 --- /dev/null +++ b/recipes-connectivity/connman/connman-conf_agldemo.inc @@ -0,0 +1,6 @@ +do_install:append() { + # Need to ignore eth1 in cluster demo setup + if ${@bb.utils.contains('AGL_FEATURES', 'agl-demo-cluster-support', 'true', 'false', d)}; then + sed -i 's/^\(NetworkInterfaceBlacklist=.*\)/\1,eth1/' ${D}${sysconfdir}/connman/main.conf + fi +} diff --git a/recipes-connectivity/kuksa-val/can-dev-helper/can-dev-helper.service b/recipes-connectivity/kuksa-val/can-dev-helper/can-dev-helper.service new file mode 100644 index 00000000..04e6a9c3 --- /dev/null +++ b/recipes-connectivity/kuksa-val/can-dev-helper/can-dev-helper.service @@ -0,0 +1,10 @@ +[Unit] +Description=CAN interface helper +Before=kuksa-dbc-feeder.service + +[Service] +ExecStart=/usr/sbin/can-dev-helper.sh +Type=oneshot + +[Install] +WantedBy=multi-user.target diff --git a/recipes-connectivity/kuksa-val/can-dev-helper/can-dev-helper.sh b/recipes-connectivity/kuksa-val/can-dev-helper/can-dev-helper.sh new file mode 100644 index 00000000..d57604c0 --- /dev/null +++ b/recipes-connectivity/kuksa-val/can-dev-helper/can-dev-helper.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# +# Script to bring up CAN interface configured for the kuksa.val +# CAN feeder in /etc/kuksa-dbc-feeder/dbc_feeder.ini as vcan +# interfaces if no physical interface is present. +# + +vcan_up() { + if [ -n "$1" ]; then + echo "Bringing up $1 as virtual CAN device" + ip link add dev $1 type vcan + ip link set up $1 + fi +} + +CONF=/etc/kuksa-dbc-feeder/config.ini +if [ $# -gt 0 ]; then + CONF=$1 +fi + +if [ ! -f $CONF ]; then + exit 0 +fi + +# Ideally the parsing would take the "[can]" section into +# account, but this should work for now. +interface=$(sed -nr '/\[can\]/,/\[/{s/^port *= *//p}' $CONF) +if [ -n "$interface" ]; then + echo "Checking $interface" + if ! ifconfig $interface >/dev/null 2>&1; then + vcan_up $interface + fi +fi + +exit 0 diff --git a/recipes-connectivity/kuksa-val/can-dev-helper_1.0.bb b/recipes-connectivity/kuksa-val/can-dev-helper_1.0.bb new file mode 100644 index 00000000..90f5ff1c --- /dev/null +++ b/recipes-connectivity/kuksa-val/can-dev-helper_1.0.bb @@ -0,0 +1,23 @@ +SUMMARY = "Systemd unit for CAN device helper" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +SRC_URI = "file://can-dev-helper.service \ + file://can-dev-helper.sh \ +" + +inherit systemd allarch + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service + install -D -m 0755 ${WORKDIR}/${BPN}.sh ${D}${sbindir}/${BPN}.sh +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "bash" diff --git a/recipes-connectivity/kuksa-val/kuksa-certificates-agl.bb b/recipes-connectivity/kuksa-val/kuksa-certificates-agl.bb new file mode 100644 index 00000000..0264ebbd --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-certificates-agl.bb @@ -0,0 +1,61 @@ +SUMMARY = "AGL certificates for KUKSA.val, the KUKSA Vehicle Abstraction Layer" +HOMEPAGE = "https://github.com/eclipse/kuksa.val" +BUGTRACKER = "https://github.com/eclipse/kuksa.val/issues" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = "file://CA.pem \ + file://Client.key \ + file://Client.pem \ + file://Server.key \ + file://Server.pem \ + file://jwt.key.pub \ +" + +inherit allarch useradd + +USERADD_PACKAGES = "${PN}-server" +USERADDEXTENSION = "useradd-staticids" +GROUPADD_PARAM:${PN}-server = "-g 900 kuksa ;" + +do_install() { + # Install replacement CA certificate, server key + certificate, + # and client key + certificate. + # These are AGL specific versions generated using a tweaked + # genCerts.sh script to have different expiry dates than the + # upstream defaults, and use AGL as the organization. + install -d ${D}${sysconfdir}/kuksa-val/ + install -m 0644 ${WORKDIR}/CA.pem ${D}${sysconfdir}/kuksa-val/ + install -m 0640 -g 900 ${WORKDIR}/Server.key ${D}${sysconfdir}/kuksa-val/ + install -m 0640 -g 900 ${WORKDIR}/Server.pem ${D}${sysconfdir}/kuksa-val/ + install -m 0644 -g 900 ${WORKDIR}/jwt.key.pub ${D}${sysconfdir}/kuksa-val/ + install -m 0644 ${WORKDIR}/Client.key ${D}${sysconfdir}/kuksa-val/ + install -m 0644 ${WORKDIR}/Client.pem ${D}${sysconfdir}/kuksa-val/ +} + +PACKAGE_BEFORE_PN += "${PN}-ca ${PN}-server ${PN}-client" + +FILES:${PN}-ca = " \ + ${sysconfdir}/kuksa-val/CA.pem \ +" +RPROVIDES:${PN}-ca += "kuksa-val-certificates-ca" + +FILES:${PN}-server = " \ + ${sysconfdir}/kuksa-val/Server.key \ + ${sysconfdir}/kuksa-val/Server.pem \ + ${sysconfdir}/kuksa-val/jwt.key.pub \ +" +RPROVIDES:${PN}-server += "kuksa-val-certificates-server" +RDEPENDS:${PN}-server += "${PN}-ca" + +FILES:${PN}-client = " \ + ${sysconfdir}/kuksa-val/Client.key \ + ${sysconfdir}/kuksa-val/Client.pem \ +" +RPROVIDES:${PN}-client += "kuksa-val-certificates-client" +RDEPENDS:${PN}-client += "${PN}-ca" + +ALLOW_EMPTY:${PN} = "1" + +RDEPENDS:${PN} += "${PN}-ca ${PN}-server ${PN}-client" diff --git a/recipes-connectivity/kuksa-val/kuksa-certificates-agl/CA.pem b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/CA.pem new file mode 100644 index 00000000..b3fa17d6 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/CA.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID3zCCAscCFDixxnLKOE9pr9sDQynjRqX7u+TlMA0GCSqGSIb3DQEBCwUAMIGr +MQswCQYDVQQGEwJVUzEWMBQGA1UECAwNU2FuIEZyYW5jaXNjbzETMBEGA1UEBwwK +Q2FsaWZvcm5pYTEcMBoGA1UECgwTYXV0b21vdGl2ZWxpbnV4Lm9yZzEVMBMGA1UE +AwwMbG9jYWxob3N0LWNhMTowOAYJKoZIhvcNAQkBFithZ2wtZGV2LWNvbW11bml0 +eUBsaXN0cy5hdXRvbW90aXZlbGludXgub3JnMB4XDTIzMDcyMDIwMzg1NVoXDTMz +MDcxNzIwMzg1NVowgasxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1TYW4gRnJhbmNp +c2NvMRMwEQYDVQQHDApDYWxpZm9ybmlhMRwwGgYDVQQKDBNhdXRvbW90aXZlbGlu +dXgub3JnMRUwEwYDVQQDDAxsb2NhbGhvc3QtY2ExOjA4BgkqhkiG9w0BCQEWK2Fn +bC1kZXYtY29tbXVuaXR5QGxpc3RzLmF1dG9tb3RpdmVsaW51eC5vcmcwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDJZvopAg03G1TuyukI2QdVTzHQxnG +iPePMVIBAQ8M5tBWBOZxxkOgwRBTqZ1GJRvgPPediPHb3+/j+k5/+NE8TT2smDfk +4u9+NBNFXGhC9jqoEe0nkxca85RHP1Jx1iIp8SJ1TTtzEu4q/O/9bCnA+05NPLWQ +YbDZr++lR4Bwhpz0ZVD69uZE/7aXPKVoVQPyeiwNgP7sfn5XOx+THpYz2Lwl2ew/ +490Mm5Wrw5pQkq49s5On5tR7cdms3CWnVKe+qpeJo/ShZg8mJesMusZRLZ3slSPp +GMVBbdFPhIv0L4HFzoJcnEzo1j6+h7fhu4v5T2qNkCkBlxehqvsy3DwfAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBALNHiz8a86sZv6Pii/rtrlctD2x1qIobOAjQID55 +/ylAVPc0JuzGEpc8Hcl9jQXBFz2ZBBYTEn0iAB+nn9BnxWYpF/G9LQsz61uzdJJs +0WlR3FyjN8PwCysMwzGEmG2BH43vfg9oltAKxY4rZ3l5c8eL/a9o2vDzNjKNibll +NdLB+8NkZz33pjyru1sG2lw6Y1gxhcOMSU7MuHgW1YI06slBu56e92OQt5atRc6l +rY9faELSJpLhtKYF9spsS/LsITJrKdVkMZRgqrhoWAIB9qyehtBGk+Agk8MvBba8 +nRAF332SyeLeN/ytJTbjOmcYVh9daGADdyRb5d+5ALBuutU= +-----END CERTIFICATE----- diff --git a/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Client.key b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Client.key new file mode 100644 index 00000000..73b67f5c --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Client.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAyISsHMGwy8dvhx+tPQOGtgtb9YDWS0kRMPcOou3QlUjAcXmz +vT2dLIwOnnRYBS9nENDqI4x52yECUBwVNIvoeiZlQqjKhSr2BOpwJIgJgqeKr4he +sU9M9s3ODqR2sdUhv7e54sRYSFv5Hs35Horr3guSRh12FtWh+iLT2PI75jbi3KjP +mK4yZGJmoSQWh+q/vhB5CQtdAcA/08aoZnhyMOGqBMzmhr1PDm7UbzZIcp2Lxs3x +q3PBJq5eMF6N3S8ssETz7WOqX0vnBdgl4DhMYCVgrjppXzmcYYbkm4uluKVf8sR7 +cAbSaoUUft2G4mLXNBE1RJVpYrzHIQW7OphjqQIDAQABAoIBAGfnl+gu1hZCeiBi +4bpEIYIj0Lsez+yjKC1fWE5FPVieIlqq3eCqFNAIo2qojxPgxF+KYkmZeWt7Z19r +rfFUrlrdmos4O/lVkbZqZUII3CS//LWIzMjEdvVNIAGmZ3svHhXidohzheu4/RZh +VT3mbuLYzCtZCOA8Q3sCoRRCMZfQ3jrTEvak4xrgotihL3bEUOIrA8Tyv8AaAhmP +nIKV+0pS/d8xCkpIBmkNxVtNRAGvsQK5i7DsQYFEDKzbFjhXz7jRapfesAQACEgJ +0yLYKSoiHktuyHIPspj37BdTZva6vNkabJVcDKXMIuRd5xnypiygv7vo+onHJ5Rw +T9TzryECgYEA6oe9qYdiXsKygUji9W6rqYGPAl6o56nyAX6QrKnKhCQBmyVYgBB5 +YmehULzjK1Xvno5ophiBkojnCE8y99liEWZWnE9p2pr8O028ZfQficfbjWgkqmL5 +awmUTON40wK7QkpWj81YwbARYAQuC611R4MfzLWlnxxHacvBZc8x2j8CgYEA2t/a +s6dW2XuqfEgfS/oKI/9i1/CXnPFVAueAPCCl/Ee/QAGJMdmSf4yonnbnOycGMdSh +QGYUHb/PT7i04U+92T+rniprXn3QFz6iwF6X6nCkdlw9RxcWAOmg5l0yIoo9bp7J +LmVnbn2Y2TOy8/Djq47gypTH8H0VSVg5BjKgOBcCgYAG3giosSUpPyw46uhyZVYz +dW65lAoAFpLWhl04IRSj/+XoJBTOUy0qu3wWwCEqwK5uhx77VhZdMxMIxEDqzvu3 +JLb+hrjDxOwD1IfiuF5AC5EbN+Ry9Mj24GXuRm7gRuEy1LhqJ4okycIIfLbYcrDP +ckB5HwyFdy+EIoo8L+/2wwKBgQDallPJteaTvuCtzC2NaEK2XritZjdUYuR+yQqV +ghmjEVhcKOyGX37iaWyBDciyl6+lFnCQayHN8CCvwozKtCOrEt5nUH/4V3f5rvFF +Y3MejK6DEm2UUOcFtE2foxWNzze5AVV0Q4t/mmmLCgm/fCUz0baIOvxPHeyjWjth +CDBgswKBgQDj5QlFkdlgJvdJweHUSWm0vssFCgCucWEPgy5iOo4MDxEHq0r1AZWU +K5j1xabtD73K6JmO3ElvSELGAd1MlvRzeZMsSP8goCk3e8a85js2sRPwDxGHa0Dd +Ef7DoyFp6UIDOUAX6R2ylPyZYqM7bowoLdGIwh9jo8fZnvHn/UCw0w== +-----END RSA PRIVATE KEY----- diff --git a/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Client.pem b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Client.pem new file mode 100644 index 00000000..fcd92b6e --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Client.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBjCCAu6gAwIBAgIUeUuog3JmZGhkE0nRcATDuclsVvkwDQYJKoZIhvcNAQEL +BQAwgasxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1TYW4gRnJhbmNpc2NvMRMwEQYD +VQQHDApDYWxpZm9ybmlhMRwwGgYDVQQKDBNhdXRvbW90aXZlbGludXgub3JnMRUw +EwYDVQQDDAxsb2NhbGhvc3QtY2ExOjA4BgkqhkiG9w0BCQEWK2FnbC1kZXYtY29t +bXVuaXR5QGxpc3RzLmF1dG9tb3RpdmVsaW51eC5vcmcwHhcNMjMwNzIwMjAzODU1 +WhcNMjcwNzE5MjAzODU1WjCBpTELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDVNhbiBG +cmFuY2lzY28xEzARBgNVBAcMCkNhbGlmb3JuaWExHDAaBgNVBAoME2F1dG9tb3Rp +dmVsaW51eC5vcmcxDzANBgNVBAMMBkNsaWVudDE6MDgGCSqGSIb3DQEJARYrYWds +LWRldi1jb21tdW5pdHlAbGlzdHMuYXV0b21vdGl2ZWxpbnV4Lm9yZzCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMiErBzBsMvHb4cfrT0DhrYLW/WA1ktJ +ETD3DqLt0JVIwHF5s709nSyMDp50WAUvZxDQ6iOMedshAlAcFTSL6HomZUKoyoUq +9gTqcCSICYKniq+IXrFPTPbNzg6kdrHVIb+3ueLEWEhb+R7N+R6K694LkkYddhbV +ofoi09jyO+Y24tyoz5iuMmRiZqEkFofqv74QeQkLXQHAP9PGqGZ4cjDhqgTM5oa9 +Tw5u1G82SHKdi8bN8atzwSauXjBejd0vLLBE8+1jql9L5wXYJeA4TGAlYK46aV85 +nGGG5JuLpbilX/LEe3AG0mqFFH7dhuJi1zQRNUSVaWK8xyEFuzqYY6kCAwEAAaMm +MCQwIgYDVR0RBBswGYIGQ2xpZW50gglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcN +AQELBQADggEBAGtM7LGk4PhEgrjLXr7tdRn/VSwUv+HLDmtgkMFsAqYolTwtK7eK +1XgNF2j6Yo4ma/efd8Td9wjKkrfkxQRCpM5gjNLhiZsBRO/HW4GiC3GKz0ELijE2 +7JU7xikawSE6Zvvj1t33KJ5uGDowv2tvDbCB76ecGohTb5O7mpe+fxMlt+d4vPku +uTfAaNfl8+oSo7suy3842ANpxteoxfVHZgG0FjdMKjSKxCyxI3buLltlQ7G+39QS +/cwuRTOp0UNPpiHWDKVOXL8qW/ZHpocGFlErstEQjUz+3/WglMlTK07ocRVQjQc6 +mAo4aKRaaHi5Khn+KPrRDnS+Rl8xEzSsBeo= +-----END CERTIFICATE----- diff --git a/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Server.key b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Server.key new file mode 100644 index 00000000..8b9c6ac6 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAzGvmH7adlcMVdfblKg56EkgiSkR45IrRaIMH/AKUcK/4EJdk +Jx3NoHuYuiTTreiovt9b5FjqV8txuJ579e4O9GyDELN1r9stR5y8zEbFQuf8afxK +Bl0JPnhXOxi7nUq92rn0H7jpm0a9WQvmbdRsFVfafNoeC4Dz1PeGMN4tHYtHHCnq +Ye5Sr7yT/eZ8RMUoXB560akRctA/pQWEwYbNps02HJs+jeNsJuXTgXpsirTy2RR5 +TKLmZjQMovxW85zYpSS9fRprwpzqeHhWbJBWWNeP8Y20nkRbAaAktc8IrlmhFMLh +4n0L1B0s0+Xn/9kt98pNSDCJPzH6Ar4LoDPDfwIDAQABAoIBAAyG0CNBXYa/3aDM +8F4TZQeZxAApEf9vQkXVQbf/sHj3T4w0ur5q5R7gdAt0FkSh7TVFGqxzhmi63s0h +aRc471GrFJ0BYkTUeYHZ6PfbnlrrPFyCSUb6jIZ3eWD1swmAewHcQ0luW2JYg2Hh +iM1SJw1nxMvB0fWCgW6bfG2iL8GPmyrVyhyrfebZdEaUUnjvfqLWroIoBZ2B0roa +dZ/VDlXzN8wspyziCqlumiq+R3b9+abBtHLyG13DQAhVYGksbX+5W4s1Yy6nwG0S +yyRh2cK5c2MPrjqHmJr1GqlXItmEnqkjiVlg/qZDEyalWHcKFNGNaURSz7RWNwo2 +cWZv8AECgYEA/h76+2yjvYfDeZRiKRfN9imfT9F6T4VoGgfoZODIe6uLsOQOeiKR +lqjj6bdIP8CDsfcHhb38FblYsgm6GFZiROQafRjVfj2yWiasQszFTOzLDRqR8LNs +nZSUv7zlPziJ28VBs1DF5lZSNbzFXEKxAWdGAINC1POdKZOi2UCUwYECgYEAze7X +7ML1QV+ZipnszLiRvccQ7kMUw51g/hi0Fw//tkCC8FnsbR489GDb8l+V/IR9tNov +7y5cd/NRziGVUhXH67ZnXa2k5yRYxhFWQxpgEEUWUhsfYVqppMj7vMjcxVa85A0R +2hzI/kWWWWcowwuHSmuoU8xRZlNdA2cbefeBBP8CgYEArm8hpRhLxTu+CGS8hKyc +ak7j1mxaYt+WN9gZw7UwqQN2HfRNo7S67wn7eGChLXG+dJi3By0ELv1NTtiybyZM +yjExpZE4azF6jbtiH3BkNouMTfBhITJoajqlaIAHdMAgkUTz9lyJm7TBNbXgW5ZD +3ky/lnaDl52p0fJPpIVaFwECgYEAyhsRYTUJPGqVpxhf9Z9isY0wCZZeR4kqStZ1 +0HiMLxLrLvYh+gmGKxTwZ9P1wIlLUfYcuzGV4Mc1TwdYo+HqfmRa1+52e78JPQKA +1YSKKQ2U1Wn3BzXSbn4tyd6cBTSWV36YOaasgBhNcVqz/5BN6/Tyk6Nfc/x2ucM0 +jSQiRIMCgYADss1PeYdANwbw8n29mXEGkk6qfVh54MU/AoS2v6kk6fqAHNFsb9vJ +m3JkRYSh3kSKwKgD97oGMpbxLr0wVj69s4s8wPjhNo4RZALCB/sj9hra7rsoRzmQ +apSPbfLaWVZEqg3fj0gCamSq8PGjY4fA9RNHOB751M2oszpQb8bdpA== +-----END RSA PRIVATE KEY----- diff --git a/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Server.pem b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Server.pem new file mode 100644 index 00000000..4b181e9a --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/Server.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBjCCAu6gAwIBAgIUeUuog3JmZGhkE0nRcATDuclsVvgwDQYJKoZIhvcNAQEL +BQAwgasxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1TYW4gRnJhbmNpc2NvMRMwEQYD +VQQHDApDYWxpZm9ybmlhMRwwGgYDVQQKDBNhdXRvbW90aXZlbGludXgub3JnMRUw +EwYDVQQDDAxsb2NhbGhvc3QtY2ExOjA4BgkqhkiG9w0BCQEWK2FnbC1kZXYtY29t +bXVuaXR5QGxpc3RzLmF1dG9tb3RpdmVsaW51eC5vcmcwHhcNMjMwNzIwMjAzODU1 +WhcNMjcwNzE5MjAzODU1WjCBpTELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDVNhbiBG +cmFuY2lzY28xEzARBgNVBAcMCkNhbGlmb3JuaWExHDAaBgNVBAoME2F1dG9tb3Rp +dmVsaW51eC5vcmcxDzANBgNVBAMMBlNlcnZlcjE6MDgGCSqGSIb3DQEJARYrYWds +LWRldi1jb21tdW5pdHlAbGlzdHMuYXV0b21vdGl2ZWxpbnV4Lm9yZzCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMxr5h+2nZXDFXX25SoOehJIIkpEeOSK +0WiDB/wClHCv+BCXZCcdzaB7mLok063oqL7fW+RY6lfLcbiee/XuDvRsgxCzda/b +LUecvMxGxULn/Gn8SgZdCT54VzsYu51Kvdq59B+46ZtGvVkL5m3UbBVX2nzaHguA +89T3hjDeLR2LRxwp6mHuUq+8k/3mfETFKFweetGpEXLQP6UFhMGGzabNNhybPo3j +bCbl04F6bIq08tkUeUyi5mY0DKL8VvOc2KUkvX0aa8Kc6nh4VmyQVljXj/GNtJ5E +WwGgJLXPCK5ZoRTC4eJ9C9QdLNPl5//ZLffKTUgwiT8x+gK+C6Azw38CAwEAAaMm +MCQwIgYDVR0RBBswGYIGU2VydmVygglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcN +AQELBQADggEBAKLnUuIYKU7kX6hw2kWziAzvucZCwkKDnMK1/xqakcgfnFw+z8nu +XSqNsXX0KNBfy0xhZ66Uc9rL37RG+smidxJxy+QmDi3c/Ooqj7DxbZwVXzstnbBp ++iqgfqjadC8Glfci7cfCnl7X4O3oQqo99BJDo7JH3S39fe98mG4mXa1WblKiWnkc +yDtUnf7eFbFeNbVkL94HGzOtghShHokGyt9vZKyGf+szCPPWiIDldLq/CUpPFEnD +AqUhTYBXbHZNZJHAEJ0waJqLxmytt19mAv03aaIMYUpBR0CMvjfDNn5x2Bp86v3A +YW544bNsyHfbvK0ZqwvOaV3sIKG7Bzm2pOA= +-----END CERTIFICATE----- diff --git a/recipes-connectivity/kuksa-val/kuksa-certificates-agl/genCertsAGL.sh b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/genCertsAGL.sh new file mode 100755 index 00000000..b078fd1b --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/genCertsAGL.sh @@ -0,0 +1,58 @@ +#!/bin/bash + + +genCAKey() { + openssl genrsa -out CA.key 2048 +} + + +genCACert() { + openssl req -key CA.key -new -out CA.csr -subj "/C=US/ST=San Francisco/L=California/O=automotivelinux.org/CN=localhost-ca/emailAddress=agl-dev-community@lists.automotivelinux.org" + openssl x509 -signkey CA.key -in CA.csr -req -days 3650 -out CA.pem +} + +genKey() { + openssl genrsa -out $1.key 2048 +} + +genCert() { + openssl req -new -key $1.key -out $1.csr -passin pass:"temp" -subj "/C=US/ST=San Francisco/L=California/O=automotivelinux.org/CN=$1/emailAddress=agl-dev-community@lists.automotivelinux.org" + openssl x509 -req -in $1.csr -extfile <(printf "subjectAltName=DNS:$1,DNS:localhost,IP:127.0.0.1") -CA CA.pem -CAkey CA.key -CAcreateserial -days 1460 -out $1.pem + openssl verify -CAfile CA.pem $1.pem +} + +set -e +# Check if the CA is available, else make CA certificates +if [ -f "CA.key" ]; then + echo "Existing CA.key will be used" +else + echo "No CA.key found, will generate new key" + genCAKey + rm -f CA.pem + echo "" +fi + +# Check if the CA.pem is available, else generate a new CA.pem +if [ -f "CA.pem" ]; then + echo "CA.pem will not be regenerated" +else + echo "No CA.pem found, will generate new CA.pem" + genCACert + echo "" +fi + + +for i in Server Client; +do + if [ -f $i.key ]; then + echo "Existing $i.key will be used" + else + echo "No $i.key found, will generate new key" + genKey $i + fi + echo "" + echo "Generating $i.pem" + genCert $i + echo "" +done + diff --git a/recipes-connectivity/kuksa-val/kuksa-certificates-agl/jwt.key.pub b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/jwt.key.pub new file mode 100644 index 00000000..d9f78534 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-certificates-agl/jwt.key.pub @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6ScE9EKXEWVyYhzfhfvg ++LC8NseiuEjfrdFx3HKkb31bRw/SeS0Rye0KDP7uzffwreKf6wWYGxVUPYmyKC7j +Pji5MpDBGM9r3pIZSvPUFdpTE5TiRHFBxWbqPSYt954BTLq4rMu/W+oq5Pdfnugb +voYpLf0dclBl1g9KyszkDnItz3TYbWhGMbsUSfyeSPzH0IADzLoifxbc5mgiR73N +CA/4yNSpfLoqWgQ2vdTM1182sMSmxfqSgMzIMUX/tiaXGdkoKITF1sULlLyWfTo9 +79XRZ0hmUwvfzr3OjMZNoClpYSVbKY+vtxHyux9KOOtv9lPMsgYIaPXvisrsneDZ +fCS0afOfjgR96uHIe2UPSGAXru3yGziqEfpRZoxsgXaOe905ordLD5bSX14xkN7N +Cz7rxDLlxPQyxp4Vhog7p/QeUyydBpZjq2bAE5GAJtiu+XGvG8RypzJFKFQwMNsw +g1BoZVD0mb0MtU8KQmHcZIfY0FVer/CR0mUjfl1rHbtoJB+RY03lQvYNAD04ibAG +NI1RhlTziu35Xo6NDEgs9hVs9k3WrtF+ZUxhivWmP2VXhWruRakVkC1NzKGh54e5 +/KlluFbBNpWgvWZqzWo9Jr7/fzHtR0Q0IZwkxh+Vd/bUZya1uLKqP+sTcc+aTHbn +AEiqOjPq0D6X45wCzIwjILUCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/recipes-connectivity/kuksa-val/kuksa-client/0001-kuksa-client-Update-cmd2-completer-usage.patch b/recipes-connectivity/kuksa-val/kuksa-client/0001-kuksa-client-Update-cmd2-completer-usage.patch new file mode 100644 index 00000000..e32e5c46 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-client/0001-kuksa-client-Update-cmd2-completer-usage.patch @@ -0,0 +1,161 @@ +From 89aa41f52d5946796ad8dea587cd848aef71c8c0 Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Mon, 27 Nov 2023 15:31:02 -0500 +Subject: [PATCH 1/2] kuksa-client: Update cmd2 completer usage + +Update cmd2 usage to avoid using internal methods and fix breakage +with newer versions of the cmd2 module. + +Upstream-Status: pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + kuksa-client/kuksa_client/__main__.py | 33 +++++++++++++-------------- + 1 file changed, 16 insertions(+), 17 deletions(-) + +diff --git a/kuksa-client/kuksa_client/__main__.py b/kuksa-client/kuksa_client/__main__.py +index 032410b..1d2d1fc 100755 +--- a/kuksa-client/kuksa_client/__main__.py ++++ b/kuksa-client/kuksa_client/__main__.py +@@ -36,7 +36,6 @@ from cmd2 import CompletionItem + from cmd2 import with_argparser + from cmd2 import with_category + from cmd2 import constants +-from cmd2.utils import basic_complete + from urllib.parse import urlparse + + from kuksa_client import kuksa_server_certificates +@@ -156,7 +155,7 @@ class TestClient(Cmd): + self.pathCompletionItems = [] + for sub_id in self.subscribeIds: + self.pathCompletionItems.append(CompletionItem(sub_id)) +- return basic_complete(text, line, begidx, endidx, self.pathCompletionItems) ++ return Cmd.basic_complete(self, text, line, begidx, endidx, self.pathCompletionItems) + + COMM_SETUP_COMMANDS = "Communication Set-up Commands" + VSS_COMMANDS = "Kuksa Interaction Commands" +@@ -171,19 +170,19 @@ class TestClient(Cmd): + + ap_disconnect = argparse.ArgumentParser() + ap_authorize = argparse.ArgumentParser() +- tokenfile_completer_method = functools.partial( ++ tokenfile_completer = functools.partial( + Cmd.path_complete, + path_filter=lambda path: (os.path.isdir(path) or path.endswith(".token")), + ) + ap_authorize.add_argument( + "token_or_tokenfile", + help="JWT(or the file storing the token) for authorizing the client.", +- completer_method=tokenfile_completer_method, ++ completer=tokenfile_completer, + ) + + ap_setValue = argparse.ArgumentParser() + ap_setValue.add_argument( +- "Path", help="Path to be set", completer_method=path_completer ++ "Path", help="Path to be set", completer=path_completer + ) + ap_setValue.add_argument("Value", nargs="+", help="Value to be set") + ap_setValue.add_argument( +@@ -203,7 +202,7 @@ class TestClient(Cmd): + + ap_getValue = argparse.ArgumentParser() + ap_getValue.add_argument( +- "Path", help="Path to be read", completer_method=path_completer ++ "Path", help="Path to be read", completer=path_completer + ) + ap_getValue.add_argument( + "-a", "--attribute", help="Attribute to be get", default="value" +@@ -214,7 +213,7 @@ class TestClient(Cmd): + "Path", + help="Path whose value is to be read", + nargs="+", +- completer_method=path_completer, ++ completer=path_completer, + ) + ap_getValues.add_argument( + "-a", "--attribute", help="Attribute to be get", default="value" +@@ -224,7 +223,7 @@ class TestClient(Cmd): + ap_setTargetValue.add_argument( + "Path", + help="Path whose target value to be set", +- completer_method=path_completer, ++ completer=path_completer, + ) + ap_setTargetValue.add_argument("Value", help="Value to be set") + +@@ -240,7 +239,7 @@ class TestClient(Cmd): + ap_getTargetValue.add_argument( + "Path", + help="Path whose target value is to be read", +- completer_method=path_completer, ++ completer=path_completer, + ) + + ap_getTargetValues = argparse.ArgumentParser() +@@ -248,12 +247,12 @@ class TestClient(Cmd): + "Path", + help="Path whose target value is to be read", + nargs="+", +- completer_method=path_completer, ++ completer=path_completer, + ) + + ap_subscribe = argparse.ArgumentParser() + ap_subscribe.add_argument( +- "Path", help="Path to subscribe to", completer_method=path_completer ++ "Path", help="Path to subscribe to", completer=path_completer + ) + ap_subscribe.add_argument( + "-a", "--attribute", help="Attribute to subscribe to", default="value" +@@ -268,7 +267,7 @@ class TestClient(Cmd): + + ap_subscribeMultiple = argparse.ArgumentParser() + ap_subscribeMultiple.add_argument( +- "Path", help="Path to subscribe to", nargs="+", completer_method=path_completer ++ "Path", help="Path to subscribe to", nargs="+", completer=path_completer + ) + ap_subscribeMultiple.add_argument( + "-a", "--attribute", help="Attribute to subscribe to", default="value" +@@ -284,18 +283,18 @@ class TestClient(Cmd): + ap_unsubscribe.add_argument( + "SubscribeId", + help="Corresponding subscription Id", +- completer_method=subscriptionIdCompleter, ++ completer=subscriptionIdCompleter, + ) + + ap_getMetaData = argparse.ArgumentParser() + ap_getMetaData.add_argument( + "Path", + help="Path whose metadata is to be read", +- completer_method=path_completer, ++ completer=path_completer, + ) + ap_updateMetaData = argparse.ArgumentParser() + ap_updateMetaData.add_argument( +- "Path", help="Path whose MetaData is to update", completer_method=path_completer ++ "Path", help="Path whose MetaData is to update", completer=path_completer + ) + ap_updateMetaData.add_argument( + "Json", +@@ -304,14 +303,14 @@ class TestClient(Cmd): + ) + + ap_updateVSSTree = argparse.ArgumentParser() +- jsonfile_completer_method = functools.partial( ++ jsonfile_completer = functools.partial( + Cmd.path_complete, + path_filter=lambda path: (os.path.isdir(path) or path.endswith(".json")), + ) + ap_updateVSSTree.add_argument( + "Json", + help="Json tree to update VSS", +- completer_method=jsonfile_completer_method, ++ completer=jsonfile_completer, + ) + + # Constructor, request names after protocol to avoid errors +-- +2.42.0 + diff --git a/recipes-connectivity/kuksa-val/kuksa-client/0002-kuksa-client-Add-external-certificates-support.patch b/recipes-connectivity/kuksa-val/kuksa-client/0002-kuksa-client-Add-external-certificates-support.patch new file mode 100644 index 00000000..adc19e6f --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-client/0002-kuksa-client-Add-external-certificates-support.patch @@ -0,0 +1,51 @@ +From 3f3dbe36b4adcdd7c3cef41980058331e79ce620 Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Sat, 5 Aug 2023 13:27:44 -0400 +Subject: [PATCH 2/2] kuksa_viss_client: Add external certificates support + +Tweak the definition of __certificate_dir__ in the kuksa_certificates +package, and certificate location logic in the client library to allow +picking up alternative certificates from /etc/kuksa-certificates or +/etc/kuksa-val before falling back to the shipped defaults. The +intent is to allow packagers to more straighhtforwardly use their own +certificates with both the server and clients. + +Upstream-Status: pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + kuksa-client/kuksa_client/cli_backend/__init__.py | 2 +- + kuksa-client/kuksa_client/kuksa_server_certificates/__init__.py | 7 ++++++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/kuksa-client/kuksa_client/cli_backend/__init__.py b/kuksa-client/kuksa_client/cli_backend/__init__.py +index 2cfe51e..96d94f2 100644 +--- a/kuksa-client/kuksa_client/cli_backend/__init__.py ++++ b/kuksa-client/kuksa_client/cli_backend/__init__.py +@@ -28,7 +28,7 @@ class Backend: + self.insecure = config.getboolean('insecure', False) + except AttributeError: + self.insecure = config.get('insecure', False) +- self.default_cert_path = pathlib.Path(kuksa_server_certificates.__path__[0]) ++ self.default_cert_path = pathlib.Path(kuksa_server_certificates.__certificate_dir__) + self.cacertificate = config.get( + 'cacertificate', str(self.default_cert_path / 'CA.pem')) + self.certificate = config.get('certificate', str( +diff --git a/kuksa-client/kuksa_client/kuksa_server_certificates/__init__.py b/kuksa-client/kuksa_client/kuksa_server_certificates/__init__.py +index 22ccd3f..8323868 100644 +--- a/kuksa-client/kuksa_client/kuksa_server_certificates/__init__.py ++++ b/kuksa-client/kuksa_client/kuksa_server_certificates/__init__.py +@@ -2,4 +2,9 @@ import os + + from kuksa_client._metadata import * + +-__certificate_dir__= os.path.dirname(os.path.realpath(__file__)) ++if os.path.isdir("/etc/kuksa-certificates"): ++ __certificate_dir__= "/etc/kuksa-certificates" ++elif os.path.isdir("/etc/kuksa-val"): ++ __certificate_dir__= "/etc/kuksa-val" ++else: ++ __certificate_dir__= os.path.dirname(os.path.realpath(__file__)) +-- +2.41.0 + diff --git a/recipes-connectivity/kuksa-val/kuksa-client_git.bb b/recipes-connectivity/kuksa-val/kuksa-client_git.bb new file mode 100644 index 00000000..944a2014 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-client_git.bb @@ -0,0 +1,41 @@ +SUMMARY = "Python client for KUKSA.val, the KUKSA Vehicle Abstraction Layer" +HOMEPAGE = "https://github.com/eclipse/kuksa.val" +BUGTRACKER = "https://github.com/eclipse/kuksa.val/issues" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://../LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +DEPENDS = " \ + python3-setuptools-git-versioning-native \ + python3-grpcio-tools-native \ + python3-grpcio \ +" + +PV = "0.4.2" + +SRC_URI = "gitsm://github.com/eclipse-kuksa/kuksa-python-sdk.git;protocol=https;branch=main \ + file://0001-kuksa-client-Update-cmd2-completer-usage.patch;patchdir=.. \ + file://0002-kuksa-client-Add-external-certificates-support.patch;patchdir=.. \ +" +SRCREV = "4ac107a638c8dbf5cde1743a3df2e28589990332" + +S = "${WORKDIR}/git/kuksa-client" + +inherit python_setuptools_build_meta + +RDEPENDS:${PN} += " \ + python3-cmd2 \ + python3-importlib-metadata \ + python3-pkg-resources \ + python3-pygments \ + python3-websockets \ + python3-grpcio \ + python3-grpcio-tools \ + python3-jsonpath-ng \ +" + +# A script for generating new certificates currently gets shipped inside +# the client module, for now add bash to RDEPENDS to quiet the QA error. +# This should probably be addressed with finer-grained packaging or some +# other change worked out with upstream. +RDEPENDS:${PN} += "bash" diff --git a/recipes-connectivity/kuksa-val/kuksa-databroker-agl-demo-cluster.bb b/recipes-connectivity/kuksa-val/kuksa-databroker-agl-demo-cluster.bb new file mode 100644 index 00000000..36b77dbc --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-databroker-agl-demo-cluster.bb @@ -0,0 +1,22 @@ +SUMMARY = "AGL cluster demo configuration for KUKSA.val databroker" +HOMEPAGE = "https://github.com/eclipse/kuksa.val" +BUGTRACKER = "https://github.com/eclipse/kuksa.val/issues" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = "file://kuksa-databroker.env" + +inherit allarch update-alternatives + +do_install() { + install -d ${D}${sysconfdir}/default + install -m 0644 ${WORKDIR}/kuksa-databroker.env ${D}${sysconfdir}/default/kuksa-databroker.agl-demo-cluster-support +} + +ALTERNATIVE:${PN} = "kuksa-databroker-env" +ALTERNATIVE_LINK_NAME[kuksa-databroker-env] = "${sysconfdir}/default/kuksa-databroker" +ALTERNATIVE_TARGET[kuksa-databroker-env] = "${sysconfdir}/default/kuksa-databroker.agl-demo-cluster-support" +ALTERNATIVE_PRIORITY[kuksa-databroker-env] = "20" + +RDEPENDS:${PN} += "kuksa-certificates-agl-ca" diff --git a/recipes-connectivity/kuksa-val/kuksa-databroker-agl-demo-cluster/kuksa-databroker.env b/recipes-connectivity/kuksa-val/kuksa-databroker-agl-demo-cluster/kuksa-databroker.env new file mode 100644 index 00000000..47788338 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-databroker-agl-demo-cluster/kuksa-databroker.env @@ -0,0 +1 @@ +EXTRA_ARGS="--vss /usr/share/vss/vss.json --tls-cert /etc/kuksa-val/Server.pem --tls-private-key /etc/kuksa-val/Server.key --jwt-public-key /etc/kuksa-val/jwt.key.pub --address 0.0.0.0" diff --git a/recipes-connectivity/kuksa-val/kuksa-databroker-agl.bb b/recipes-connectivity/kuksa-val/kuksa-databroker-agl.bb new file mode 100644 index 00000000..2cee2930 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-databroker-agl.bb @@ -0,0 +1,21 @@ +SUMMARY = "AGL options for KUKSA.val databroker" +HOMEPAGE = "https://github.com/eclipse/kuksa.val" +BUGTRACKER = "https://github.com/eclipse/kuksa.val/issues" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = "file://kuksa-databroker.env" + +inherit allarch update-alternatives + +do_install() { + install -d ${D}${sysconfdir}/default + install -m 0644 ${WORKDIR}/kuksa-databroker.env ${D}${sysconfdir}/default/kuksa-databroker.agl +} + +ALTERNATIVE:${PN} = "kuksa-databroker-env" +ALTERNATIVE_LINK_NAME[kuksa-databroker-env] = "${sysconfdir}/default/kuksa-databroker" +ALTERNATIVE_TARGET[kuksa-databroker-env] = "${sysconfdir}/default/kuksa-databroker.agl" + +RDEPENDS:${PN} += "kuksa-databroker kuksa-certificates-agl vss-agl" diff --git a/recipes-connectivity/kuksa-val/kuksa-databroker-agl/kuksa-databroker.env b/recipes-connectivity/kuksa-val/kuksa-databroker-agl/kuksa-databroker.env new file mode 100644 index 00000000..ff137095 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-databroker-agl/kuksa-databroker.env @@ -0,0 +1 @@ +EXTRA_ARGS="--vss /usr/share/vss/vss.json --tls-cert /etc/kuksa-val/Server.pem --tls-private-key /etc/kuksa-val/Server.key --jwt-public-key /etc/kuksa-val/jwt.key.pub" diff --git a/recipes-connectivity/kuksa-val/kuksa-databroker-crates.inc b/recipes-connectivity/kuksa-val/kuksa-databroker-crates.inc new file mode 100644 index 00000000..78a5b750 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-databroker-crates.inc @@ -0,0 +1,696 @@ +# Autogenerated with 'bitbake -c update_crates kuksa-databroker' + +# from Cargo.lock +SRC_URI += " \ + crate://crates.io/addr2line/0.21.0 \ + crate://crates.io/adler/1.0.2 \ + crate://crates.io/aho-corasick/1.1.2 \ + crate://crates.io/android-tzdata/0.1.1 \ + crate://crates.io/android_system_properties/0.1.5 \ + crate://crates.io/ansi_term/0.12.1 \ + crate://crates.io/anstream/0.6.4 \ + crate://crates.io/anstyle/1.0.4 \ + crate://crates.io/anstyle-parse/0.2.2 \ + crate://crates.io/anstyle-query/1.0.0 \ + crate://crates.io/anstyle-wincon/3.0.1 \ + crate://crates.io/anyhow/1.0.75 \ + crate://crates.io/arc-swap/1.6.0 \ + crate://crates.io/arrayref/0.3.7 \ + crate://crates.io/arrayvec/0.5.2 \ + crate://crates.io/async-stream/0.3.5 \ + crate://crates.io/async-stream-impl/0.3.5 \ + crate://crates.io/async-trait/0.1.74 \ + crate://crates.io/autocfg/1.1.0 \ + crate://crates.io/axum/0.6.20 \ + crate://crates.io/axum-core/0.3.4 \ + crate://crates.io/backtrace/0.3.69 \ + crate://crates.io/base64/0.13.1 \ + crate://crates.io/base64/0.21.5 \ + crate://crates.io/bitflags/1.3.2 \ + crate://crates.io/bitflags/2.4.1 \ + crate://crates.io/blake2b_simd/0.5.11 \ + crate://crates.io/block-buffer/0.10.4 \ + crate://crates.io/bstr/1.7.0 \ + crate://crates.io/btoi/0.4.3 \ + crate://crates.io/bumpalo/3.14.0 \ + crate://crates.io/bytecount/0.6.7 \ + crate://crates.io/byteorder/1.5.0 \ + crate://crates.io/bytes/1.5.0 \ + crate://crates.io/cc/1.0.83 \ + crate://crates.io/cfg-if/1.0.0 \ + crate://crates.io/chrono/0.4.31 \ + crate://crates.io/clap/4.4.7 \ + crate://crates.io/clap_builder/4.4.7 \ + crate://crates.io/clap_derive/4.4.7 \ + crate://crates.io/clap_lex/0.6.0 \ + crate://crates.io/clru/0.6.1 \ + crate://crates.io/colorchoice/1.0.0 \ + crate://crates.io/console/0.15.7 \ + crate://crates.io/constant_time_eq/0.1.5 \ + crate://crates.io/core-foundation-sys/0.8.4 \ + crate://crates.io/cpufeatures/0.2.11 \ + crate://crates.io/crc32fast/1.3.2 \ + crate://crates.io/crossbeam-utils/0.8.16 \ + crate://crates.io/crypto-common/0.1.6 \ + crate://crates.io/cucumber/0.20.1 \ + crate://crates.io/cucumber-codegen/0.20.1 \ + crate://crates.io/cucumber-expressions/0.3.0 \ + crate://crates.io/data-encoding/2.4.0 \ + crate://crates.io/deranged/0.3.9 \ + crate://crates.io/derive_more/0.99.17 \ + crate://crates.io/digest/0.10.7 \ + crate://crates.io/dirs/1.0.5 \ + crate://crates.io/dirs/4.0.0 \ + crate://crates.io/dirs-sys/0.3.7 \ + crate://crates.io/drain_filter_polyfill/0.1.3 \ + crate://crates.io/dunce/1.0.4 \ + crate://crates.io/either/1.9.0 \ + crate://crates.io/encode_unicode/0.3.6 \ + crate://crates.io/equivalent/1.0.1 \ + crate://crates.io/errno/0.3.5 \ + crate://crates.io/faster-hex/0.8.1 \ + crate://crates.io/fastrand/2.0.1 \ + crate://crates.io/filetime/0.2.22 \ + crate://crates.io/fixedbitset/0.4.2 \ + crate://crates.io/flate2/1.0.28 \ + crate://crates.io/fnv/1.0.7 \ + crate://crates.io/form_urlencoded/1.2.0 \ + crate://crates.io/futures/0.3.29 \ + crate://crates.io/futures-channel/0.3.29 \ + crate://crates.io/futures-core/0.3.29 \ + crate://crates.io/futures-executor/0.3.29 \ + crate://crates.io/futures-io/0.3.29 \ + crate://crates.io/futures-macro/0.3.29 \ + crate://crates.io/futures-sink/0.3.29 \ + crate://crates.io/futures-task/0.3.29 \ + crate://crates.io/futures-util/0.3.29 \ + crate://crates.io/generic-array/0.14.7 \ + crate://crates.io/getrandom/0.1.16 \ + crate://crates.io/getrandom/0.2.10 \ + crate://crates.io/gherkin/0.14.0 \ + crate://crates.io/gimli/0.28.0 \ + crate://crates.io/gix/0.53.1 \ + crate://crates.io/gix-actor/0.26.0 \ + crate://crates.io/gix-bitmap/0.2.7 \ + crate://crates.io/gix-chunk/0.4.4 \ + crate://crates.io/gix-commitgraph/0.20.0 \ + crate://crates.io/gix-config/0.29.0 \ + crate://crates.io/gix-config-value/0.14.0 \ + crate://crates.io/gix-date/0.8.0 \ + crate://crates.io/gix-diff/0.35.0 \ + crate://crates.io/gix-discover/0.24.0 \ + crate://crates.io/gix-features/0.34.0 \ + crate://crates.io/gix-fs/0.6.0 \ + crate://crates.io/gix-glob/0.12.0 \ + crate://crates.io/gix-hash/0.13.1 \ + crate://crates.io/gix-hashtable/0.4.0 \ + crate://crates.io/gix-index/0.24.0 \ + crate://crates.io/gix-lock/9.0.0 \ + crate://crates.io/gix-macros/0.1.0 \ + crate://crates.io/gix-object/0.36.0 \ + crate://crates.io/gix-odb/0.52.0 \ + crate://crates.io/gix-pack/0.42.0 \ + crate://crates.io/gix-path/0.10.0 \ + crate://crates.io/gix-quote/0.4.7 \ + crate://crates.io/gix-ref/0.36.0 \ + crate://crates.io/gix-refspec/0.17.0 \ + crate://crates.io/gix-revision/0.21.0 \ + crate://crates.io/gix-revwalk/0.7.0 \ + crate://crates.io/gix-sec/0.10.0 \ + crate://crates.io/gix-tempfile/9.0.0 \ + crate://crates.io/gix-trace/0.1.3 \ + crate://crates.io/gix-traverse/0.32.0 \ + crate://crates.io/gix-url/0.23.0 \ + crate://crates.io/gix-utils/0.1.5 \ + crate://crates.io/gix-validate/0.8.0 \ + crate://crates.io/globset/0.4.13 \ + crate://crates.io/globwalk/0.8.1 \ + crate://crates.io/h2/0.3.21 \ + crate://crates.io/hashbrown/0.12.3 \ + crate://crates.io/hashbrown/0.14.2 \ + crate://crates.io/heck/0.4.1 \ + crate://crates.io/hermit-abi/0.3.3 \ + crate://crates.io/home/0.5.5 \ + crate://crates.io/http/0.2.9 \ + crate://crates.io/http-body/0.4.5 \ + crate://crates.io/httparse/1.8.0 \ + crate://crates.io/httpdate/1.0.3 \ + crate://crates.io/humantime/2.1.0 \ + crate://crates.io/hyper/0.14.27 \ + crate://crates.io/hyper-timeout/0.4.1 \ + crate://crates.io/iana-time-zone/0.1.58 \ + crate://crates.io/iana-time-zone-haiku/0.1.2 \ + crate://crates.io/idna/0.4.0 \ + crate://crates.io/ignore/0.4.20 \ + crate://crates.io/indexmap/1.9.3 \ + crate://crates.io/indexmap/2.0.2 \ + crate://crates.io/inflections/1.1.1 \ + crate://crates.io/inventory/0.3.12 \ + crate://crates.io/itertools/0.10.5 \ + crate://crates.io/itertools/0.11.0 \ + crate://crates.io/itoa/1.0.9 \ + crate://crates.io/jemalloc-sys/0.5.4+5.3.0-patched \ + crate://crates.io/jemallocator/0.5.4 \ + crate://crates.io/js-sys/0.3.64 \ + crate://crates.io/jsonwebtoken/9.1.0 \ + crate://crates.io/lazy-regex/3.0.2 \ + crate://crates.io/lazy-regex-proc_macros/3.0.1 \ + crate://crates.io/lazy_static/1.4.0 \ + crate://crates.io/libc/0.2.149 \ + crate://crates.io/linefeed/0.6.0 \ + crate://crates.io/linked-hash-map/0.5.6 \ + crate://crates.io/linux-raw-sys/0.4.10 \ + crate://crates.io/lock_api/0.4.11 \ + crate://crates.io/log/0.4.20 \ + crate://crates.io/matchers/0.1.0 \ + crate://crates.io/matchit/0.7.3 \ + crate://crates.io/memchr/2.6.4 \ + crate://crates.io/memmap2/0.7.1 \ + crate://crates.io/mime/0.3.17 \ + crate://crates.io/minimal-lexical/0.2.1 \ + crate://crates.io/miniz_oxide/0.7.1 \ + crate://crates.io/mio/0.8.9 \ + crate://crates.io/mortal/0.2.4 \ + crate://crates.io/multimap/0.8.3 \ + crate://crates.io/nix/0.26.4 \ + crate://crates.io/nom/7.1.3 \ + crate://crates.io/nom_locate/4.2.0 \ + crate://crates.io/nu-ansi-term/0.46.0 \ + crate://crates.io/num-bigint/0.4.4 \ + crate://crates.io/num-integer/0.1.45 \ + crate://crates.io/num-traits/0.2.17 \ + crate://crates.io/num_cpus/1.16.0 \ + crate://crates.io/num_threads/0.1.6 \ + crate://crates.io/object/0.32.1 \ + crate://crates.io/once_cell/1.18.0 \ + crate://crates.io/overload/0.1.1 \ + crate://crates.io/parking_lot/0.12.1 \ + crate://crates.io/parking_lot_core/0.9.9 \ + crate://crates.io/peg/0.6.3 \ + crate://crates.io/peg-macros/0.6.3 \ + crate://crates.io/peg-runtime/0.6.3 \ + crate://crates.io/pem/3.0.2 \ + crate://crates.io/percent-encoding/2.3.0 \ + crate://crates.io/petgraph/0.6.4 \ + crate://crates.io/phf/0.11.2 \ + crate://crates.io/phf_codegen/0.11.2 \ + crate://crates.io/phf_generator/0.11.2 \ + crate://crates.io/phf_shared/0.11.2 \ + crate://crates.io/pin-project/1.1.3 \ + crate://crates.io/pin-project-internal/1.1.3 \ + crate://crates.io/pin-project-lite/0.2.13 \ + crate://crates.io/pin-utils/0.1.0 \ + crate://crates.io/powerfmt/0.2.0 \ + crate://crates.io/ppv-lite86/0.2.17 \ + crate://crates.io/prettyplease/0.1.25 \ + crate://crates.io/proc-macro2/1.0.69 \ + crate://crates.io/prodash/26.2.2 \ + crate://crates.io/prost/0.11.9 \ + crate://crates.io/prost-build/0.11.9 \ + crate://crates.io/prost-derive/0.11.9 \ + crate://crates.io/prost-types/0.11.9 \ + crate://crates.io/quote/1.0.33 \ + crate://crates.io/rand/0.8.5 \ + crate://crates.io/rand_chacha/0.3.1 \ + crate://crates.io/rand_core/0.6.4 \ + crate://crates.io/redox_syscall/0.1.57 \ + crate://crates.io/redox_syscall/0.2.16 \ + crate://crates.io/redox_syscall/0.3.5 \ + crate://crates.io/redox_syscall/0.4.1 \ + crate://crates.io/redox_users/0.3.5 \ + crate://crates.io/redox_users/0.4.3 \ + crate://crates.io/regex/1.10.2 \ + crate://crates.io/regex-automata/0.1.10 \ + crate://crates.io/regex-automata/0.4.3 \ + crate://crates.io/regex-syntax/0.6.29 \ + crate://crates.io/regex-syntax/0.7.5 \ + crate://crates.io/regex-syntax/0.8.2 \ + crate://crates.io/ring/0.17.5 \ + crate://crates.io/rust-argon2/0.8.3 \ + crate://crates.io/rustc-demangle/0.1.23 \ + crate://crates.io/rustix/0.38.21 \ + crate://crates.io/rustls/0.21.8 \ + crate://crates.io/rustls-pemfile/1.0.3 \ + crate://crates.io/rustls-webpki/0.101.7 \ + crate://crates.io/rustversion/1.0.14 \ + crate://crates.io/ryu/1.0.15 \ + crate://crates.io/same-file/1.0.6 \ + crate://crates.io/scopeguard/1.2.0 \ + crate://crates.io/sct/0.7.1 \ + crate://crates.io/sealed/0.5.0 \ + crate://crates.io/serde/1.0.190 \ + crate://crates.io/serde_derive/1.0.190 \ + crate://crates.io/serde_json/1.0.107 \ + crate://crates.io/serde_path_to_error/0.1.14 \ + crate://crates.io/serde_urlencoded/0.7.1 \ + crate://crates.io/sha1/0.10.6 \ + crate://crates.io/sha1_smol/1.0.0 \ + crate://crates.io/sharded-slab/0.1.7 \ + crate://crates.io/signal-hook/0.3.17 \ + crate://crates.io/signal-hook-registry/1.4.1 \ + crate://crates.io/simple_asn1/0.6.2 \ + crate://crates.io/siphasher/0.3.11 \ + crate://crates.io/slab/0.4.9 \ + crate://crates.io/smallstr/0.2.0 \ + crate://crates.io/smallvec/1.11.1 \ + crate://crates.io/smart-default/0.7.1 \ + crate://crates.io/smawk/0.3.2 \ + crate://crates.io/socket2/0.4.10 \ + crate://crates.io/socket2/0.5.5 \ + crate://crates.io/spin/0.9.8 \ + crate://crates.io/sqlparser/0.16.0 \ + crate://crates.io/strsim/0.10.0 \ + crate://crates.io/syn/1.0.109 \ + crate://crates.io/syn/2.0.38 \ + crate://crates.io/sync_wrapper/0.1.2 \ + crate://crates.io/synthez/0.3.1 \ + crate://crates.io/synthez-codegen/0.3.1 \ + crate://crates.io/synthez-core/0.3.1 \ + crate://crates.io/tempfile/3.8.1 \ + crate://crates.io/terminal_size/0.3.0 \ + crate://crates.io/terminfo/0.8.0 \ + crate://crates.io/textwrap/0.16.0 \ + crate://crates.io/thiserror/1.0.50 \ + crate://crates.io/thiserror-impl/1.0.50 \ + crate://crates.io/thread_local/1.1.7 \ + crate://crates.io/time/0.3.30 \ + crate://crates.io/time-core/0.1.2 \ + crate://crates.io/time-macros/0.2.15 \ + crate://crates.io/tinyvec/1.6.0 \ + crate://crates.io/tinyvec_macros/0.1.1 \ + crate://crates.io/tokio/1.33.0 \ + crate://crates.io/tokio-io-timeout/1.2.0 \ + crate://crates.io/tokio-macros/2.1.0 \ + crate://crates.io/tokio-rustls/0.24.1 \ + crate://crates.io/tokio-stream/0.1.14 \ + crate://crates.io/tokio-tungstenite/0.20.1 \ + crate://crates.io/tokio-util/0.7.10 \ + crate://crates.io/tonic/0.9.2 \ + crate://crates.io/tonic-build/0.8.4 \ + crate://crates.io/tower/0.4.13 \ + crate://crates.io/tower-layer/0.3.2 \ + crate://crates.io/tower-service/0.3.2 \ + crate://crates.io/tracing/0.1.40 \ + crate://crates.io/tracing-attributes/0.1.27 \ + crate://crates.io/tracing-core/0.1.32 \ + crate://crates.io/tracing-subscriber/0.3.17 \ + crate://crates.io/try-lock/0.2.4 \ + crate://crates.io/tungstenite/0.20.1 \ + crate://crates.io/typed-builder/0.15.2 \ + crate://crates.io/typed-builder-macro/0.15.2 \ + crate://crates.io/typenum/1.17.0 \ + crate://crates.io/unicode-bidi/0.3.13 \ + crate://crates.io/unicode-bom/2.0.2 \ + crate://crates.io/unicode-ident/1.0.12 \ + crate://crates.io/unicode-linebreak/0.1.5 \ + crate://crates.io/unicode-normalization/0.1.22 \ + crate://crates.io/unicode-width/0.1.11 \ + crate://crates.io/untrusted/0.9.0 \ + crate://crates.io/url/2.4.1 \ + crate://crates.io/utf-8/0.7.6 \ + crate://crates.io/utf8parse/0.2.1 \ + crate://crates.io/uuid/1.5.0 \ + crate://crates.io/vergen/8.2.5 \ + crate://crates.io/version_check/0.9.4 \ + crate://crates.io/walkdir/2.4.0 \ + crate://crates.io/want/0.3.1 \ + crate://crates.io/wasi/0.9.0+wasi-snapshot-preview1 \ + crate://crates.io/wasi/0.11.0+wasi-snapshot-preview1 \ + crate://crates.io/wasm-bindgen/0.2.87 \ + crate://crates.io/wasm-bindgen-backend/0.2.87 \ + crate://crates.io/wasm-bindgen-macro/0.2.87 \ + crate://crates.io/wasm-bindgen-macro-support/0.2.87 \ + crate://crates.io/wasm-bindgen-shared/0.2.87 \ + crate://crates.io/which/4.4.2 \ + crate://crates.io/winapi/0.3.9 \ + crate://crates.io/winapi-i686-pc-windows-gnu/0.4.0 \ + crate://crates.io/winapi-util/0.1.6 \ + crate://crates.io/winapi-x86_64-pc-windows-gnu/0.4.0 \ + crate://crates.io/windows/0.48.0 \ + crate://crates.io/windows-core/0.51.1 \ + crate://crates.io/windows-sys/0.45.0 \ + crate://crates.io/windows-sys/0.48.0 \ + crate://crates.io/windows-targets/0.42.2 \ + crate://crates.io/windows-targets/0.48.5 \ + crate://crates.io/windows_aarch64_gnullvm/0.42.2 \ + crate://crates.io/windows_aarch64_gnullvm/0.48.5 \ + crate://crates.io/windows_aarch64_msvc/0.42.2 \ + crate://crates.io/windows_aarch64_msvc/0.48.5 \ + crate://crates.io/windows_i686_gnu/0.42.2 \ + crate://crates.io/windows_i686_gnu/0.48.5 \ + crate://crates.io/windows_i686_msvc/0.42.2 \ + crate://crates.io/windows_i686_msvc/0.48.5 \ + crate://crates.io/windows_x86_64_gnu/0.42.2 \ + crate://crates.io/windows_x86_64_gnu/0.48.5 \ + crate://crates.io/windows_x86_64_gnullvm/0.42.2 \ + crate://crates.io/windows_x86_64_gnullvm/0.48.5 \ + crate://crates.io/windows_x86_64_msvc/0.42.2 \ + crate://crates.io/windows_x86_64_msvc/0.48.5 \ + crate://crates.io/winnow/0.5.17 \ +" + +SRC_URI[addr2line-0.21.0.sha256sum] = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +SRC_URI[adler-1.0.2.sha256sum] = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +SRC_URI[aho-corasick-1.1.2.sha256sum] = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +SRC_URI[android-tzdata-0.1.1.sha256sum] = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +SRC_URI[android_system_properties-0.1.5.sha256sum] = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +SRC_URI[ansi_term-0.12.1.sha256sum] = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +SRC_URI[anstream-0.6.4.sha256sum] = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +SRC_URI[anstyle-1.0.4.sha256sum] = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +SRC_URI[anstyle-parse-0.2.2.sha256sum] = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +SRC_URI[anstyle-query-1.0.0.sha256sum] = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +SRC_URI[anstyle-wincon-3.0.1.sha256sum] = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +SRC_URI[anyhow-1.0.75.sha256sum] = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +SRC_URI[arc-swap-1.6.0.sha256sum] = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +SRC_URI[arrayref-0.3.7.sha256sum] = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +SRC_URI[arrayvec-0.5.2.sha256sum] = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +SRC_URI[async-stream-0.3.5.sha256sum] = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +SRC_URI[async-stream-impl-0.3.5.sha256sum] = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +SRC_URI[async-trait-0.1.74.sha256sum] = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +SRC_URI[autocfg-1.1.0.sha256sum] = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +SRC_URI[axum-0.6.20.sha256sum] = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +SRC_URI[axum-core-0.3.4.sha256sum] = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +SRC_URI[backtrace-0.3.69.sha256sum] = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +SRC_URI[base64-0.13.1.sha256sum] = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +SRC_URI[base64-0.21.5.sha256sum] = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +SRC_URI[bitflags-1.3.2.sha256sum] = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +SRC_URI[bitflags-2.4.1.sha256sum] = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +SRC_URI[blake2b_simd-0.5.11.sha256sum] = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +SRC_URI[block-buffer-0.10.4.sha256sum] = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +SRC_URI[bstr-1.7.0.sha256sum] = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" +SRC_URI[btoi-0.4.3.sha256sum] = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" +SRC_URI[bumpalo-3.14.0.sha256sum] = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +SRC_URI[bytecount-0.6.7.sha256sum] = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +SRC_URI[byteorder-1.5.0.sha256sum] = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +SRC_URI[bytes-1.5.0.sha256sum] = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +SRC_URI[cc-1.0.83.sha256sum] = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +SRC_URI[cfg-if-1.0.0.sha256sum] = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +SRC_URI[chrono-0.4.31.sha256sum] = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +SRC_URI[clap-4.4.7.sha256sum] = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +SRC_URI[clap_builder-4.4.7.sha256sum] = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +SRC_URI[clap_derive-4.4.7.sha256sum] = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +SRC_URI[clap_lex-0.6.0.sha256sum] = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +SRC_URI[clru-0.6.1.sha256sum] = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807" +SRC_URI[colorchoice-1.0.0.sha256sum] = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +SRC_URI[console-0.15.7.sha256sum] = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +SRC_URI[constant_time_eq-0.1.5.sha256sum] = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +SRC_URI[core-foundation-sys-0.8.4.sha256sum] = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +SRC_URI[cpufeatures-0.2.11.sha256sum] = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +SRC_URI[crc32fast-1.3.2.sha256sum] = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +SRC_URI[crossbeam-utils-0.8.16.sha256sum] = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +SRC_URI[crypto-common-0.1.6.sha256sum] = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +SRC_URI[cucumber-0.20.1.sha256sum] = "08c1c99a359eddd550cbe157e9d8be68f4ba5fb48a668ca6702e82c3503770ef" +SRC_URI[cucumber-codegen-0.20.1.sha256sum] = "eec3b6ad01b305d2ddc5e48eb4e31c5d79b1cd2807ee870b7711c895d2b57434" +SRC_URI[cucumber-expressions-0.3.0.sha256sum] = "d794fed319eea24246fb5f57632f7ae38d61195817b7eb659455aa5bdd7c1810" +SRC_URI[data-encoding-2.4.0.sha256sum] = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +SRC_URI[deranged-0.3.9.sha256sum] = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +SRC_URI[derive_more-0.99.17.sha256sum] = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +SRC_URI[digest-0.10.7.sha256sum] = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +SRC_URI[dirs-1.0.5.sha256sum] = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +SRC_URI[dirs-4.0.0.sha256sum] = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +SRC_URI[dirs-sys-0.3.7.sha256sum] = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +SRC_URI[drain_filter_polyfill-0.1.3.sha256sum] = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" +SRC_URI[dunce-1.0.4.sha256sum] = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +SRC_URI[either-1.9.0.sha256sum] = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +SRC_URI[encode_unicode-0.3.6.sha256sum] = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +SRC_URI[equivalent-1.0.1.sha256sum] = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +SRC_URI[errno-0.3.5.sha256sum] = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +SRC_URI[faster-hex-0.8.1.sha256sum] = "239f7bfb930f820ab16a9cd95afc26f88264cf6905c960b340a615384aa3338a" +SRC_URI[fastrand-2.0.1.sha256sum] = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +SRC_URI[filetime-0.2.22.sha256sum] = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +SRC_URI[fixedbitset-0.4.2.sha256sum] = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +SRC_URI[flate2-1.0.28.sha256sum] = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +SRC_URI[fnv-1.0.7.sha256sum] = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +SRC_URI[form_urlencoded-1.2.0.sha256sum] = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +SRC_URI[futures-0.3.29.sha256sum] = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +SRC_URI[futures-channel-0.3.29.sha256sum] = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +SRC_URI[futures-core-0.3.29.sha256sum] = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +SRC_URI[futures-executor-0.3.29.sha256sum] = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +SRC_URI[futures-io-0.3.29.sha256sum] = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +SRC_URI[futures-macro-0.3.29.sha256sum] = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +SRC_URI[futures-sink-0.3.29.sha256sum] = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +SRC_URI[futures-task-0.3.29.sha256sum] = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +SRC_URI[futures-util-0.3.29.sha256sum] = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +SRC_URI[generic-array-0.14.7.sha256sum] = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +SRC_URI[getrandom-0.1.16.sha256sum] = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +SRC_URI[getrandom-0.2.10.sha256sum] = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +SRC_URI[gherkin-0.14.0.sha256sum] = "20b79820c0df536d1f3a089a2fa958f61cb96ce9e0f3f8f507f5a31179567755" +SRC_URI[gimli-0.28.0.sha256sum] = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +SRC_URI[gix-0.53.1.sha256sum] = "06a8c9f9452078f474fecd2880de84819b8c77224ab62273275b646bf785f906" +SRC_URI[gix-actor-0.26.0.sha256sum] = "8e8c6778cc03bca978b2575a03e04e5ba6f430a9dd9b0f1259f0a8a9a5e5cc66" +SRC_URI[gix-bitmap-0.2.7.sha256sum] = "0ccab4bc576844ddb51b78d81b4a42d73e6229660fa614dfc3d3999c874d1959" +SRC_URI[gix-chunk-0.4.4.sha256sum] = "5b42ea64420f7994000130328f3c7a2038f639120518870436d31b8bde704493" +SRC_URI[gix-commitgraph-0.20.0.sha256sum] = "4676ede3a7d37e7028e2889830349a6aca22efc1d2f2dd9fa3351c1a8ddb0c6a" +SRC_URI[gix-config-0.29.0.sha256sum] = "1108c4ac88248dd25cc8ab0d0dae796e619fb72d92f88e30e00b29d61bb93cc4" +SRC_URI[gix-config-value-0.14.0.sha256sum] = "ea7505b97f4d8e7933e29735a568ba2f86d8de466669d9f0e8321384f9972f47" +SRC_URI[gix-date-0.8.0.sha256sum] = "fc7df669639582dc7c02737642f76890b03b5544e141caba68a7d6b4eb551e0d" +SRC_URI[gix-diff-0.35.0.sha256sum] = "b45e342d148373bd9070d557e6fb1280aeae29a3e05e32506682d027278501eb" +SRC_URI[gix-discover-0.24.0.sha256sum] = "da4cacda5ee9dd1b38b0e2506834e40e66c08cf050ef55c344334c76745f277b" +SRC_URI[gix-features-0.34.0.sha256sum] = "f414c99e1a7abc69b21f3225a6539d203b0513f1d1d448607c4ea81cdcf9ee59" +SRC_URI[gix-fs-0.6.0.sha256sum] = "404795da3d4c660c9ab6c3b2ad76d459636d1e1e4b37b0c7ff68eee898c298d4" +SRC_URI[gix-glob-0.12.0.sha256sum] = "e3ac79c444193b0660fe0c0925d338bd338bd643e32138784dccfb12c628b892" +SRC_URI[gix-hash-0.13.1.sha256sum] = "1884c7b41ea0875217c1be9ce91322f90bde433e91d374d0e1276073a51ccc60" +SRC_URI[gix-hashtable-0.4.0.sha256sum] = "409268480841ad008e81c17ca5a293393fbf9f2b6c2f85b8ab9de1f0c5176a16" +SRC_URI[gix-index-0.24.0.sha256sum] = "0e9599fc30b3d6aad231687a403f85dfa36ae37ccf1b68ee1f621ad5b7fc7a0d" +SRC_URI[gix-lock-9.0.0.sha256sum] = "1568c3d90594c60d52670f325f5db88c2d572e85c8dd45fabc23d91cadb0fd52" +SRC_URI[gix-macros-0.1.0.sha256sum] = "9d8acb5ee668d55f0f2d19a320a3f9ef67a6999ad483e11135abcc2464ed18b6" +SRC_URI[gix-object-0.36.0.sha256sum] = "3e5528d5b2c984044d547e696e44a8c45fa122e83cd8c2ac1da69bd474336be8" +SRC_URI[gix-odb-0.52.0.sha256sum] = "d0446eca295459deb3d6dd6ed7d44a631479f1b7381d8087166605c7a9f717c6" +SRC_URI[gix-pack-0.42.0.sha256sum] = "be19ee650300d7cbac5829b637685ec44a8d921a7c2eaff8a245d8f2f008870c" +SRC_URI[gix-path-0.10.0.sha256sum] = "6a1d370115171e3ae03c5c6d4f7d096f2981a40ddccb98dfd704c773530ba73b" +SRC_URI[gix-quote-0.4.7.sha256sum] = "475c86a97dd0127ba4465fbb239abac9ea10e68301470c9791a6dd5351cdc905" +SRC_URI[gix-ref-0.36.0.sha256sum] = "3cccbfa8d5cd9b86465f27a521e0c017de54b92d9fd37c143e49c658a2f04f3a" +SRC_URI[gix-refspec-0.17.0.sha256sum] = "678ba30d95baa5462df9875628ed40655d5f5b8aba7028de86ed57f36e762c6c" +SRC_URI[gix-revision-0.21.0.sha256sum] = "b3e80a5992ae446fe1745dd26523b86084e3f1b6b3e35377fe09b4f35ac8f151" +SRC_URI[gix-revwalk-0.7.0.sha256sum] = "b806349bc1f668e09035800e07ac8045da4e39a8925a245d93142c4802224ec1" +SRC_URI[gix-sec-0.10.0.sha256sum] = "92b9542ac025a8c02ed5d17b3fc031a111a384e859d0be3532ec4d58c40a0f28" +SRC_URI[gix-tempfile-9.0.0.sha256sum] = "2762b91ff95e27ff3ea95758c0d4efacd7435a1be3629622928b8276de0f72a8" +SRC_URI[gix-trace-0.1.3.sha256sum] = "96b6d623a1152c3facb79067d6e2ecdae48130030cf27d6eb21109f13bd7b836" +SRC_URI[gix-traverse-0.32.0.sha256sum] = "3ec6358f8373fb018af8fc96c9d2ec6a5b66999e2377dc40b7801351fec409ed" +SRC_URI[gix-url-0.23.0.sha256sum] = "1c79d595b99a6c7ab274f3c991735a0c0f5a816a3da460f513c48edf1c7bf2cc" +SRC_URI[gix-utils-0.1.5.sha256sum] = "b85d89dc728613e26e0ed952a19583744e7f5240fcd4aa30d6c824ffd8b52f0f" +SRC_URI[gix-validate-0.8.0.sha256sum] = "e05cab2b03a45b866156e052aa38619f4ece4adcb2f79978bfc249bc3b21b8c5" +SRC_URI[globset-0.4.13.sha256sum] = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +SRC_URI[globwalk-0.8.1.sha256sum] = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +SRC_URI[h2-0.3.21.sha256sum] = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +SRC_URI[hashbrown-0.12.3.sha256sum] = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +SRC_URI[hashbrown-0.14.2.sha256sum] = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +SRC_URI[heck-0.4.1.sha256sum] = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +SRC_URI[hermit-abi-0.3.3.sha256sum] = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +SRC_URI[home-0.5.5.sha256sum] = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +SRC_URI[http-0.2.9.sha256sum] = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +SRC_URI[http-body-0.4.5.sha256sum] = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +SRC_URI[httparse-1.8.0.sha256sum] = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +SRC_URI[httpdate-1.0.3.sha256sum] = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +SRC_URI[humantime-2.1.0.sha256sum] = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +SRC_URI[hyper-0.14.27.sha256sum] = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +SRC_URI[hyper-timeout-0.4.1.sha256sum] = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +SRC_URI[iana-time-zone-0.1.58.sha256sum] = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +SRC_URI[iana-time-zone-haiku-0.1.2.sha256sum] = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +SRC_URI[idna-0.4.0.sha256sum] = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +SRC_URI[ignore-0.4.20.sha256sum] = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +SRC_URI[indexmap-1.9.3.sha256sum] = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +SRC_URI[indexmap-2.0.2.sha256sum] = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +SRC_URI[inflections-1.1.1.sha256sum] = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" +SRC_URI[inventory-0.3.12.sha256sum] = "e1be380c410bf0595e94992a648ea89db4dd3f3354ba54af206fd2a68cf5ac8e" +SRC_URI[itertools-0.10.5.sha256sum] = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +SRC_URI[itertools-0.11.0.sha256sum] = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +SRC_URI[itoa-1.0.9.sha256sum] = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +SRC_URI[jemalloc-sys-0.5.4+5.3.0-patched.sha256sum] = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" +SRC_URI[jemallocator-0.5.4.sha256sum] = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc" +SRC_URI[js-sys-0.3.64.sha256sum] = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +SRC_URI[jsonwebtoken-9.1.0.sha256sum] = "155c4d7e39ad04c172c5e3a99c434ea3b4a7ba7960b38ecd562b270b097cce09" +SRC_URI[lazy-regex-3.0.2.sha256sum] = "e723bd417b2df60a0f6a2b6825f297ea04b245d4ba52b5a22cb679bdf58b05fa" +SRC_URI[lazy-regex-proc_macros-3.0.1.sha256sum] = "0f0a1d9139f0ee2e862e08a9c5d0ba0470f2aa21cd1e1aa1b1562f83116c725f" +SRC_URI[lazy_static-1.4.0.sha256sum] = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +SRC_URI[libc-0.2.149.sha256sum] = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +SRC_URI[linefeed-0.6.0.sha256sum] = "28715d08e35c6c074f9ae6b2e6a2420bac75d050c66ecd669d7d5b98e2caa036" +SRC_URI[linked-hash-map-0.5.6.sha256sum] = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +SRC_URI[linux-raw-sys-0.4.10.sha256sum] = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +SRC_URI[lock_api-0.4.11.sha256sum] = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +SRC_URI[log-0.4.20.sha256sum] = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +SRC_URI[matchers-0.1.0.sha256sum] = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +SRC_URI[matchit-0.7.3.sha256sum] = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +SRC_URI[memchr-2.6.4.sha256sum] = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +SRC_URI[memmap2-0.7.1.sha256sum] = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +SRC_URI[mime-0.3.17.sha256sum] = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +SRC_URI[minimal-lexical-0.2.1.sha256sum] = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +SRC_URI[miniz_oxide-0.7.1.sha256sum] = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +SRC_URI[mio-0.8.9.sha256sum] = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +SRC_URI[mortal-0.2.4.sha256sum] = "2c624fa1b7aab6bd2aff6e9b18565cc0363b6d45cbcd7465c9ed5e3740ebf097" +SRC_URI[multimap-0.8.3.sha256sum] = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +SRC_URI[nix-0.26.4.sha256sum] = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +SRC_URI[nom-7.1.3.sha256sum] = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +SRC_URI[nom_locate-4.2.0.sha256sum] = "1e3c83c053b0713da60c5b8de47fe8e494fe3ece5267b2f23090a07a053ba8f3" +SRC_URI[nu-ansi-term-0.46.0.sha256sum] = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +SRC_URI[num-bigint-0.4.4.sha256sum] = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +SRC_URI[num-integer-0.1.45.sha256sum] = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +SRC_URI[num-traits-0.2.17.sha256sum] = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +SRC_URI[num_cpus-1.16.0.sha256sum] = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +SRC_URI[num_threads-0.1.6.sha256sum] = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +SRC_URI[object-0.32.1.sha256sum] = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +SRC_URI[once_cell-1.18.0.sha256sum] = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +SRC_URI[overload-0.1.1.sha256sum] = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +SRC_URI[parking_lot-0.12.1.sha256sum] = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +SRC_URI[parking_lot_core-0.9.9.sha256sum] = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +SRC_URI[peg-0.6.3.sha256sum] = "9f76678828272f177ac33b7e2ac2e3e73cc6c1cd1e3e387928aa69562fa51367" +SRC_URI[peg-macros-0.6.3.sha256sum] = "636d60acf97633e48d266d7415a9355d4389cea327a193f87df395d88cd2b14d" +SRC_URI[peg-runtime-0.6.3.sha256sum] = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5" +SRC_URI[pem-3.0.2.sha256sum] = "3163d2912b7c3b52d651a055f2c7eec9ba5cd22d26ef75b8dd3a59980b185923" +SRC_URI[percent-encoding-2.3.0.sha256sum] = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +SRC_URI[petgraph-0.6.4.sha256sum] = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +SRC_URI[phf-0.11.2.sha256sum] = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +SRC_URI[phf_codegen-0.11.2.sha256sum] = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +SRC_URI[phf_generator-0.11.2.sha256sum] = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +SRC_URI[phf_shared-0.11.2.sha256sum] = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +SRC_URI[pin-project-1.1.3.sha256sum] = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +SRC_URI[pin-project-internal-1.1.3.sha256sum] = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +SRC_URI[pin-project-lite-0.2.13.sha256sum] = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +SRC_URI[pin-utils-0.1.0.sha256sum] = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +SRC_URI[powerfmt-0.2.0.sha256sum] = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +SRC_URI[ppv-lite86-0.2.17.sha256sum] = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +SRC_URI[prettyplease-0.1.25.sha256sum] = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +SRC_URI[proc-macro2-1.0.69.sha256sum] = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +SRC_URI[prodash-26.2.2.sha256sum] = "794b5bf8e2d19b53dcdcec3e4bba628e20f5b6062503ba89281fa7037dd7bbcf" +SRC_URI[prost-0.11.9.sha256sum] = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +SRC_URI[prost-build-0.11.9.sha256sum] = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +SRC_URI[prost-derive-0.11.9.sha256sum] = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +SRC_URI[prost-types-0.11.9.sha256sum] = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +SRC_URI[quote-1.0.33.sha256sum] = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +SRC_URI[rand-0.8.5.sha256sum] = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +SRC_URI[rand_chacha-0.3.1.sha256sum] = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +SRC_URI[rand_core-0.6.4.sha256sum] = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +SRC_URI[redox_syscall-0.1.57.sha256sum] = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +SRC_URI[redox_syscall-0.2.16.sha256sum] = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +SRC_URI[redox_syscall-0.3.5.sha256sum] = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +SRC_URI[redox_syscall-0.4.1.sha256sum] = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +SRC_URI[redox_users-0.3.5.sha256sum] = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +SRC_URI[redox_users-0.4.3.sha256sum] = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +SRC_URI[regex-1.10.2.sha256sum] = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +SRC_URI[regex-automata-0.1.10.sha256sum] = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +SRC_URI[regex-automata-0.4.3.sha256sum] = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +SRC_URI[regex-syntax-0.6.29.sha256sum] = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +SRC_URI[regex-syntax-0.7.5.sha256sum] = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +SRC_URI[regex-syntax-0.8.2.sha256sum] = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +SRC_URI[ring-0.17.5.sha256sum] = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +SRC_URI[rust-argon2-0.8.3.sha256sum] = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +SRC_URI[rustc-demangle-0.1.23.sha256sum] = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +SRC_URI[rustix-0.38.21.sha256sum] = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +SRC_URI[rustls-0.21.8.sha256sum] = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +SRC_URI[rustls-pemfile-1.0.3.sha256sum] = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +SRC_URI[rustls-webpki-0.101.7.sha256sum] = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +SRC_URI[rustversion-1.0.14.sha256sum] = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +SRC_URI[ryu-1.0.15.sha256sum] = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +SRC_URI[same-file-1.0.6.sha256sum] = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +SRC_URI[scopeguard-1.2.0.sha256sum] = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +SRC_URI[sct-0.7.1.sha256sum] = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +SRC_URI[sealed-0.5.0.sha256sum] = "f4a8caec23b7800fb97971a1c6ae365b6239aaeddfb934d6265f8505e795699d" +SRC_URI[serde-1.0.190.sha256sum] = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +SRC_URI[serde_derive-1.0.190.sha256sum] = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +SRC_URI[serde_json-1.0.107.sha256sum] = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +SRC_URI[serde_path_to_error-0.1.14.sha256sum] = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +SRC_URI[serde_urlencoded-0.7.1.sha256sum] = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +SRC_URI[sha1-0.10.6.sha256sum] = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +SRC_URI[sha1_smol-1.0.0.sha256sum] = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +SRC_URI[sharded-slab-0.1.7.sha256sum] = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +SRC_URI[signal-hook-0.3.17.sha256sum] = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +SRC_URI[signal-hook-registry-1.4.1.sha256sum] = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +SRC_URI[simple_asn1-0.6.2.sha256sum] = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +SRC_URI[siphasher-0.3.11.sha256sum] = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +SRC_URI[slab-0.4.9.sha256sum] = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +SRC_URI[smallstr-0.2.0.sha256sum] = "1e922794d168678729ffc7e07182721a14219c65814e66e91b839a272fe5ae4f" +SRC_URI[smallvec-1.11.1.sha256sum] = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +SRC_URI[smart-default-0.7.1.sha256sum] = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" +SRC_URI[smawk-0.3.2.sha256sum] = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +SRC_URI[socket2-0.4.10.sha256sum] = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +SRC_URI[socket2-0.5.5.sha256sum] = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +SRC_URI[spin-0.9.8.sha256sum] = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +SRC_URI[sqlparser-0.16.0.sha256sum] = "7e9a527b68048eb95495a1508f6c8395c8defcff5ecdbe8ad4106d08a2ef2a3c" +SRC_URI[strsim-0.10.0.sha256sum] = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +SRC_URI[syn-1.0.109.sha256sum] = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +SRC_URI[syn-2.0.38.sha256sum] = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +SRC_URI[sync_wrapper-0.1.2.sha256sum] = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +SRC_URI[synthez-0.3.1.sha256sum] = "a3d2c2202510a1e186e63e596d9318c91a8cbe85cd1a56a7be0c333e5f59ec8d" +SRC_URI[synthez-codegen-0.3.1.sha256sum] = "f724aa6d44b7162f3158a57bccd871a77b39a4aef737e01bcdff41f4772c7746" +SRC_URI[synthez-core-0.3.1.sha256sum] = "78bfa6ec52465e2425fd43ce5bbbe0f0b623964f7c63feb6b10980e816c654ea" +SRC_URI[tempfile-3.8.1.sha256sum] = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +SRC_URI[terminal_size-0.3.0.sha256sum] = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +SRC_URI[terminfo-0.8.0.sha256sum] = "666cd3a6681775d22b200409aad3b089c5b99fb11ecdd8a204d9d62f8148498f" +SRC_URI[textwrap-0.16.0.sha256sum] = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +SRC_URI[thiserror-1.0.50.sha256sum] = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +SRC_URI[thiserror-impl-1.0.50.sha256sum] = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +SRC_URI[thread_local-1.1.7.sha256sum] = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +SRC_URI[time-0.3.30.sha256sum] = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +SRC_URI[time-core-0.1.2.sha256sum] = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +SRC_URI[time-macros-0.2.15.sha256sum] = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +SRC_URI[tinyvec-1.6.0.sha256sum] = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +SRC_URI[tinyvec_macros-0.1.1.sha256sum] = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +SRC_URI[tokio-1.33.0.sha256sum] = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +SRC_URI[tokio-io-timeout-1.2.0.sha256sum] = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +SRC_URI[tokio-macros-2.1.0.sha256sum] = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +SRC_URI[tokio-rustls-0.24.1.sha256sum] = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +SRC_URI[tokio-stream-0.1.14.sha256sum] = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +SRC_URI[tokio-tungstenite-0.20.1.sha256sum] = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +SRC_URI[tokio-util-0.7.10.sha256sum] = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +SRC_URI[tonic-0.9.2.sha256sum] = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +SRC_URI[tonic-build-0.8.4.sha256sum] = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" +SRC_URI[tower-0.4.13.sha256sum] = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +SRC_URI[tower-layer-0.3.2.sha256sum] = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +SRC_URI[tower-service-0.3.2.sha256sum] = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +SRC_URI[tracing-0.1.40.sha256sum] = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +SRC_URI[tracing-attributes-0.1.27.sha256sum] = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +SRC_URI[tracing-core-0.1.32.sha256sum] = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +SRC_URI[tracing-subscriber-0.3.17.sha256sum] = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +SRC_URI[try-lock-0.2.4.sha256sum] = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +SRC_URI[tungstenite-0.20.1.sha256sum] = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +SRC_URI[typed-builder-0.15.2.sha256sum] = "7fe83c85a85875e8c4cb9ce4a890f05b23d38cd0d47647db7895d3d2a79566d2" +SRC_URI[typed-builder-macro-0.15.2.sha256sum] = "29a3151c41d0b13e3d011f98adc24434560ef06673a155a6c7f66b9879eecce2" +SRC_URI[typenum-1.17.0.sha256sum] = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +SRC_URI[unicode-bidi-0.3.13.sha256sum] = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +SRC_URI[unicode-bom-2.0.2.sha256sum] = "98e90c70c9f0d4d1ee6d0a7d04aa06cb9bbd53d8cfbdd62a0269a7c2eb640552" +SRC_URI[unicode-ident-1.0.12.sha256sum] = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +SRC_URI[unicode-linebreak-0.1.5.sha256sum] = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" +SRC_URI[unicode-normalization-0.1.22.sha256sum] = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +SRC_URI[unicode-width-0.1.11.sha256sum] = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +SRC_URI[untrusted-0.9.0.sha256sum] = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +SRC_URI[url-2.4.1.sha256sum] = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +SRC_URI[utf-8-0.7.6.sha256sum] = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +SRC_URI[utf8parse-0.2.1.sha256sum] = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +SRC_URI[uuid-1.5.0.sha256sum] = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +SRC_URI[vergen-8.2.5.sha256sum] = "85e7dc29b3c54a2ea67ef4f953d5ec0c4085035c0ae2d325be1c0d2144bd9f16" +SRC_URI[version_check-0.9.4.sha256sum] = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +SRC_URI[walkdir-2.4.0.sha256sum] = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +SRC_URI[want-0.3.1.sha256sum] = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +SRC_URI[wasi-0.9.0+wasi-snapshot-preview1.sha256sum] = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +SRC_URI[wasi-0.11.0+wasi-snapshot-preview1.sha256sum] = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +SRC_URI[wasm-bindgen-0.2.87.sha256sum] = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +SRC_URI[wasm-bindgen-backend-0.2.87.sha256sum] = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +SRC_URI[wasm-bindgen-macro-0.2.87.sha256sum] = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +SRC_URI[wasm-bindgen-macro-support-0.2.87.sha256sum] = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +SRC_URI[wasm-bindgen-shared-0.2.87.sha256sum] = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +SRC_URI[which-4.4.2.sha256sum] = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +SRC_URI[winapi-0.3.9.sha256sum] = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +SRC_URI[winapi-i686-pc-windows-gnu-0.4.0.sha256sum] = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +SRC_URI[winapi-util-0.1.6.sha256sum] = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +SRC_URI[winapi-x86_64-pc-windows-gnu-0.4.0.sha256sum] = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +SRC_URI[windows-0.48.0.sha256sum] = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +SRC_URI[windows-core-0.51.1.sha256sum] = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +SRC_URI[windows-sys-0.45.0.sha256sum] = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +SRC_URI[windows-sys-0.48.0.sha256sum] = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +SRC_URI[windows-targets-0.42.2.sha256sum] = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +SRC_URI[windows-targets-0.48.5.sha256sum] = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +SRC_URI[windows_aarch64_gnullvm-0.42.2.sha256sum] = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +SRC_URI[windows_aarch64_gnullvm-0.48.5.sha256sum] = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +SRC_URI[windows_aarch64_msvc-0.42.2.sha256sum] = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +SRC_URI[windows_aarch64_msvc-0.48.5.sha256sum] = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +SRC_URI[windows_i686_gnu-0.42.2.sha256sum] = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +SRC_URI[windows_i686_gnu-0.48.5.sha256sum] = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +SRC_URI[windows_i686_msvc-0.42.2.sha256sum] = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +SRC_URI[windows_i686_msvc-0.48.5.sha256sum] = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +SRC_URI[windows_x86_64_gnu-0.42.2.sha256sum] = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +SRC_URI[windows_x86_64_gnu-0.48.5.sha256sum] = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +SRC_URI[windows_x86_64_gnullvm-0.42.2.sha256sum] = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +SRC_URI[windows_x86_64_gnullvm-0.48.5.sha256sum] = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +SRC_URI[windows_x86_64_msvc-0.42.2.sha256sum] = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +SRC_URI[windows_x86_64_msvc-0.48.5.sha256sum] = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +SRC_URI[winnow-0.5.17.sha256sum] = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" diff --git a/recipes-connectivity/kuksa-val/kuksa-databroker/0001-Remove-protobuf-src-usage.patch b/recipes-connectivity/kuksa-val/kuksa-databroker/0001-Remove-protobuf-src-usage.patch new file mode 100644 index 00000000..05e92c7d --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-databroker/0001-Remove-protobuf-src-usage.patch @@ -0,0 +1,88 @@ +From 37c2a7380c2b1993e62deee4d80e85ad0340ef78 Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Thu, 23 Nov 2023 10:43:38 -0500 +Subject: [PATCH 2/2] Remove protobuf-src usage + +The vendoring of a protoc and libprotobuf build that was added in +commit 890703c9 by using protobuf-src is not really workable with +OpenEmbedded / Yocto Project, and somewhat undesirable for any +distribution package builds when it comes to transparency and +reproducibility. Remove it so that building in OE/YP will work. + +Upstream-Status: Pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + Cargo.lock | 19 ------------------- + kuksa_databroker/databroker-proto/Cargo.toml | 1 - + kuksa_databroker/databroker-proto/build.rs | 1 - + 3 files changed, 21 deletions(-) + +diff --git a/Cargo.lock b/Cargo.lock +index bb9ec7f..383e7e6 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -162,15 +162,6 @@ version = "1.1.0" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +-[[package]] +-name = "autotools" +-version = "0.2.6" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "aef8da1805e028a172334c3b680f93e71126f2327622faef2ec3d893c0a4ad77" +-dependencies = [ +- "cc", +-] +- + [[package]] + name = "axum" + version = "0.6.20" +@@ -604,7 +595,6 @@ version = "0.4.1" + dependencies = [ + "prost", + "prost-types", +- "protobuf-src", + "tonic", + "tonic-build", + ] +@@ -2244,15 +2234,6 @@ dependencies = [ + "prost", + ] + +-[[package]] +-name = "protobuf-src" +-version = "1.1.0+21.5" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "c7ac8852baeb3cc6fb83b93646fb93c0ffe5d14bf138c945ceb4b9948ee0e3c1" +-dependencies = [ +- "autotools", +-] +- + [[package]] + name = "quote" + version = "1.0.33" +diff --git a/kuksa_databroker/databroker-proto/Cargo.toml b/kuksa_databroker/databroker-proto/Cargo.toml +index 5957b7e..9b92162 100644 +--- a/kuksa_databroker/databroker-proto/Cargo.toml ++++ b/kuksa_databroker/databroker-proto/Cargo.toml +@@ -25,4 +25,3 @@ prost-types = { workspace = true } + + [build-dependencies] + tonic-build = { workspace = true, features = ["transport", "prost"] } +-protobuf-src = "1.1.0" +diff --git a/kuksa_databroker/databroker-proto/build.rs b/kuksa_databroker/databroker-proto/build.rs +index d02a006..d3a70ac 100644 +--- a/kuksa_databroker/databroker-proto/build.rs ++++ b/kuksa_databroker/databroker-proto/build.rs +@@ -12,7 +12,6 @@ + ********************************************************************************/ + + fn main() -> Result<(), Box<dyn std::error::Error>> { +- std::env::set_var("PROTOC", protobuf_src::protoc()); + tonic_build::configure() + .compile_well_known_types(false) + .protoc_arg("--experimental_allow_proto3_optional") +-- +2.42.0 + diff --git a/recipes-connectivity/kuksa-val/kuksa-databroker/kuksa-databroker.service b/recipes-connectivity/kuksa-val/kuksa-databroker/kuksa-databroker.service new file mode 100644 index 00000000..04e81992 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-databroker/kuksa-databroker.service @@ -0,0 +1,12 @@ +[Unit] +Description=Eclipse KUKSA.val databroker +After=network.target + +[Service] +User=kuksa +EnvironmentFile=-/etc/default/kuksa-databroker +ExecStart=/usr/bin/databroker $EXTRA_ARGS +Restart=on-abort + +[Install] +WantedBy=multi-user.target diff --git a/recipes-connectivity/kuksa-val/kuksa-databroker_git.bb b/recipes-connectivity/kuksa-val/kuksa-databroker_git.bb new file mode 100644 index 00000000..2009c220 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-databroker_git.bb @@ -0,0 +1,55 @@ +SUMMARY = "KUKSA.val databroker, the KUKSA Vehicle Abstraction Layer" +#DESCRIPTION = "KUKSA.val provides a COVESA VSS data model describing data in a vehicle." +HOMEPAGE = "https://github.com/eclipse/kuksa.val" +BUGTRACKER = "https://github.com/eclipse/kuksa.val/issues" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=2b42edef8fa55315f34f2370b4715ca9 \ +" + +DEPENDS = "protobuf-native grpc-native" + +require kuksa-val.inc + +require ${BPN}-crates.inc + +SRC_URI += "file://0001-Remove-protobuf-src-usage.patch \ + file://kuksa-databroker.service \ +" + +S = "${WORKDIR}/git" + +inherit cargo cargo-update-recipe-crates systemd useradd + +# Enable optional VISS support for potential use by e.g. the web apps +CARGO_BUILD_FLAGS += "--features viss" + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +USERADD_PACKAGES = "${PN}" +USERADDEXTENSION = "useradd-staticids" +GROUPADD_PARAM:${PN} = "-g 900 kuksa ;" +USERADD_PARAM:${PN} = "--system -g 900 -u 900 -o -d / --shell /bin/nologin kuksa ;" + +do_install:append() { + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir} + fi + + # Install gRPC API protobuf files + install -d ${D}${includedir} + cp -dr ${S}/proto/kuksa ${D}${includedir} + cp -dr ${S}/kuksa_databroker/proto/sdv ${D}${includedir} +} + +PACKAGE_BEFORE_PN += "${PN}-cli" + +FILES:${PN} += "${systemd_system_unitdir} ${datadir}" + +FILES:${PN}-cli = "${bindir}/databroker-cli" + +# The upstream Cargo.toml builds optimized and stripped binaries, for +# now disable the QA check as opposed to tweaking the configuration. +INSANE_SKIP:${PN} = "already-stripped" +INSANE_SKIP:${PN}-cli = "already-stripped" diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0001-dbc2val-add-installation-mechanism.patch b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0001-dbc2val-add-installation-mechanism.patch new file mode 100644 index 00000000..58ad3259 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0001-dbc2val-add-installation-mechanism.patch @@ -0,0 +1,76 @@ +From d23ce9baabaabff17a4bf6050462edd11feb7cef Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Wed, 19 Apr 2023 15:55:01 -0400 +Subject: [PATCH] dbc2val: add installation mechanism + +Add setup.py and setup.cfg to allow installing the dbcfeederlib +module and dbcfeeder.py in a way suitable for packaging. + +Upstream-Status: pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> + + +--- + dbc2val/setup.cfg | 30 ++++++++++++++++++++++++++++++ + dbc2val/setup.py | 14 ++++++++++++++ + 2 files changed, 44 insertions(+) + create mode 100644 dbc2val/setup.cfg + create mode 100644 dbc2val/setup.py + +diff --git a/dbc2val/setup.cfg b/dbc2val/setup.cfg +new file mode 100644 +index 0000000..03dc6d6 +--- /dev/null ++++ b/dbc2val/setup.cfg +@@ -0,0 +1,30 @@ ++[metadata] ++name = dbcfeeder ++author = Sebastian Schildt, Naresh Nayak, Wenwen Chen ++author_email = sebastian.schildt@de.bosch.com, naresh.nayak@de.bosch.com, wenwen.chen@de.bosch.com ++description = kuksa.val DBC feeder ++long_description = file:README.md ++long_description_content_type = text/markdown ++url=https://github.com/eclipse/kuksa.val.feeders ++project_urls= ++ Source=https://github.com/eclipse/kuksa.val.feeders/tree/master/dbc2val ++ Bug Tracker=https://github.com/eclipse/kuksa.val.feeders/issues ++classifiers = ++ Intended Audience :: Developers ++ Development Status :: 3 - Alpha ++ Environment :: Console ++ Programming Language :: Python :: 3 ++ License :: OSI Approved :: Apache Software License ++ Operating System :: OS Independent ++ Topic :: Software Development ++ ++license_file = ../LICENSE.txt ++ ++[options] ++python_requires = >=3.6 ++install_requires= ++ pyserial ++ pyyaml ++ kuksa-client ++packages=dbcfeederlib ++scripts=dbcfeeder.py +diff --git a/dbc2val/setup.py b/dbc2val/setup.py +new file mode 100644 +index 0000000..65f9157 +--- /dev/null ++++ b/dbc2val/setup.py +@@ -0,0 +1,14 @@ ++from setuptools import setup ++ ++setup( ++ version_config={ ++ "template": "{tag}", ++ "dev_template": "{tag}-{ccount}", ++ "dirty_template": "{tag}+{ccount}-dirty", ++ "starting_version": "0.1.0", ++ "version_callback": None, ++ "version_file": None, ++ "count_commits_from_version_file": False ++ }, ++ setup_requires=['setuptools-git-versioning'], ++) diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0002-dbc2val-usability-improvements.patch b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0002-dbc2val-usability-improvements.patch new file mode 100644 index 00000000..31051b18 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0002-dbc2val-usability-improvements.patch @@ -0,0 +1,76 @@ +From b217a746ef7b92291320e4c1a66b52df0318495f Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Sat, 5 Aug 2023 13:58:16 -0400 +Subject: [PATCH 2/3] dbc2val: usability improvements + +Changes: +- Tweaked default configuration file search path to better match + Linux FHS and kuksa-val-server. First look for a config.ini in + /etc/kuksa-dbc-feeder, then /etc/dbc_feeder.ini. +- Add catching of exceptions around CAN device opening so that the + script can exit cleanly with an error message if the device is + not available. +- Fixed shutdown behavior with some tweaks to actually stop the + reader and KUKSA.val client library threads. This makes the + script actually exit on SIGTERM as opposed to hanging. + +Upstream-Status: pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> + +--- + dbc2val/dbcfeeder.py | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/dbc2val/dbcfeeder.py b/dbc2val/dbcfeeder.py +index 966dba7..e7fd319 100755 +--- a/dbc2val/dbcfeeder.py ++++ b/dbc2val/dbcfeeder.py +@@ -188,7 +188,11 @@ class Feeder: + + # use socketCAN + log.info("Using socket CAN device '%s'", canport) ++ try: + self._reader.start_listening(bustype="socketcan", channel=canport) ++ except: ++ log.error("Could not open {}, exiting".format(canport)) ++ sys.exit(-1) + + receiver = threading.Thread(target=self._run_receiver) + receiver.start() +@@ -212,6 +216,11 @@ class Feeder: + threads.append(transmitter) + else: + log.info("No val2dbc mappings found or val2dbc disabled!!") ++ ++ # Spin so signal handlers will work ++ while not self._shutdown: ++ time.sleep(0.1) ++ + # Wait for all of them to finish + for thread in threads: + thread.join() +@@ -363,8 +372,10 @@ def parse_config(filename): + configfile = filename + else: + config_candidates = [ +- "/config/dbc_feeder.ini", ++ "/etc/kuksa-dbc-feeder/config.ini", ++ "/etc/kuksa-dbc-feeder/dbc_feeder.ini", + "/etc/dbc_feeder.ini", ++ "/config/dbc_feeder.ini", + "config/dbc_feeder.ini", + ] + for candidate in config_candidates: +@@ -577,7 +588,7 @@ def main(argv): + elif "can" in config and "dbc_default_file" in config["can"]: + dbc_default = config["can"]["dbc_default_file"] + else: +- dbc_default = "dbc_default_values.json" ++ dbc_default = "" + + if args.dbc2val: + use_dbc2val = True +-- +2.41.0 + diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0003-dbc2val-fix-token-file-configuration-option.patch b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0003-dbc2val-fix-token-file-configuration-option.patch new file mode 100644 index 00000000..aae8b3dc --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0003-dbc2val-fix-token-file-configuration-option.patch @@ -0,0 +1,30 @@ +From dc20da27a73141b04cc6b0ce5d74e547d6fc7256 Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Mon, 8 May 2023 14:58:06 -0400 +Subject: [PATCH] dbc2val: fix token file configuration option + +The client library changed the token option name to +'token_or_tokenfile', update things to match so that token +location can be configured again for dbcfeeder.py. + +Upstream-Status: pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> + +--- + dbc2val/dbcfeederlib/serverclientwrapper.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dbc2val/dbcfeederlib/serverclientwrapper.py b/dbc2val/dbcfeederlib/serverclientwrapper.py +index 1219a76..63bc12e 100644 +--- a/dbc2val/dbcfeederlib/serverclientwrapper.py ++++ b/dbc2val/dbcfeederlib/serverclientwrapper.py +@@ -59,7 +59,7 @@ class ServerClientWrapper(clientwrapper.ClientWrapper): + self._client_config["insecure"] = not self._tls + # Do not set token if it is empty to allow default client lib info to be used + if self._token_path != "": +- self._client_config["token"] = self._token_path ++ self._client_config["token_or_tokenfile"] = self._token_path + + if self._root_ca_path: + self._client_config['cacertificate'] = self._root_ca_path diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/agl-vcar.dbc b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/agl-vcar.dbc new file mode 100644 index 00000000..0d012139 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/agl-vcar.dbc @@ -0,0 +1,31 @@ +VERSION "AGL Virtual Car 1.0" + +BS_: + +BO_ 1001 Vehicle_Status_1: 8 Vector_XXX + SG_ PT_VehicleAvgSpeed : 7|15@0+ (0.015625,0) [0|0] "" Vector_XXX + +BO_ 985 Vehicle_Status_2: 8 Vector_XXX + SG_ PT_FuelLevelPct : 8|8@1+ (0.392157,0) [0|0] "" Vector_XXX + SG_ PT_EngineSpeed : 23|16@0+ (0.25,0) [0|0] "" Vector_XXX + SG_ PT_FuelLevelLow : 55|1@1+ (1,0) [0|1] "" Vector_XXX + +BO_ 33 Steering_Wheel: 8 Vector_XXX + SG_ SW_Previous : 39|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_VolumeUp : 38|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_Mode : 37|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_VolumeDown : 36|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_Next : 35|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_Info : 33|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_VolumeMute : 32|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_Voice : 42|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_PhoneHangup : 41|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_PhoneCall : 40|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_CruiseEnable : 55|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_CruiseResume : 54|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_CruiseSet : 52|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_CruiseCancel : 51|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_CruiseLimit : 49|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_CruiseDistance : 48|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_Horn : 63|1@1+ (1,0) [0|1] "" Vector_XXX + SG_ SW_LaneDepartureWarning : 56|1@1+ (1,0) [0|1] "" Vector_XXX diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/config.ini b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/config.ini new file mode 100644 index 00000000..378a3437 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/config.ini @@ -0,0 +1,30 @@ +[general] +# server type: +# switch between kuksa_databroker and kuksa_val_server +server_type = kuksa_databroker +# VSS mapping file +mapping = /usr/share/vss/vss.json + +# IP address for server (KUKSA.val Server or Databroker) +ip = localhost + +# Port for server (KUKSA.val Server or Databroker) +port = 55555 + +# Shall TLS be used (default False for Databroker, True for KUKSA.val Server) +tls = True + +# TLS-related settings +# Path to root CA, needed if using TLS +root_ca_path=/etc/kuksa-val/CA.pem + +# Token file for authorization. +token = /etc/kuksa-dbc-feeder/dbc_feeder.token + +[can] +# CAN port +port = can0 +# Enable SAE-J1939 Mode. False: ignore +j1939 = False +# DBC file used to parse CAN messages +dbcfile = /etc/kuksa-dbc-feeder/agl-vcar.dbc diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/dbc_feeder.json.token b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/dbc_feeder.json.token new file mode 100644 index 00000000..b8df6666 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/dbc_feeder.json.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJrdWtzYS52YWwiLCJpc3MiOiJFY2xpcHNlIEtVS1NBIERldiIsImFkbWluIjp0cnVlLCJtb2RpZnlUcmVlIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTc2NzIyNTU5OSwia3Vrc2EtdnNzIjp7IioiOiJydyJ9fQ.p2cnFGH16QoQ14l6ljPVKggFXZKmD-vrw8G6Vs6DvAokjsUG8FHh-F53cMsE-GDjyZH_1_CrlDCnbGlqjsFbgAylqA7IAJWp9_N6dL5p8DHZTwlZ4IV8L1CtCALs7XVqvcQKHCCzB63Y8PgVDCAqpQSRb79JPVD4pZwkBKpOknfEY5y9wfbswZiRKdgz7o61_oFnd-yywpse-23HD6v0htThVF1SuGL1PuvGJ8p334nt9bpkZO3gaTh1xVD_uJMwHzbuBCF33_f-I5QMZO6bVooXqGfe1zvl3nDrPEjq1aPulvtP8RgREYEqE6b2hB8jouTiC_WpE3qrdMw9sfWGFbm04qC-2Zjoa1yYSXoxmYd0SnliSYHAad9aXoEmFENezQV-of7sc-NX1-2nAXRAEhaqh0IRuJwB4_sG7SvQmnanwkz-sBYxKqkoFpOsZ6hblgPDOPYY2NAsZlYkjvAL2mpiInrsmY_GzGsfwPeAx31iozImX75rao8rm-XucAmCIkRlpBz6MYKCjQgyRz3UtZCJ2DYF4lKqTjphEAgclbYZ7KiCuTn9HualwtEmVzHHFneHMKl7KnRQk-9wjgiyQ5nlsVpCCblg6JKr9of4utuPO3cBvbjhB4_ueQ40cpWVOICcOLS7_w0i3pCq1ZKDEMrYDJfz87r2sU9kw1zeFQk
\ No newline at end of file diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/dbc_feeder.token b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/dbc_feeder.token new file mode 100644 index 00000000..8ce854f3 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/dbc_feeder.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoicHJvdmlkZSJ9.OJWzTvDjcmeWyg3vmBR5TEtqYaHq8HrpFLlTKZAfDBAQBUHpyUEboJ97jfWuWgBnTpnfboyfAbwvLqo6bEVZ6tXzF8n9LtW6HmPbIWoDqXuobM2grUCVaGKuOcnCpMCQYChziqHbYwRJYP9nkYgbQU1kE4dN7880Io4xzq0GEbWksB2CVpOoExQUmCZpCohPs-XEkdmXhcUKnWnOeiSsRGKusx987vpY_WOXh6WE7DfJgzAgpPDo33qI7zQuTzUILORQsiHmsrQO0-zcvokNjaQUzlt5ETZ7MQLCtiUQaN0NMbDMCWkmSfNvZ5hKCNbfr2FaiMzrGBOQdvQiFo-DqZKGNweaGpufYXuaKfn3SXKoDr8u1xDE5oKgWMjxDR9pQYGzIF5bDXITSywCm4kN5DIn7e2_Ga28h3rBl0t0ZT0cwlszftQRueDTFcMns1u9PEDOqf7fRrhjq3zqpxuMAoRANVd2z237eBsS0AvdSIxL52N4xO8P_h93NN8Vaum28fTPxzm8p9WlQh4mgUelggtT415hLcxizx15ARIRG0RiW91Pglzt4WRtXHnsg93Ixd3yXXzZ2i4Y0hqhj_L12SsXunK2VxKup2sFCQz6wM-t_7ADmNYcs80idzsadY8rYKDV8N1WqOOd4ANG_nzWa86Tyu6wAwhDVag5nbFmLZQ
\ No newline at end of file diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/kuksa-dbc-feeder.service b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/kuksa-dbc-feeder.service new file mode 100644 index 00000000..a30018c6 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/kuksa-dbc-feeder.service @@ -0,0 +1,11 @@ +[Unit] +Description=Eclipse KUKSA.val DBC feeder +Requires=kuksa-databroker.service can-dev-helper.service +After=kuksa-databroker.service can-dev-helper.service + +[Service] +ExecStart=/usr/bin/dbcfeeder.py +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/mapping.yml b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/mapping.yml new file mode 100644 index 00000000..b1c1fece --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/mapping.yml @@ -0,0 +1,152 @@ +# Mapping Speed +PT_VehicleAvgSpeed: + minupdatedelay: 100 + targets: + Vehicle.Speed: {} + +PT_EngineSpeed: + minupdatedelay: 100 + targets: + Vehicle.Powertrain.CombustionEngine.Speed: + transform: + math: "floor(x+0.5)" + +# +# NOTE: +# +# The following mappings depend on the AGL-specific VSS overlay +# that adds the extra Vehicle.Cabin.SteeringWheel.Switches sensors. +# Since the CAN events are coming from LIN polling, applications +# need to filter/debounce themselves. The minupdatedelay of 0 is +# intentional to avoid missing events. +# + +SW_Next: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.Next: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_Previous: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.Previous: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_Mode: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.Mode: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_Info: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.Info: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_CruiseEnable: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.CruiseEnable: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_CruiseSet: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.CruiseSet: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_CruiseResume: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.CruiseResume: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_CruiseCancel: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.CruiseCancel: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_VolumeUp: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.VolumeUp: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_VolumeDown: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.VolumeDown: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_VolumeMute: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.VolumeMute: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_Horn: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.Horn: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" + +SW_LaneDepartureWarning: + minupdatedelay: 0 + targets: + Vehicle.Cabin.SteeringWheel.Switches.LaneDepartureWarning: + filter-duplicates: "true" + transform: + fullmapping: + 0: "false" + 1: "true" diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder_git.bb b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder_git.bb new file mode 100644 index 00000000..809152bb --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder_git.bb @@ -0,0 +1,57 @@ +SUMMARY = "DBC feeder for KUKSA.val, the KUKSA Vehicle Abstraction Layer" +HOMEPAGE = "https://github.com/eclipse/kuksa.val" +BUGTRACKER = "https://github.com/eclipse/kuksa.val/issues" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=175792518e4ac015ab6696d16c4f607e" + +DEPENDS = "python3-setuptools-git-versioning-native" + +PV = "0.4.0+git${SRCPV}" + +SRC_URI = "git://github.com/eclipse/kuksa.val.feeders.git;protocol=https;branch=main \ + file://0001-dbc2val-add-installation-mechanism.patch \ + file://0002-dbc2val-usability-improvements.patch \ + file://0003-dbc2val-fix-token-file-configuration-option.patch \ + file://config.ini \ + file://dbc_feeder.token \ + file://agl-vcar.dbc \ + file://kuksa-dbc-feeder.service \ + " +SRCREV = "5bb52eca8d79f7c05a024f69b1faab81dabacdcd" + +S = "${WORKDIR}/git" + +inherit setuptools3 systemd + +SETUPTOOLS_SETUP_PATH = "${S}/dbc2val" + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_install:append() { + install -d ${D}${sysconfdir}/kuksa-dbc-feeder + install -m 0644 ${WORKDIR}/config.ini ${D}${sysconfdir}/kuksa-dbc-feeder/ + # Token should ideally not be readable by other users. + # The potential for running the feeder as non-root will take some + # investigation. + install -m 0600 ${WORKDIR}/dbc_feeder.token ${D}${sysconfdir}/kuksa-dbc-feeder/ + install -m 0644 ${WORKDIR}/agl-vcar.dbc ${D}${sysconfdir}/kuksa-dbc-feeder/ + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/kuksa-dbc-feeder.service ${D}${systemd_system_unitdir} + fi +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += " \ + bash \ + python3-pyserial \ + python3-cantools \ + python3-can \ + python3-can-j1939 \ + python3-pyyaml \ + python3-py-expression-eval \ + kuksa-client \ + can-dev-helper \ +" diff --git a/recipes-connectivity/kuksa-val/kuksa-val-agl-demo-cluster.bb b/recipes-connectivity/kuksa-val/kuksa-val-agl-demo-cluster.bb new file mode 100644 index 00000000..17e9e3c9 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val-agl-demo-cluster.bb @@ -0,0 +1,22 @@ +SUMMARY = "AGL cluster demo configuration for KUKSA.val, the KUKSA Vehicle Abstraction Layer" +HOMEPAGE = "https://github.com/eclipse/kuksa.val" +BUGTRACKER = "https://github.com/eclipse/kuksa.val/issues" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = "file://kuksa-val.env" + +inherit allarch update-alternatives + +do_install() { + install -d ${D}${sysconfdir}/default + install -m 0644 ${WORKDIR}/kuksa-val.env ${D}${sysconfdir}/default/kuksa-val.agl-demo-cluster-support +} + +ALTERNATIVE:${PN} = "kuksa-val-env" +ALTERNATIVE_LINK_NAME[kuksa-val-env] = "${sysconfdir}/default/kuksa-val" +ALTERNATIVE_TARGET[kuksa-val-env] = "${sysconfdir}/default/kuksa-val.agl-demo-cluster-support" +ALTERNATIVE_PRIORITY[kuksa-val-env] = "20" + +RDEPENDS:${PN} += "kuksa-certificates-agl-client" diff --git a/recipes-connectivity/kuksa-val/kuksa-val-agl-demo-cluster/kuksa-val.env b/recipes-connectivity/kuksa-val/kuksa-val-agl-demo-cluster/kuksa-val.env new file mode 100644 index 00000000..f5ea757e --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val-agl-demo-cluster/kuksa-val.env @@ -0,0 +1 @@ +EXTRA_ARGS="--vss /usr/share/vss/vss.json --address 0.0.0.0" diff --git a/recipes-connectivity/kuksa-val/kuksa-val-agl.bb b/recipes-connectivity/kuksa-val/kuksa-val-agl.bb new file mode 100644 index 00000000..8b69e5e5 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val-agl.bb @@ -0,0 +1,23 @@ +SUMMARY = "AGL demo signal overlay for KUKSA.val, the KUKSA Vehicle Abstraction Layer" +HOMEPAGE = "https://github.com/eclipse/kuksa.val" +BUGTRACKER = "https://github.com/eclipse/kuksa.val/issues" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = "file://kuksa-val.env" + +inherit allarch update-alternatives + +do_install() { + install -d ${D}${sysconfdir}/default + install -m 0644 ${WORKDIR}/kuksa-val.env ${D}${sysconfdir}/default/kuksa-val.agl +} + +FILES:${PN} += "${datadir}/kuksa-val/overlays" + +ALTERNATIVE:${PN} = "kuksa-val-env" +ALTERNATIVE_LINK_NAME[kuksa-val-env] = "${sysconfdir}/default/kuksa-val" +ALTERNATIVE_TARGET[kuksa-val-env] = "${sysconfdir}/default/kuksa-val.agl" + +RDEPENDS:${PN} += "kuksa-val vss-agl" diff --git a/recipes-connectivity/kuksa-val/kuksa-val-agl/00-agl_vss_overlay_2.2.json b/recipes-connectivity/kuksa-val/kuksa-val-agl/00-agl_vss_overlay_2.2.json new file mode 100644 index 00000000..423d3238 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val-agl/00-agl_vss_overlay_2.2.json @@ -0,0 +1,153 @@ +{ + "Vehicle": { + "children": { + "Cabin": { + "children": { + "SteeringWheel": { + "children": { + "Switches": { + "children": { + "VolumeUp": { + "datatype": "boolean", + "description": "Steering wheel volume up switch engaged", + "type": "sensor", + "uuid": "b1b71c0d19684170bbf9fc40eb4d0d0e" + }, + "VolumeDown": { + "datatype": "boolean", + "description": "Steering wheel volume down switch engaged", + "type": "sensor", + "uuid": "03ff9703a5604ab190cf518eec08ba07" + }, + "VolumeMute": { + "datatype": "boolean", + "description": "Steering wheel volume mute switch engaged", + "type": "sensor", + "uuid": "c20467086cf846dc9f27da93d611af12" + }, + "Next": { + "datatype": "boolean", + "description": "Steering wheel next switch engaged", + "type": "sensor", + "uuid": "a2a997e5e6a848d0be1bf8b8bc45e215" + }, + "Previous": { + "datatype": "boolean", + "description": "Steering wheel previous switch engaged", + "type": "sensor", + "uuid": "1505a53421044bccb249f08c270e3912" + }, + "Mode": { + "datatype": "boolean", + "description": "Steering wheel mode switch engaged", + "type": "sensor", + "uuid": "6cba659f06ae4809adb5de53786ab0b6" + }, + "Info": { + "datatype": "boolean", + "description": "Steering wheel info switch engaged", + "type": "sensor", + "uuid": "5dd6d297edfb4cb99ab2ed7723877cd0" + }, + "CruiseEnable": { + "datatype": "boolean", + "description": "Steering wheel cruise enable switch engaged", + "type": "sensor", + "uuid": "f4f383fbf3ff4a7b99ea71203cd8a446" + }, + "CruiseSet": { + "datatype": "boolean", + "description": "Steering wheel cruise set switch engaged", + "type": "sensor", + "uuid": "14bd5c2326a043b79898df4e80403a93" + }, + "CruiseResume": { + "datatype": "boolean", + "description": "Steering wheel cruise resume switch engaged", + "type": "sensor", + "uuid": "000cc121e98345f2976615f550b91639" + }, + "CruiseCancel": { + "datatype": "boolean", + "description": "Steering wheel cruise cancel switch engaged", + "type": "sensor", + "uuid": "b953dac89a2b40fdace6c74bb212afb8" + }, + "CruiseLimit": { + "datatype": "boolean", + "description": "Steering wheel cruise limit switch engaged", + "type": "sensor", + "uuid": "1c211ac5dd4d42249d7e1c104ef81df9" + }, + "CruiseDistance": { + "datatype": "boolean", + "description": "Steering wheel cruise distance switch engaged", + "type": "sensor", + "uuid": "744c8913afe641d0903c44932879ab43" + }, + "Voice": { + "datatype": "boolean", + "description": "Steering wheel voice switch engaged", + "type": "sensor", + "uuid": "9d78ab3889d74209acf6974e070d9d57" + }, + "PhoneCall": { + "datatype": "boolean", + "description": "Steering wheel phone call switch engaged", + "type": "sensor", + "uuid": "3b505e5d962546c7a03509a5c14cfd60" + }, + "PhoneSwitch": { + "datatype": "boolean", + "description": "Steering wheel phone call switch engaged", + "type": "sensor", + "uuid": "f19d7c584f2f4f0080a10f773e472359" + }, + "Horn": { + "datatype": "boolean", + "description": "Steering wheel horn switch engaged", + "type": "sensor", + "uuid": "e025a116b74a41a0a283815621a41fb2" + }, + "LaneDepartureWarning": { + "datatype": "boolean", + "description": "Steering wheel lane departure warning switch engaged", + "type": "sensor", + "uuid": "6dd9c149da8449df885e6250e912e986" + } + } + } + } + }, + "Infotainment": { + "children": { + "Navigation": { + "children": { + "State": { + "datatype": "string", + "description": "Navigation state", + "enum": [ + "unknown", + "Active", + "Arrived", + "Stopped" + ], + "type": "sensor", + "uuid": "4c16a4aace5a418580c6370356d2acb9" + }, + "ElapsedDistance": { + "datatype": "float", + "description": "Navigation elapsed distance", + "type": "sensor", + "unit": "km", + "uuid": "0bef606dcf5b4a75bfd7e5f3c68359ec" + } + } + } + } + } + } + } + } + } +} diff --git a/recipes-connectivity/kuksa-val/kuksa-val-agl/kuksa-val.env b/recipes-connectivity/kuksa-val/kuksa-val-agl/kuksa-val.env new file mode 100644 index 00000000..c7cffb38 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val-agl/kuksa-val.env @@ -0,0 +1 @@ +EXTRA_ARGS="--vss /usr/share/vss/vss.json" diff --git a/recipes-connectivity/kuksa-val/kuksa-val.inc b/recipes-connectivity/kuksa-val/kuksa-val.inc new file mode 100644 index 00000000..2d3d9337 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val.inc @@ -0,0 +1,6 @@ +PV = "0.4.2" + +SRC_URI = "gitsm://github.com/eclipse/kuksa.val.git;protocol=https;branch=master" +SRCREV = "afaf54200ab8bf2126c9ad4a3dec746828cfecb1" + +S = "${WORKDIR}/git" diff --git a/recipes-connectivity/kuksa-val/kuksa-val/0001-Make-Boost-requirements-more-liberal.patch b/recipes-connectivity/kuksa-val/kuksa-val/0001-Make-Boost-requirements-more-liberal.patch new file mode 100644 index 00000000..24419166 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val/0001-Make-Boost-requirements-more-liberal.patch @@ -0,0 +1,41 @@ +From 69a64b4426fdeff1c1e098941496deda5ad3ea31 Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Thu, 6 Oct 2022 11:56:38 -0400 +Subject: [PATCH 1/5] Make Boost requirements more liberal + +To allow building with Yocto Project 4.0/kirkstone, remove the EXACT +specifier from the Boost find_package call and restore the lower +Boost version originally specified before upstream commit 7ea6026d +raised it due to issues with the in-tree build. + +Upstream-Status: Pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + kuksa-val-server/boost.cmake | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kuksa-val-server/boost.cmake b/kuksa-val-server/boost.cmake +index 7358976..0da54df 100644 +--- a/kuksa-val-server/boost.cmake ++++ b/kuksa-val-server/boost.cmake +@@ -19,14 +19,14 @@ + # 4. Change version in main README.md file for KUKSA.val Server + + set(Boost_USE_STATIC_LIBS OFF) +-set(BOOST_VER 1.82.0) ++set(BOOST_VER 1.75.0) + set(Boost_NO_BOOST_CMAKE ON) + set(BOOST_COMPONENTS filesystem program_options system log thread) + ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) + + # Workaround function to allow cmake call `find_package` twice. Avoide side effects from local variables, which are produced be `find_package` + function(findBoost Required) +- find_package(Boost ${BOOST_VER} EXACT ${Required} ++ find_package(Boost ${BOOST_VER} ${Required} + COMPONENTS ${BOOST_COMPONENTS} + OPTIONAL_COMPONENTS unit_test_framework + ) +-- +2.41.0 + diff --git a/recipes-connectivity/kuksa-val/kuksa-val/0002-Fix-gRPC-configuration-for-OE-cross-compiling.patch b/recipes-connectivity/kuksa-val/kuksa-val/0002-Fix-gRPC-configuration-for-OE-cross-compiling.patch new file mode 100644 index 00000000..a7eaf100 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val/0002-Fix-gRPC-configuration-for-OE-cross-compiling.patch @@ -0,0 +1,53 @@ +From 09eba6eef270a3f75add5c54b5455399aecceaf6 Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Thu, 6 Oct 2022 11:56:57 -0400 +Subject: [PATCH 2/3] Fix gRPC configuration for OE cross-compiling + +The gRPC CMake package that kuksa.val pulls in is problematic with +respect to cross-compiling with OpenEmbedded's split native and +target sysroots, as the location of the grpc_cpp_plugin does not +match the (somewhat ill-advised) assumptions in the original +upstream gRPC configuration. To work around this, a patch to +gRPC is separately applied to split the plugins into their own +optional package, and the logic in grpc.cmake here tweaked to +explicitly take cross-compilation into account. + +Upstream-Status: Pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + kuksa-val-server/grpc.cmake | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/kuksa-val-server/grpc.cmake b/kuksa-val-server/grpc.cmake +index 4d90f1d..d097a69 100644 +--- a/kuksa-val-server/grpc.cmake ++++ b/kuksa-val-server/grpc.cmake +@@ -14,14 +14,21 @@ set(gRPC_SSL_PROVIDER "package" CACHE STRING "Provider of ssl library") + set(GRPC_VER 1.44.0) + + find_package(Protobuf) +-find_package(gRPC ${GRPC_VER} EXACT CONFIG) ++find_package(gRPC ${GRPC_VER} CONFIG) ++if(NOT CMAKE_CROSSCOMPILING) ++ find_package(gRPCPlugin ${GRPC_VER} CONFIG) ++ if(gRPCPlugin_FOUND) ++ set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>) ++ endif() ++else() ++ find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) ++endif() + +-if(Protobuf_FOUND AND gRPC_FOUND) ++if(Protobuf_FOUND AND gRPC_FOUND AND _GRPC_CPP_PLUGIN_EXECUTABLE) + message(STATUS "Using protobuf ${protobuf_VERSION}") + message(STATUS "Using gRPC ${gRPC_VERSION}") + + set(_GRPC_GRPCPP gRPC::grpc++) +- set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>) + set(_REFLECTION gRPC::grpc++_reflection) + set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>) + +-- +2.37.3 + diff --git a/recipes-connectivity/kuksa-val/kuksa-val/0003-Make-install-locations-configurable.patch b/recipes-connectivity/kuksa-val/kuksa-val/0003-Make-install-locations-configurable.patch new file mode 100644 index 00000000..11db788b --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val/0003-Make-install-locations-configurable.patch @@ -0,0 +1,198 @@ +From f73106b1f204b49930922e8bb4d1fdec6ac64b7d Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Sat, 5 Aug 2023 12:19:45 -0400 +Subject: [PATCH 5/5] Make install locations configurable + +Make binary, certificate, and configuration file install locations +configurable, including generation and installation of an accurate +default config.ini as well as a header file so that the server +binary uses the specified defaults. This allows configuring a +build that installs files into locations more along the lines of +the Linux FHS. An effort has been made to ensure that the previous +default locations are maintained. + +Upstream-Status: Pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + kuksa-val-server/config.ini | 7 ---- + kuksa-val-server/config.ini.in | 7 ++++ + kuksa-val-server/src/CMakeLists.txt | 59 +++++++++++++++++++++-------- + kuksa-val-server/src/config.hpp.in | 27 +++++++++++++ + kuksa-val-server/src/main.cpp | 5 ++- + 5 files changed, 81 insertions(+), 24 deletions(-) + delete mode 100644 kuksa-val-server/config.ini + create mode 100644 kuksa-val-server/config.ini.in + create mode 100644 kuksa-val-server/src/config.hpp.in + +diff --git a/kuksa-val-server/config.ini b/kuksa-val-server/config.ini +deleted file mode 100644 +index 8fcd63c..0000000 +--- a/kuksa-val-server/config.ini ++++ /dev/null +@@ -1,7 +0,0 @@ +-vss = vss_release_4.0.json +-log-level = ALL +-cert-path = . +- +-[mqtt] +- publish = +- topic-prefix = vss +diff --git a/kuksa-val-server/config.ini.in b/kuksa-val-server/config.ini.in +new file mode 100644 +index 0000000..3793bd6 +--- /dev/null ++++ b/kuksa-val-server/config.ini.in +@@ -0,0 +1,7 @@ ++vss = @KUKSA_DEFAULT_DATADIR@/vss_release_4.0.json ++log-level = ALL ++cert-path = @KUKSA_DEFAULT_CERTDIR@ ++ ++[mqtt] ++ publish = ++ topic-prefix = vss +diff --git a/kuksa-val-server/src/CMakeLists.txt b/kuksa-val-server/src/CMakeLists.txt +index 908c66c..b749a7a 100644 +--- a/kuksa-val-server/src/CMakeLists.txt ++++ b/kuksa-val-server/src/CMakeLists.txt +@@ -161,6 +161,35 @@ if(BUILD_EXE) + ###### + # Setup server install and packaging + ++ set(KUKSA_INSTALL_BINDIR "bin/${SERVER_EXE_NAME}" CACHE STRING "Server binary install directory") ++ ++ if(DEFINED KUKSA_INSTALL_DATADIR) ++ set(KUKSA_DEFAULT_DATADIR_INTERNAL "${KUKSA_INSTALL_DATADIR}") ++ else() ++ set(KUKSA_DEFAULT_DATADIR_INTERNAL ".") ++ endif() ++ set(KUKSA_INSTALL_DATADIR "${KUKSA_INSTALL_BINDIR}" CACHE STRING "Data install directory") ++ set(KUKSA_DEFAULT_DATADIR "${KUKSA_DEFAULT_DATADIR_INTERNAL}" CACHE STRING "Default data location") ++ ++ if(DEFINED KUKSA_INSTALL_CONFIGDIR) ++ set(KUKSA_DEFAULT_CONFIG "${KUKSA_INSTALL_CONFIGDIR}/config.ini" CACHE STRING "Default config.ini location") ++ else() ++ set(KUKSA_DEFAULT_CONFIG "config.ini" CACHE STRING "Default config.ini location") ++ endif() ++ set(KUKSA_INSTALL_CONFIGDIR "${KUKSA_INSTALL_BINDIR}" CACHE STRING "config.ini install directory") ++ ++ if(DEFINED KUKSA_INSTALL_CERTDIR) ++ set(KUKSA_DEFAULT_CERTDIR_INTERNAL "${KUKSA_INSTALL_CERTDIR}") ++ else() ++ set(KUKSA_DEFAULT_CERTDIR_INTERNAL ".") ++ endif() ++ set(KUKSA_INSTALL_CERTDIR "${KUKSA_INSTALL_BINDIR}" CACHE STRING "Certificate install directory") ++ set(KUKSA_DEFAULT_CERTDIR "${KUKSA_DEFAULT_CERTDIR_INTERNAL}" CACHE STRING "Default certificate location") ++ ++ # Generate header for main.cpp to pick up default locations ++ configure_file(config.hpp.in config.hpp @ONLY) ++ include_directories(${CMAKE_CURRENT_BINARY_DIR}) ++ + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/jwt/jwt.key.pub ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Server.pem ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Server.key ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) +@@ -173,23 +202,23 @@ if(BUILD_EXE) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_3.0.json ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_3.1.1.json ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_4.0.json ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) +- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../config.ini ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) ++ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../config.ini.in ${CMAKE_CURRENT_BINARY_DIR}/config.ini @COPY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../config_grpc_client.ini ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + +- install( TARGETS ${SERVER_EXE_NAME} DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/jwt/jwt.key.pub DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Server.pem DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Server.key DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Client.pem DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Client.key DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/CA.pem DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_2.0.json DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_2.1.json DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_2.2.json DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_3.0.json DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_3.1.1.json DESTINATION bin/${SERVER_EXE_NAME}) +- install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_4.0.json DESTINATION bin/${SERVER_EXE_NAME}) +- ++ install( TARGETS ${SERVER_EXE_NAME} DESTINATION ${KUKSA_INSTALL_BINDIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/jwt/jwt.key.pub DESTINATION ${KUKSA_INSTALL_CERTDIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Server.pem DESTINATION ${KUKSA_INSTALL_CERTDIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Server.key DESTINATION ${KUKSA_INSTALL_CERTDIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Client.pem DESTINATION ${KUKSA_INSTALL_CERTDIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/Client.key DESTINATION ${KUKSA_INSTALL_CERTDIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../kuksa_certificates/CA.pem DESTINATION ${KUKSA_INSTALL_CERTDIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_2.0.json DESTINATION ${KUKSA_INSTALL_DATADIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_2.1.json DESTINATION ${KUKSA_INSTALL_DATADIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_2.2.json DESTINATION ${KUKSA_INSTALL_DATADIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_3.0.json DESTINATION ${KUKSA_INSTALL_DATADIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_3.1.1.json DESTINATION ${KUKSA_INSTALL_DATADIR}) ++ install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../data/vss-core/vss_release_4.0.json DESTINATION ${KUKSA_INSTALL_DATADIR}) ++ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/config.ini DESTINATION ${KUKSA_INSTALL_CONFIGDIR}) + + # CPack + INCLUDE(InstallRequiredSystemLibraries) +diff --git a/kuksa-val-server/src/config.hpp.in b/kuksa-val-server/src/config.hpp.in +new file mode 100644 +index 0000000..24226d2 +--- /dev/null ++++ b/kuksa-val-server/src/config.hpp.in +@@ -0,0 +1,27 @@ ++/********************************************************************** ++ * Copyright (c) 2022 Konsulko Group ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * SPDX-License-Identifier: Apache-2.0 ++ **********************************************************************/ ++ ++#ifndef __CONFIG_H___ ++ ++// Default configuration file location ++#cmakedefine KUKSA_DEFAULT_CONFIG "@KUKSA_DEFAULT_CONFIG@" ++ ++// Default Certificate directory ++#cmakedefine KUKSA_DEFAULT_CERTDIR "@KUKSA_DEFAULT_CERTDIR@" ++ ++#endif +diff --git a/kuksa-val-server/src/main.cpp b/kuksa-val-server/src/main.cpp +index f3e6dd1..8346188 100644 +--- a/kuksa-val-server/src/main.cpp ++++ b/kuksa-val-server/src/main.cpp +@@ -47,6 +47,7 @@ + #include "exception.hpp" + #include "grpcHandler.hpp" + #include "OverlayLoader.hpp" ++#include "config.hpp" + + + #include "../buildinfo.h" +@@ -107,7 +108,7 @@ int main(int argc, const char *argv[]) { + program_options::options_description desc{"OPTIONS"}; + desc.add_options() + ("help,h", "Help screen") +- ("config-file,c", program_options::value<boost::filesystem::path>()->default_value(boost::filesystem::path{"config.ini"}), ++ ("config-file,c", program_options::value<boost::filesystem::path>()->default_value(boost::filesystem::path{KUKSA_DEFAULT_CONFIG}), + "Configuration file with `kuksa-val-server` input parameters." + "Configuration file can replace command-line parameters and through different files multiple configurations can be handled more easily (e.g. test and production setup)." + "Sample of configuration file parameters looks like:\n" +@@ -116,7 +117,7 @@ int main(int argc, const char *argv[]) { + "log-level = ALL\n") + ("vss", program_options::value<boost::filesystem::path>()->required(), "[mandatory] Path to VSS data file describing VSS data tree structure which `kuksa-val-server` shall handle. Sample 'vss_release_4.0.json' file can be found under [data](./data/vss-core/vss_release_4.0.json)") + ("overlays", program_options::value<boost::filesystem::path>(), "Path to a directory cotaiing additional VSS models. All json files will be applied on top of the main vss file given by the -vss parameter in alphanumerical order") +- ("cert-path", program_options::value<boost::filesystem::path>()->required()->default_value(boost::filesystem::path(".")), ++ ("cert-path", program_options::value<boost::filesystem::path>()->required()->default_value(boost::filesystem::path(KUKSA_DEFAULT_CERTDIR)), + "[mandatory] Directory path where 'Server.pem', 'Server.key' and 'jwt.key.pub' are located. ") + ("insecure", program_options::bool_switch()->default_value(false), "By default, `kuksa-val-server` shall accept only SSL (TLS) secured connections. If provided, `kuksa-val-server` shall also accept plain un-secured connections for Web-Socket and GRPC API connections, and also shall not fail connections due to self-signed certificates.") + ("use-keycloak", "Use KeyCloak for permission management") +-- +2.41.0 + diff --git a/recipes-connectivity/kuksa-val/kuksa-val/0004-Disable-default-fetch-and-build-of-googletest.patch b/recipes-connectivity/kuksa-val/kuksa-val/0004-Disable-default-fetch-and-build-of-googletest.patch new file mode 100644 index 00000000..8dc8b213 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val/0004-Disable-default-fetch-and-build-of-googletest.patch @@ -0,0 +1,83 @@ +From 21a33ac3b07b00b510c80f50bde7cc42dcada039 Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Thu, 6 Oct 2022 13:31:02 -0400 +Subject: [PATCH 3/3] Disable default fetch and build of googletest + +The logic in test/unit-test/CMakeLists.txt was always fetching and +building googletest even if the unit-test was not enabled (which is +the default), rework it a bit to only do so when the unit-test is +desired. + +Upstream-Status: Pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + .../test/unit-test/CMakeLists.txt | 42 +++++++++---------- + 1 file changed, 21 insertions(+), 21 deletions(-) + +diff --git a/kuksa-val-server/test/unit-test/CMakeLists.txt b/kuksa-val-server/test/unit-test/CMakeLists.txt +index 55eedc9..6cec94f 100644 +--- a/kuksa-val-server/test/unit-test/CMakeLists.txt ++++ b/kuksa-val-server/test/unit-test/CMakeLists.txt +@@ -16,18 +16,6 @@ enable_testing() + include(CTest) + include(FetchContent) + +-FetchContent_Declare( +- googletest +- GIT_REPOSITORY https://github.com/google/googletest.git +- GIT_TAG release-1.11.0 +-) +- +-FetchContent_GetProperties(googletest) +-if(NOT googletest_POPULATED) +- FetchContent_Populate(googletest) +- add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) +-endif() +- + ###### + # CMake configuration responsible for building kuksa-val optional unit tests based on core library + +@@ -37,18 +25,30 @@ set(UNITTEST_EXE_NAME "kuksaval-unit-test" ) + + set(BUILD_UNIT_TEST OFF CACHE BOOL "Build unit tests") + +-### +-# Setup targets ++if(BUILD_UNIT_TEST) ++ FetchContent_Declare( ++ googletest ++ GIT_REPOSITORY https://github.com/google/googletest.git ++ GIT_TAG release-1.11.0 ++ ) + +-set(proto_gen_dir "${CMAKE_BINARY_DIR}/proto") +-include_directories(${proto_gen_dir}) +-include_directories(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) ++ FetchContent_GetProperties(googletest) ++ if(NOT googletest_POPULATED) ++ FetchContent_Populate(googletest) ++ add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) ++ endif() + +-# Prevent GoogleTest from overriding our compiler/linker options +-# when building with Visual Studio +-set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) ++ ### ++ # Setup targets ++ ++ set(proto_gen_dir "${CMAKE_BINARY_DIR}/proto") ++ include_directories(${proto_gen_dir}) ++ include_directories(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) ++ ++ # Prevent GoogleTest from overriding our compiler/linker options ++ # when building with Visual Studio ++ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +-if(BUILD_UNIT_TEST) + add_executable(${UNITTEST_EXE_NAME} + AccessCheckerTests.cpp + AuthenticatorTests.cpp +-- +2.37.3 + diff --git a/recipes-connectivity/kuksa-val/kuksa-val/0005-kuksa-val-server-Add-missing-check_git-dependency.patch b/recipes-connectivity/kuksa-val/kuksa-val/0005-kuksa-val-server-Add-missing-check_git-dependency.patch new file mode 100644 index 00000000..ea866a6e --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val/0005-kuksa-val-server-Add-missing-check_git-dependency.patch @@ -0,0 +1,32 @@ +From 4c232caca95606fe4be6f84fe437c4bb506c885e Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Wed, 1 Mar 2023 16:25:38 -0500 +Subject: [PATCH] kuksa-val-server: Add missing check_git dependency + +There was no explicit dependency on the check_git target in +kuksa-val-server/src/CMakeLists.txt, so there was a race with +creating buildinfo.h when building parallel, leading to +intermittent build failures on the AGL CI builders. Add the +dependency to improve build robustness. + +Upstream-Status: Pending +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + kuksa-val-server/src/CMakeLists.txt | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kuksa-val-server/src/CMakeLists.txt b/kuksa-val-server/src/CMakeLists.txt +index 9428306..afc570e 100644 +--- a/kuksa-val-server/src/CMakeLists.txt ++++ b/kuksa-val-server/src/CMakeLists.txt +@@ -142,6 +142,7 @@ endif() + if(BUILD_EXE) + add_executable(${SERVER_EXE_NAME} main.cpp + ) ++ add_dependencies(${SERVER_EXE_NAME} check_git) + + if (ENABLE_COVERAGE) + add_coverage(${SERVER_EXE_NAME}) +-- +2.39.2 + diff --git a/recipes-connectivity/kuksa-val/kuksa-val/0006-kuksa-val-server-OverlayLoader-explicitly-include-fs.patch b/recipes-connectivity/kuksa-val/kuksa-val/0006-kuksa-val-server-OverlayLoader-explicitly-include-fs.patch new file mode 100644 index 00000000..0f40a7c1 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val/0006-kuksa-val-server-OverlayLoader-explicitly-include-fs.patch @@ -0,0 +1,35 @@ +From 60561b755cbfbb3aa99b1a0d736cc89540636c00 Mon Sep 17 00:00:00 2001 +From: Denys Dmytriyenko <denys@konsulko.com> +Date: Wed, 7 Jun 2023 21:16:30 +0000 +Subject: [PATCH] kuksa-val-server: OverlayLoader: explicitly include fstream + header + +Otherwise gcc13 now errors out: + +| .../kuksa-val-server/src/OverlayLoader.cpp: In function 'void applyOverlays(std::shared_ptr<ILogger>, std::vector<boost::filesystem::path>, std::shared_ptr<IVssDatabase>)': +| .../kuksa-val-server/src/OverlayLoader.cpp:70:24: error: variable 'std::ifstream is' has initializer but incomplete type +| 70 | std::ifstream is(p.generic_string()); +| | ^ + +Upstream-Status: Pending + +Signed-off-by: Denys Dmytriyenko <denys@konsulko.com> +--- + kuksa-val-server/src/OverlayLoader.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kuksa-val-server/src/OverlayLoader.cpp b/kuksa-val-server/src/OverlayLoader.cpp +index bed9234..abd1945 100644 +--- a/kuksa-val-server/src/OverlayLoader.cpp ++++ b/kuksa-val-server/src/OverlayLoader.cpp +@@ -23,6 +23,7 @@ + /* helper fuctions to load overlays during server startup */ + + #include <stdexcept> ++#include <fstream> + #include <jsoncons/json.hpp> + + #include "OverlayLoader.hpp" +-- +2.25.1 + diff --git a/recipes-connectivity/kuksa-val/kuksa-val/kuksa-val.service b/recipes-connectivity/kuksa-val/kuksa-val/kuksa-val.service new file mode 100644 index 00000000..5467e9a4 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val/kuksa-val.service @@ -0,0 +1,12 @@ +[Unit] +Description=Eclipse KUKSA.val VIS server +After=network.target + +[Service] +User=kuksa +EnvironmentFile=-/etc/default/kuksa-val +ExecStart=/usr/bin/kuksa-val-server $EXTRA_ARGS +Restart=on-abort + +[Install] +WantedBy=multi-user.target diff --git a/recipes-connectivity/kuksa-val/kuksa-val_git.bb b/recipes-connectivity/kuksa-val/kuksa-val_git.bb new file mode 100644 index 00000000..64daba22 --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-val_git.bb @@ -0,0 +1,89 @@ +SUMMARY = "KUKSA.val, the KUKSA Vehicle Abstraction Layer" +DESCRIPTION = "KUKSA.val provides a COVESA VSS data model describing data in a vehicle." +HOMEPAGE = "https://github.com/eclipse/kuksa.val" +BUGTRACKER = "https://github.com/eclipse/kuksa.val/issues" + +LICENSE = "Apache-2.0 & BSL-1.0 & MIT" +LIC_FILES_CHKSUM = "file://../LICENSE;md5=2b42edef8fa55315f34f2370b4715ca9 \ + file://3rd-party-libs/jsoncons/LICENSE;md5=6ee7f7ed2001e4cde4679fdb8926f820 \ + file://3rd-party-libs/turtle/LICENSE_1_0.txt;md5=e4224ccaecb14d942c71d31bef20d78c \ + file://3rd-party-libs/jwt-cpp/LICENSE;md5=8325a5ce4414c65ffdda392e0d96a9ff" + +DEPENDS = "boost openssl mosquitto protobuf-native grpc-native grpc" + +require kuksa-val.inc + +SRC_URI += "file://kuksa-val.service \ + file://0001-Make-Boost-requirements-more-liberal.patch;patchdir=.. \ + file://0002-Fix-gRPC-configuration-for-OE-cross-compiling.patch;patchdir=.. \ + file://0003-Make-install-locations-configurable.patch;patchdir=.. \ + file://0004-Disable-default-fetch-and-build-of-googletest.patch;patchdir=.. \ + file://0005-kuksa-val-server-Add-missing-check_git-dependency.patch;patchdir=.. \ + file://0006-kuksa-val-server-OverlayLoader-explicitly-include-fs.patch;patchdir=.. \ +" + +S = "${WORKDIR}/git/kuksa-val-server" + +inherit cmake pkgconfig systemd useradd + +SYSTEMD_SERVICE:${PN} = "kuksa-val.service" + +USERADD_PACKAGES = "${PN} ${PN}-server-certificates" +USERADDEXTENSION = "useradd-staticids" +GROUPADD_PARAM:${PN} = "-g 900 kuksa ;" +USERADD_PARAM:${PN} = "--system -g 900 -u 900 -o -d / --shell /bin/nologin kuksa ;" +GROUPADD_PARAM:${PN}-server-certificates = "-g 900 kuksa ;" + +# Configure file locations more along the lines of FHS instead of kuksa.val's +# default locations. +EXTRA_OECMAKE = " \ + -DKUKSA_INSTALL_BINDIR=${bindir} \ + -DKUKSA_INSTALL_CERTDIR=${sysconfdir}/kuksa-val \ + -DKUKSA_INSTALL_DATADIR=${datadir}/kuksa-val \ + -DKUKSA_INSTALL_CONFIGDIR=${sysconfdir}/kuksa-val \ +" + +do_install:append() { + # Lower the logging level used in the installed config.ini from the upstream + # default of "ALL", which spams the logs. + sed -i 's/^log-level = .*/log-level = WARNING/' ${D}/${sysconfdir}/kuksa-val/config.ini + + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/kuksa-val.service ${D}${systemd_system_unitdir} + fi +} + +# Put certificates into their own packages so we can avoid duplicates +# of them for e.g. cluster clients, and so downstream users can +# replace them with their own certificates. +# +# NOTE: +# Downstream users can replace these packages with alternates by +# having their packages set their RPROVIDES to include the desired +# kuksa-val-certificates-* and explicitly adding their package(s) +# to an image, they will end up getting priority during rootfs +# construction and installed instead of the default ones here. + +PACKAGE_BEFORE_PN += "${PN}-certificates-ca ${PN}-certificates-server ${PN}-certificates-client" + +FILES:${PN}-certificates-ca = " \ + ${sysconfdir}/kuksa-val/CA.pem \ +" + +FILES:${PN}-certificates-server = " \ + ${sysconfdir}/kuksa-val/Server.key \ + ${sysconfdir}/kuksa-val/Server.pem \ + ${sysconfdir}/kuksa-val/jwt.key.pub \ +" +RDEPENDS:${PN}-certificates-server += "${PN}-certificates-ca" + +FILES:${PN}-certificates-client = " \ + ${sysconfdir}/kuksa-val/Client.key \ + ${sysconfdir}/kuksa-val/Client.pem \ +" +RDEPENDS:${PN}-certificate-clients += "${PN}-certificates-ca" + +FILES:${PN} += "${systemd_system_unitdir} ${datadir}" + +RDEPENDS:${PN} += "${PN}-certificates-server ${PN}-certificates-client" diff --git a/recipes-connectivity/rtl-sdr/rtl-sdr/0001-remove-I-usr-include-in-pkg-config.patch b/recipes-connectivity/rtl-sdr/rtl-sdr/0001-remove-I-usr-include-in-pkg-config.patch new file mode 100644 index 00000000..86b7392d --- /dev/null +++ b/recipes-connectivity/rtl-sdr/rtl-sdr/0001-remove-I-usr-include-in-pkg-config.patch @@ -0,0 +1,40 @@ +From 3aeaf8054fcb2617ca8f6196ca32be3e69337f77 Mon Sep 17 00:00:00 2001 +From: Martin Kelly <mkelly@xevo.com> +Date: Fri, 21 Apr 2017 10:29:19 -0700 +Subject: [PATCH] remove -I/usr/include in pkg-config + +This shouldn't be necessary as it's part of the default compiler include +paths anyway. Morever, it can cause GCC 6 C++ build failures in +downstream packages when combined with QMake (such as +qtmultimedia-rtlfm-radio-plugin). + +Fix these issues by removing it. + +Upstream-Status: Inappropriate [disable-feature] + +This patch should not go upstream because it breaks the ability to build +with --prefix. That's not a problem for Openembedded, but it is for +upstream more generally. See this mail thread for more information: + +http://lists.osmocom.org/pipermail/osmocom-sdr/2017-April/001580.html + +Signed-off-by: Martin Kelly <mkelly@xevo.com> +--- + librtlsdr.pc.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/librtlsdr.pc.in b/librtlsdr.pc.in +index 5e55049..84b6d0c 100644 +--- a/librtlsdr.pc.in ++++ b/librtlsdr.pc.in +@@ -6,6 +6,6 @@ includedir=@includedir@ + Name: RTL-SDR Library + Description: C Utility Library + Version: @VERSION@ +-Cflags: -I${includedir}/ @RTLSDR_PC_CFLAGS@ ++Cflags: @RTLSDR_PC_CFLAGS@ + Libs: -L${libdir} -lrtlsdr -lusb-1.0 + Libs.private: @RTLSDR_PC_LIBS@ +-- +2.1.4 + diff --git a/recipes-connectivity/rtl-sdr/rtl-sdr_0.5.3.bb b/recipes-connectivity/rtl-sdr/rtl-sdr_0.5.3.bb new file mode 100644 index 00000000..77ca871b --- /dev/null +++ b/recipes-connectivity/rtl-sdr/rtl-sdr_0.5.3.bb @@ -0,0 +1,26 @@ +SUMMARY = "Turns a Realtek RTL2832U-based DVB dongle into a SDR receiver" +DESCRIPTION = "DVB-T dongles based on the Realtek RTL2832U chipset can be used as Software Digital Radio adapters, since the chip allows transferring raw I/Q samples to the host, which is really used for DAB/DAB+/FM demodulation." +HOMEPAGE = "http://sdr.osmocom.org/trac/wiki/rtl-sdr" + +LICENSE = "GPL-2.0-or-later" +LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe \ + file://src/librtlsdr.c;endline=18;md5=1b05599c3ebd4d74857a0a7c45f3d4ef" + +DEPENDS = "libusb1" + +SRC_URI = "git://git.osmocom.org/rtl-sdr;branch=master \ + file://0001-remove-I-usr-include-in-pkg-config.patch \ + " +SRCREV = "e3c03f738f5aef4dc51e2b741fbdb542b9cc1bb1" +S = "${WORKDIR}/git" + +inherit autotools pkgconfig + +EXTRA_OECONF = "--enable-driver-detach" + +do_configure:append() { + # remove included temporary path from pc file due to pass-through of OE CFLAGS + # debug-prefix-map + # See: http://lists.openembedded.org/pipermail/openembedded-devel/2016-May/107456.html + sed -i -e "s# -fdebug-prefix-map=.*##g;s# -fmacro-prefix-map=.*##g" librtlsdr.pc +} diff --git a/recipes-connectivity/vss/vss-agl/agl_vss_overlay.vspec b/recipes-connectivity/vss/vss-agl/agl_vss_overlay.vspec new file mode 100644 index 00000000..6c0a08ae --- /dev/null +++ b/recipes-connectivity/vss/vss-agl/agl_vss_overlay.vspec @@ -0,0 +1,334 @@ +# Define DBC mappings for vehicle and engine speeds + +Vehicle.Speed: + datatype: float + type: sensor + dbc: + signal: PT_VehicleAvgSpeed + interval_ms: 100 + +Vehicle.Powertrain.CombustionEngine.Speed: + datatype: float + type: sensor + dbc: + signal: PT_EngineSpeed + interval_ms: 100 + transform: + math: "floor(x+0.5)" + + +# Define extra navigation state signals + +Vehicle.Cabin.Infotainment.Navigation.State: + datatype: string + type: sensor + allowed: [ 'UNKNOWN', 'ACTIVE', 'ARRIVED', 'STOPPED' ] + description: Navigation state. + +Vehicle.Cabin.Infotainment.Navigation.ElapsedDistance: + datatype: float + type: sensor + unit: km + description: Navigation elapsed distance. + + +# Define audio control signals + +Vehicle.Cabin.Infotainment.Media.Audio: + type: branch + description: Media audio controls. + +Vehicle.Cabin.Infotainment.Media.Audio.Balance: + datatype: int8 + type: actuator + min: -100 + max: 100 + unit: percent + description: Audio left/right balance. + +Vehicle.Cabin.Infotainment.Media.Audio.Fade: + datatype: int8 + type: actuator + min: -100 + max: 100 + unit: percent + description: Audio front/rear balance. + +Vehicle.Cabin.Infotainment.Media.Audio.Bass: + datatype: int8 + type: actuator + min: -100 + max: 100 + unit: percent + description: Audio low-frequency filter control. + +Vehicle.Cabin.Infotainment.Media.Audio.Treble: + datatype: int8 + type: actuator + min: -100 + max: 100 + unit: percent + description: Audio high-frequency filter control. + + +# Define extra steering wheel switch signals, including DBC mappings + +Vehicle.Cabin.SteeringWheel: + type: branch + description: AGL steering wheel demo data. + +Vehicle.Cabin.SteeringWheel.Switches: + type: branch + description: AGL steering wheel demo switch data. + +Vehicle.Cabin.SteeringWheel.Switches.VolumeUp: + datatype: boolean + type: sensor + description: Steering wheel volume up switch engaged. + dbc: + signal: SW_VolumeUp + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.VolumeDown: + datatype: boolean + type: sensor + description: Steering wheel volume down switch engaged. + dbc: + signal: SW_VolumeDown + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.VolumeMute: + datatype: boolean + type: sensor + description: Steering wheel volume mute switch engaged. + dbc: + signal: SW_VolumeMute + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.Next: + datatype: boolean + type: sensor + description: Steering wheel next switch engaged. + dbc: + signal: SW_Next + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.Previous: + datatype: boolean + type: sensor + description: Steering wheel previous switch engaged. + dbc: + signal: SW_Previous + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.Mode: + datatype: boolean + type: sensor + description: Steering wheel mode switch engaged. + dbc: + signal: SW_Mode + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.Info: + datatype: boolean + type: sensor + description: Steering wheel info switch engaged. + dbc: + signal: SW_Info + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.CruiseEnable: + datatype: boolean + type: sensor + description: Steering wheel cruise enable switch engaged. + dbc: + signal: SW_CruiseEnable + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.CruiseSet: + datatype: boolean + type: sensor + description: Steering wheel cruise set switch engaged. + dbc: + signal: SW_CruiseSet + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.CruiseResume: + datatype: boolean + type: sensor + description: Steering wheel cruise resume switch engaged. + dbc: + signal: SW_CruiseResume + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.CruiseCancel: + datatype: boolean + type: sensor + description: Steering wheel cruise cancel switch engaged. + dbc: + signal: SW_CruiseCancel + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.CruiseLimit: + datatype: boolean + type: sensor + description: Steering wheel cruise limit switch engaged. + dbc: + signal: SW_CruiseLimit + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.CruiseDistance: + datatype: boolean + type: sensor + description: Steering wheel cruise distance switch engaged. + dbc: + signal: SW_CruiseDistance + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.Voice: + datatype: boolean + type: sensor + description: Steering wheel voice switch engaged. + dbc: + signal: SW_Voice + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.PhoneCall: + datatype: boolean + type: sensor + description: Steering wheel phone call switch engaged. + dbc: + signal: SW_PhoneCall + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.PhoneHangup: + datatype: boolean + type: sensor + description: Steering wheel phone hangup switch engaged. + dbc: + signal: SW_PhoneHangup + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.Horn: + datatype: boolean + type: sensor + description: Steering wheel horn switch engaged. + dbc: + signal: SW_Horn + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true + +Vehicle.Cabin.SteeringWheel.Switches.LaneDepartureWarning: + datatype: boolean + type: sensor + description: Steering wheel lane departure warning switch engaged. + dbc: + signal: SW_LaneDepartureWarning + on_change: true + transform: + mapping: + - from: 0 + to: false + - from: 1 + to: true diff --git a/recipes-connectivity/vss/vss-agl_4.0.bb b/recipes-connectivity/vss/vss-agl_4.0.bb new file mode 100644 index 00000000..83fb4b1a --- /dev/null +++ b/recipes-connectivity/vss/vss-agl_4.0.bb @@ -0,0 +1,36 @@ +SUMMARY = "Vehicle Signal Specification with AGL overlays" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=9741c346eef56131163e13b9db1241b3" + +DEPENDS = "vss-tools-native" + +inherit allarch update-alternatives + +require vss.inc + +SRC_URI += "file://agl_vss_overlay.vspec" + +# Since we're not relying on the simple upstream repo Makefile, use +# best practices and output into a separate directory. +B = "${WORKDIR}/build" + +do_configure[noexec] = "1" + +VSPEC2JSON_OPTS = "-e dbc -o ${WORKDIR}/agl_vss_overlay.vspec --no-uuid --json-pretty" + +do_compile() { + vspec2json.py -I ${S}/spec ${VSPEC2JSON_OPTS} -u ${S}/spec/units.yaml ${S}/spec/VehicleSignalSpecification.vspec vss_rel_${PV}-agl.json +} + +do_install() { + install -d ${D}${datadir}/vss + install -m 0644 vss_rel_${PV}-agl.json ${D}${datadir}/vss/ +} + +ALTERNATIVE_LINK_NAME[vss.json] = "${datadir}/vss/vss.json" + +ALTERNATIVE_PRIORITY = "20" +ALTERNATIVE:${PN} = "vss.json" +ALTERNATIVE_TARGET_${PN} = "${datadir}/vss/vss_rel_${PV}-agl.json" + +FILES:${PN} += "${datadir}/vss/" diff --git a/recipes-connectivity/vss/vss-tools_4.0.bb b/recipes-connectivity/vss/vss-tools_4.0.bb new file mode 100644 index 00000000..432dd39b --- /dev/null +++ b/recipes-connectivity/vss/vss-tools_4.0.bb @@ -0,0 +1,28 @@ +SUMMARY = "COVESA Vehicle Signal Specification tooling." +HOMEPAGE = "https://github.com/COVESA/vss-tools" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=9741c346eef56131163e13b9db1241b3" + +SRC_URI = "git://github.com/COVESA/vss-tools.git;protocol=https;branch=master" +SRCREV = "784505f3005c2350d7861c3add030348e2d910e3" + +S = "${WORKDIR}/git" + +inherit setuptools3 + +RDEPENDS:${PN} += " \ + python3-core \ + python3-ctypes \ + python3-email \ + python3-json \ + python3-logging \ + python3-netclient \ + python3-pkg-resources \ + python3-anytree \ + python3-deprecation \ + python3-graphql-core \ + python3-pyyaml \ + python3-six \ +" + +BBCLASSEXTEND += "native nativesdk" diff --git a/recipes-connectivity/vss/vss.inc b/recipes-connectivity/vss/vss.inc new file mode 100644 index 00000000..de2ffdcf --- /dev/null +++ b/recipes-connectivity/vss/vss.inc @@ -0,0 +1,5 @@ +SRC_URI = "git://github.com/COVESA/vehicle_signal_specification.git;branch=release/4.0;protocol=https" +# v4.0 +SRCREV = "249dc03f3d75f96218c95483df0a32a2c3535964" + +S = "${WORKDIR}/git" diff --git a/recipes-connectivity/vss/vss_4.0.bb b/recipes-connectivity/vss/vss_4.0.bb new file mode 100644 index 00000000..05351662 --- /dev/null +++ b/recipes-connectivity/vss/vss_4.0.bb @@ -0,0 +1,43 @@ +SUMMARY = "Vehicle Signal Specification" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=9741c346eef56131163e13b9db1241b3" + +DEPENDS = "vss-tools-native" + +inherit allarch update-alternatives + +require vss.inc + +UPSTREAM_CHECK_GITTAGREGEX = "v(?P<pver>\d+(\.\d+)+)" + +S = "${WORKDIR}/git" + +do_configure[noexec] = "1" + +EXTRA_OEMAKE = "TOOLSDIR=${STAGING_BINDIR_NATIVE}" + +do_compile() { + oe_runmake json +} + +do_install() { + # Cannot use the "install" target in the project Makefile, as it is + # intended for setting the repo up for builds. + # For now, just the generated JSON is installed. It is possible that + # installing the vspec files somewhere as a development package may + # be useful, but for now things will be kept simple. + install -d ${D}${datadir}/vss + install -m 0644 ${S}/vss_rel_${PV}.json ${D}${datadir}/vss/ +} + +# NOTE: +# A virtual RPROVIDES is not used for now, as packages such as KUKSA.val +# provide their own copies of the VSS JSON, so we can install this one +# and any alternatives in parallel and point e.g. KUKSA.val at the desired +# file with a configuration change. This may be worth revisiting down the +# road. + +ALTERNATIVE_LINK_NAME[vss.json] = "${datadir}/vss/vss.json" + +ALTERNATIVE:${PN} = "vss.json" +ALTERNATIVE_TARGET_${PN} = "${datadir}/vss/vss_rel_${PV}.json" diff --git a/recipes-core/base-files-guest/base-files-guest-fstab/fstab b/recipes-core/base-files-guest/base-files-guest-fstab/fstab new file mode 100644 index 00000000..d6c936be --- /dev/null +++ b/recipes-core/base-files-guest/base-files-guest-fstab/fstab @@ -0,0 +1,3 @@ +# Reference fstab for container guest +devpts /dev/pts devpts mode=0620,ptmxmode=0666,gid=5 0 0 +tmpfs /var/volatile tmpfs defaults 0 0 diff --git a/recipes-core/base-files-guest/base-files-guest-fstab_1.0.0.bb b/recipes-core/base-files-guest/base-files-guest-fstab_1.0.0.bb new file mode 100644 index 00000000..ad3e6e94 --- /dev/null +++ b/recipes-core/base-files-guest/base-files-guest-fstab_1.0.0.bb @@ -0,0 +1,25 @@ +SUMMARY = "Container guest extention for fstab" +DESCRIPTION = "The base-files-guest-fstab package creates the fstab for container guest integration." +SECTION = "base" +LICENSE = "GPL-2.0-only" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6" + +SRC_URI = " \ + file://fstab \ +" +S = "${WORKDIR}" + +#INHIBIT_DEFAULT_DEPS = "1" + +do_install () { + install -m 0755 -d ${D}${sysconfdir} + + install -m 0644 ${WORKDIR}/fstab ${D}${sysconfdir}/fstab-guest +} + +PACKAGES = "${PN}" +FILES:${PN} = "${sysconfdir}/fstab-guest" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +CONFFILES:${PN} = "${sysconfdir}/fstab-guest" diff --git a/recipes-core/dbus/dbus/dbus.service b/recipes-core/dbus/dbus/dbus.service new file mode 100644 index 00000000..dee6ad74 --- /dev/null +++ b/recipes-core/dbus/dbus/dbus.service @@ -0,0 +1,10 @@ +[Unit] +Description=D-Bus User Message Bus +Documentation=man:dbus-daemon(1) +Requires=dbus.socket + +[Service] +ExecStart=/usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation +ExecReload=/usr/bin/dbus-send --print-reply --session --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig +Restart=always +RestartSec=1 diff --git a/recipes-core/dbus/dbus/dbus.socket b/recipes-core/dbus/dbus/dbus.socket new file mode 100644 index 00000000..af76b2f1 --- /dev/null +++ b/recipes-core/dbus/dbus/dbus.socket @@ -0,0 +1,9 @@ +[Unit] +Description=D-Bus User Message Bus Socket +Before=sockets.target + +[Socket] +ListenStream=%t/bus + +[Install] +WantedBy=default.target diff --git a/recipes-core/dbus/dbus/dbus_env.conf b/recipes-core/dbus/dbus/dbus_env.conf new file mode 100644 index 00000000..f8f02669 --- /dev/null +++ b/recipes-core/dbus/dbus/dbus_env.conf @@ -0,0 +1,5 @@ +[Unit] +Wants=dbus.service + +[Service] +Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/bus diff --git a/recipes-core/dbus/dbus_%.bbappend b/recipes-core/dbus/dbus_%.bbappend new file mode 100644 index 00000000..8abed712 --- /dev/null +++ b/recipes-core/dbus/dbus_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'dbus_agldemo.inc', '', d)} diff --git a/recipes-core/dbus/dbus_agldemo.inc b/recipes-core/dbus/dbus_agldemo.inc new file mode 100644 index 00000000..826584c0 --- /dev/null +++ b/recipes-core/dbus/dbus_agldemo.inc @@ -0,0 +1,28 @@ +FILESEXTRAPATHS:append := ":${THISDIR}/dbus" + +SRC_URI += "file://dbus.service \ + file://dbus.socket \ + file://dbus_env.conf \ + " + +inherit systemd + +do_install:append() { + if [ "${PN}" != "nativesdk-dbus" ]; then + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -m 644 -p -D ${WORKDIR}/dbus.service ${D}${systemd_user_unitdir}/dbus.service + install -m 644 -p -D ${WORKDIR}/dbus.socket ${D}${systemd_user_unitdir}/dbus.socket + install -m 644 -p -D ${WORKDIR}/dbus_env.conf ${D}${systemd_system_unitdir}/user@.service.d/dbus_env.conf + + # Execute these manually on behalf of systemctl script (from systemd-systemctl-native.bb) + # because it does not support systemd's user mode. + install -d ${D}${sysconfdir}/systemd/user/default.target.wants/ + ln -sf ${systemd_user_unitdir}/dbus.socket ${D}${sysconfdir}/systemd/user/default.target.wants/dbus.socket + fi + fi +} + +FILES:${PN} += " \ + ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/dbus.*', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_system_unitdir}/user@.service.d/dbus_env.conf', '', d)} \ + " diff --git a/recipes-core/distro-build-manifest/distro-build-manifest.bb b/recipes-core/distro-build-manifest/distro-build-manifest.bb new file mode 100644 index 00000000..823cc28a --- /dev/null +++ b/recipes-core/distro-build-manifest/distro-build-manifest.bb @@ -0,0 +1,164 @@ +SUMMARY = "Distribution build manifest" +DESCRIPTION = "The folder /etc/platform-info contains build manifest (SPEC-720)." +LICENSE = "MIT" + +# information distributed by the package is machine specific +PACKAGE_ARCH = "${MACHINE_ARCH}" + +# dependencies of ${DISTRO_MANIFEST_GENERATOR} +DEPENDS = "coreutils-native bash-native git-native gawk-native sed-native jq-native" + +# force a rebuild everytime a build is started +do_compile[nostamp] = "1" + +# borrowed to os-release.bb (output format is very close) +python do_compilestep1 () { + import shutil + with open(d.expand('${B}/bbinfo-deploy'),'w') as f: + allkeys=[] + for field in d.getVar('BUILD_MANIFEST_FIELDS_DEPLOY').split(): + key='DIST_BB_{0}'.format(field) + allkeys.append(key) + value=d.getVar(field) + if value: + f.write('{0}="{1}"\n'.format(key,value)) + f.write('declare -A BITBAKE_VARS\nBITBAKE_VARS[deploy]="%s"' % ' '.join(allkeys)) + + with open(d.expand('${B}/bbinfo-target'),'w') as f: + allkeys=[] + for field in d.getVar('BUILD_MANIFEST_FIELDS_TARGET').split(): + key='DIST_BB_{0}'.format(field) + allkeys.append(key) + value=d.getVar(field) + if value: + f.write('{0}="{1}"\n'.format(key,value)) + f.write('declare -A BITBAKE_VARS\nBITBAKE_VARS[target]="%s"' % ' '.join(allkeys)) + + with open(d.expand('${B}/bbinfo-sdk'),'w') as f: + allkeys=[] + for field in d.getVar('BUILD_MANIFEST_FIELDS_SDK').split(): + key='DIST_BB_{0}'.format(field) + allkeys.append(key) + value=d.getVar(field) + if value: + f.write('{0}="{1}"\n'.format(key,value)) + f.write('declare -A BITBAKE_VARS\nBITBAKE_VARS[sdk]="%s"' % ' '.join(allkeys)) +} + +do_compilestep2 () { + rc=99 + timestamp=${DATETIME} + outfile=${B}/build-info + if [ -x "${DISTRO_MANIFEST_GENERATOR}" -a -f "${DISTRO_SETUP_MANIFEST}" ]; then + rc=0 + for format in bash json; do + if [ "$format" = "json" ]; then + ext=".json" + else + ext="" + fi + for mode in deploy target sdk; do + ${DISTRO_MANIFEST_GENERATOR} -m $mode -f $format -t $timestamp -s ${B}/bbinfo-${mode} ${DISTRO_SETUP_MANIFEST} >${outfile}-${mode}${ext} + rc=$? + if [ $rc -ne 0 ]; then + break + fi + done + done + else + if [ -z "${DISTRO_MANIFEST_GENERATOR}" ]; then + echo "The name of the generation script is not defined." + elif [ ! -f "${DISTRO_MANIFEST_GENERATOR}" ]; then + echo "Generation script ${DISTRO_MANIFEST_GENERATOR} is missing." + elif [ ! -x "${DISTRO_MANIFEST_GENERATOR}" ]; then + echo "Generation script ${DISTRO_MANIFEST_GENERATOR} isn't executable." + fi + if [ -z "${DISTRO_SETUP_MANIFEST}" ]; then + echo "The name of the data file is not defined." + elif [ ! -f "${DISTRO_SETUP_MANIFEST}" ]; then + echo "Data file ${DISTRO_SETUP_MANIFEST} is missing." + fi + echo "You can try to rerun aglsetup.sh to solve that issue." + echo "You can also try to source agl-init-build-env instead of oe-init-build-env." + fi + + if [ "$rc" -ne 0 ]; then + echo "distro-build-manifest generation failed." + fi + return $rc +} + +do_compilestep1[vardeps] += " ${BUILD_MANIFEST_FIELDS_DEPLOY}" +do_compilestep1[vardeps] += " ${BUILD_MANIFEST_FIELDS_TARGET}" +do_compilestep1[vardeps] += " ${BUILD_MANIFEST_FIELDS_SDK}" + +# avoid errors "ERROR: When reparsing .../distro-build-manifest/distro-build-manifest.bb.do_compile, the basehash value changed from .... to .... . The metadata is not deterministic and this needs to be fixed." +do_compilestep2[vardepsexclude] = "DATETIME" + +# combine the two steps +python do_compile() { + bb.build.exec_func("do_compilestep1",d) + bb.build.exec_func("do_compilestep2",d) +} + +do_install () { + # install in target dir + install -d ${D}${sysconfdir}/platform-info + install -m 0644 build-info-target ${D}${sysconfdir}/platform-info/build + install -m 0644 build-info-target.json ${D}${sysconfdir}/platform-info/build.json + + # also copy in deploy dir + install -d ${DEPLOY_DIR_IMAGE} + install -m 0644 build-info-deploy ${DEPLOY_DIR_IMAGE}/build-info + install -m 0644 build-info-deploy.json ${DEPLOY_DIR_IMAGE}/build-info.json + + # copy into sdk deploy dir + install -d ${DEPLOY_DIR}/sdk + install -m 0644 build-info-sdk ${DEPLOY_DIR}/sdk/${SDK_NAME}.build-info + install -m 0644 build-info-sdk.json ${DEPLOY_DIR}/sdk/${SDK_NAME}.build-info.json + + # and copy to nativesdk package + # TODO +} + +# list of variables to add to the various manifests +# smalles one is 'target', then 'deploy' and finally 'sdk' +BUILD_MANIFEST_FIELDS_TARGET = "\ + MACHINE_ARCH \ + MACHINEOVERRIDES \ + MACHINE_FEATURES \ + DISTRO_CODENAME \ + DISTRO_FEATURES \ + DISTRO_BRANCH_VERSION_TAG \ + AGLVERSION \ + AGL_BRANCH \ + AGLRELEASETYPE \ +" + +BUILD_MANIFEST_FIELDS_DEPLOY = "\ + ${BUILD_MANIFEST_FIELDS_TARGET} \ + DISTRO \ + DISTRO_VERSION \ + DISTROOVERRIDES \ + TUNE_FEATURES \ + TUNE_PKGARCH \ + ALL_MULTILIB_PACKAGE_ARCHS \ +" + +BUILD_MANIFEST_FIELDS_SDK = "\ + ${BUILD_MANIFEST_FIELDS_DEPLOY} \ + HOST_SYS \ + TARGET_SYS \ + TARGET_VENDOR \ + SDK_ARCH \ + SDK_VENDOR \ + SDK_VERSION \ + SDK_OS \ +" + +# dont exec useless tasks +do_fetch[noexec] = "1" +do_unpack[noexec] = "1" +do_patch[noexec] = "1" +do_configure[noexec] = "1" + diff --git a/recipes-core/nss/nss-agl-driver-db/nss-agl-driver-db.service b/recipes-core/nss/nss-agl-driver-db/nss-agl-driver-db.service new file mode 100644 index 00000000..40818cf2 --- /dev/null +++ b/recipes-core/nss/nss-agl-driver-db/nss-agl-driver-db.service @@ -0,0 +1,12 @@ +[Unit] +Description=Deploy Kuksa certificates to /home/agl-driver/.pki/ +After=local-fs.target +Before=multi-user.target +ConditionPathExists=!/home/agl-driver/.pki + +[Service] +User=agl-driver +ExecStart=/usr/sbin/nss-agl-driver-db.sh + +[Install] +WantedBy=multi-user.target diff --git a/recipes-core/nss/nss-agl-driver-db/nss-agl-driver-db.sh b/recipes-core/nss/nss-agl-driver-db/nss-agl-driver-db.sh new file mode 100755 index 00000000..1a8351bf --- /dev/null +++ b/recipes-core/nss/nss-agl-driver-db/nss-agl-driver-db.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e + +# TLDR we need this file for chromium to connect back to kuksa. + +# check if directory already exists and bail out +if test -d /home/agl-driver/.pki/nssdb ; then + echo "Directory already exists! Doing nothing." + exit 127 +fi + +# setup empty db in subfolder +mkdir -p /home/agl-driver/.pki/nssdb +certutil -N -d /home/agl-driver/.pki/nssdb --empty-password + +# deploy cert into local db +certutil -A -d /home/agl-driver/.pki/nssdb -n "KuksaRootCA" -t "pC,," -i /etc/kuksa-val/CA.pem + +#chown -R agl-driver:agl-driver /home/agl-driver/.pki/nssdb diff --git a/recipes-core/nss/nss-agl-driver-db_git.bb b/recipes-core/nss/nss-agl-driver-db_git.bb new file mode 100644 index 00000000..b2fb4034 --- /dev/null +++ b/recipes-core/nss/nss-agl-driver-db_git.bb @@ -0,0 +1,32 @@ +SUMMARY = "Custom nss db hosting the kuksa certificates" +DESCRIPTION = "Custom nss db hosting the kuksa certificates for chromium" +AUTHOR = "Jan-Simon Moeller <jsmoeller@linuxfoundation.org>" +HOMEPAGE = "https://git.automotivelinux.org" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +PV = "0.1" + +SRC_URI = "file://${BPN}.service \ + file://${BPN}.sh \ + " + +inherit systemd + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -d ${D}${systemd_system_unitdir} + install -d ${D}${sbindir} + install -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir} + install -m 0755 ${WORKDIR}/${BPN}.sh ${D}${sbindir} + fi +} + +FILES:${PN} += "${systemd_system_unitdir} ${sbindir}" + +RDEPENDS:${PN} += "nss agl-users kuksa-val-certificates-client bash" diff --git a/recipes-core/packagegroups/packagegroup-agl-image-ivi.bbappend b/recipes-core/packagegroups/packagegroup-agl-image-ivi.bbappend deleted file mode 100644 index e1b68abc..00000000 --- a/recipes-core/packagegroups/packagegroup-agl-image-ivi.bbappend +++ /dev/null @@ -1,3 +0,0 @@ -RDEPENDS_${PN} += " \ - packagegroup-agl-ivi-identity \ -" diff --git a/recipes-core/packagegroups/packagegroup-agl-ivi-connectivity.bbappend b/recipes-core/packagegroups/packagegroup-agl-ivi-connectivity.bbappend deleted file mode 100644 index 6e19d78c..00000000 --- a/recipes-core/packagegroups/packagegroup-agl-ivi-connectivity.bbappend +++ /dev/null @@ -1,5 +0,0 @@ - -RDEPENDS_${PN} += "\ - agl-service-nfc \ -" - diff --git a/recipes-core/packagegroups/packagegroup-agl-ivi-identity.bb b/recipes-core/packagegroups/packagegroup-agl-ivi-identity.bb deleted file mode 100644 index fa157c8f..00000000 --- a/recipes-core/packagegroups/packagegroup-agl-ivi-identity.bb +++ /dev/null @@ -1,9 +0,0 @@ -inherit packagegroup - -RDEPENDS_${PN} += "\ - agl-service-data-persistence \ - agl-service-identity-agent \ -" - -LICENSE = "MIT" - diff --git a/recipes-core/psplash/.appends.core b/recipes-core/psplash/.appends.core new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/recipes-core/psplash/.appends.core diff --git a/recipes-core/psplash/files/psplash-args.conf b/recipes-core/psplash/files/psplash-args.conf new file mode 100644 index 00000000..e5b34f4d --- /dev/null +++ b/recipes-core/psplash/files/psplash-args.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=/usr/bin/psplash $PSPLASH_ARGS $PSPLASH_ANGLE_ARGS diff --git a/recipes-core/psplash/files/psplash-colors.h b/recipes-core/psplash/files/psplash-colors.h new file mode 100644 index 00000000..44749039 --- /dev/null +++ b/recipes-core/psplash/files/psplash-colors.h @@ -0,0 +1,34 @@ +/* + * pslash - a lightweight framebuffer splashscreen for embedded devices. + * + * Copyright (c) 2012 sleep(5) ltd + * Author: Tomas Frydrych <tomas@sleepfive.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _HAVE_PSPLASH_COLORS_H +#define _HAVE_PSPLASH_COLORS_H + +/* This is the overall background color */ +#define PSPLASH_BACKGROUND_COLOR 0xff,0xff,0xff + +/* This is the color of any text output */ +#define PSPLASH_TEXT_COLOR 0x00,0x00,0x00 + +/* This is the color of the progress bar indicator */ +#define PSPLASH_BAR_COLOR 0x00,0x00,0x00 + +/* This is the color of the progress bar background */ +#define PSPLASH_BAR_BACKGROUND_COLOR 0xff,0xff,0xff + +#endif diff --git a/recipes-core/psplash/files/psplash-inverted.conf b/recipes-core/psplash/files/psplash-inverted.conf new file mode 100644 index 00000000..440db891 --- /dev/null +++ b/recipes-core/psplash/files/psplash-inverted.conf @@ -0,0 +1,2 @@ +[Service] +Environment=PSPLASH_ANGLE_ARGS='--angle 180' diff --git a/recipes-core/psplash/files/psplash-poky-img.h b/recipes-core/psplash/files/psplash-poky-img.h new file mode 100644 index 00000000..c0e8b081 --- /dev/null +++ b/recipes-core/psplash/files/psplash-poky-img.h @@ -0,0 +1,5411 @@ +/* GdkPixbuf RGB C-Source image dump 1-byte-run-length-encoded */ + +#define POKY_IMG_ROWSTRIDE (1800) +#define POKY_IMG_WIDTH (600) +#define POKY_IMG_HEIGHT (400) +#define POKY_IMG_BYTES_PER_PIXEL (3) /* 3:RGB, 4:RGBA */ +#define POKY_IMG_RLE_PIXEL_DATA ((uint8*) \ + "\377\377\377\377\377\377\377\377\203\377\377\377\1\376\376\376\221\377" \ + "\377\377\1\376\376\376\215\377\377\377\1\376\376\376\203\377\377\377" \ + "\1\376\376\376\233\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \ + "\376\202\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377" \ + "\376\376\376\206\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \ + "\376\204\377\377\377\1\376\376\376\203\377\377\377\5\376\376\376\377" \ + "\377\377\376\376\376\377\377\377\376\376\376\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\202\376\376\376\207\377\377" \ + "\377\1\376\376\376\205\377\377\377\1\376\376\376\211\377\377\377\3\376" \ + "\376\376\377\377\377\376\376\376\235\377\377\377\1\376\376\376\203\377" \ + "\377\377\1\376\376\376\213\377\377\377\3\376\376\376\377\377\377\376" \ + "\376\376\216\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\365\377\377\377\1\376" \ + "\376\376\203\377\377\377\1\376\376\376\207\377\377\377\1\376\376\376" \ + "\203\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\205\377" \ + "\377\377\1\376\376\376\203\377\377\377\12\376\376\376\377\377\377\346" \ + "\346\346\315\315\315\316\316\316\265\265\265\235\235\235\234\234\234" \ + "\233\233\233\204\204\204\203kkm\202lln\2EEG;;=\215::<\204kkm\3kkkxxx" \ + "\235\235\235\202\234\234\234\1\265\265\265\202\316\316\316\1\332\332" \ + "\332\207\377\377\377\202\376\376\376\2\377\377\377\376\376\376\211\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\203\377\377\377\5\376" \ + "\376\376\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\366\377\377\377\1\376\376\376\205" \ + "\377\377\377\1\376\376\376\214\377\377\377\11\376\376\376\332\332\332" \ + "\316\316\320\247\247\251\236\236\240\204\204\206kkm__a<<>\202::<\11;" \ + ";=99;;;=99;::<;;=::<;;=99;\203::<\1<<>\213::<\13;;=::<;;=::<;;=::<;;" \ + "=::<;;=::<;;=\207::<\3SSUllnxxz\202\234\234\236\202\316\316\316\2\377" \ + "\377\377\376\376\376\214\377\377\377\1\376\376\376\203\377\377\377\1" \ + "\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\376\377" \ + "\377\377\1\376\376\376\203\377\377\377\1\376\376\376\203\377\377\377" \ + "\7\332\332\334\302\302\304\234\234\236\203\203\205llnEEG;;=\202::<\6" \ + ";;=::<;;=::<;;=99;\204::<\1""99;\202;;=\1""99;\205::<\1;;=\213::<\11" \ + ";;=::<;;=::<;;=::<;;=::<;;=\202::<\1""99;\206::<\1;;=\203::<\13;;=99" \ + ";;;=::<;;=::<kkmxxz\234\234\236\300\300\302\316\316\316\203\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \ + "\376\204\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\374\377\377\377\7\346\346\350\301\301\303\235\235\237ww" \ + "y``b99;;;=\202::<\1;;=\204::<\203;;=\3::<99;;;=\207::<\202;;=\204::<" \ + "\203;;=\215::<\1;;=\207::<\11;;=::<;;=99;::<;;=::<99;::<\202;;=\5::<" \ + ";;=::<;;=99;\202::<\2;;=::<\202;;=\6::<SSUkkm\235\235\237\264\264\266" \ + "\332\332\334\210\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \ + "\376\377\377\377\377\377\377\377\377\377\377\377\377\362\377\377\377" \ + "\1\376\376\376\202\377\377\377\11\346\346\350\265\265\267\221\221\223" \ + "kkm::<;;=::<99;;;=\203::<\1;;=\202::<\3""99;::<;;=\202::<\4;;=99;::<" \ + ";;=\204::<\1;;=\202::<\202;;=\1::<\202;;=\202::<\1;;=\203::<\1;;=\211" \ + "::<\2;;=99;\202::<\2;;=99;\206::<\1;;=\202::<\2""99;;;=\210::<\1;;=\202" \ + "::<\1;;=\203::<\1;;=\203::<\1;;=\202::<\4kkm\222\222\224\265\265\267" \ + "\332\332\334\204\377\377\377\1\376\376\376\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\362\377\377\377\12\363\363\363\316\316\316\235\235" \ + "\235jjjFFH;;=::<;;=::<;;=\202::<\1;;=\204::<\1""99;\202::<\2;;=::<\202" \ + ";;=\204::<\7;;=::<;;=::<;;=::<;;=\203::<\1;;=\202::<\1;;=\217::<\2""9" \ + "9;;;=\203::<\1;;=\202::<\4""99;;;=::<;;=\203::<\2;;=99;\202::<\1;;=\207" \ + "::<\1;;=\213::<\1;;=\204::<\7kkk\221\221\221\301\301\301\363\363\363" \ + "\376\376\376\377\377\377\376\376\376\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\321\377\377\377\1\376\376\376\202\377\377\377\1\376" \ + "\376\376\221\377\377\377\1\376\376\376\204\377\377\377\4\363\363\365" \ + "\301\301\303\222\222\224__a\220::<\3;;=::<;;=\204::<\203;;=\203::<\2" \ + ";;=::<\202;;=\4::<;;=::<;;=\204::<\1;;=\202::<\4;;=::<99;;;=\211::<\1" \ + "99;\205::<\202;;=\210::<\5;;=::<;;=::<;;=\203::<\1;;=\212::<\4;;=99;" \ + ";;=99;\211::<\4SSU\204\204\206\266\266\270\345\345\345\221\377\377\377" \ + "\1\376\376\376\204\377\377\377\202\376\376\376\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\266\377\377\377\1\376\376\376\203\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\207\377\377\377\1\376\376" \ + "\376\210\377\377\377\10\363\363\363\301\301\301\221\221\221``b99;;;=" \ + "::<;;=\213::<\3;;=::<;;=\203::<\1;;=\204::<\2;;=99;\202::<\1""99;\202" \ + ";;=\204::<\1;;=\210::<\202;;=\202::<\2;;=99;\215::<\1;;=\204::<\1;;=" \ + "\205::<\5;;=99;;;=::<;;=\202::<\202;;=\4""99;;;=::<;;=\203::<\1;;=\204" \ + "::<\3;;=99;;;=\210::<\11;;=::<;;=99;;;=SSS\205\205\205\266\266\266\363" \ + "\363\363\202\377\377\377\1\376\376\376\206\377\377\377\1\376\376\376" \ + "\204\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\266\377\377\377\1\376\376\376" \ + "\204\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\207\377" \ + "\377\377\5\376\376\376\333\333\335\250\250\252kkm;;=\203::<\202;;=\212" \ + "::<\10;;=::<;;=::<;;=::<;;=::<\202;;=\206::<\10;;=::<;;=::<;;=::<;;=" \ + "::<\202;;=\2::<;;=\203::<\3;;=::<;;=\202::<\1;;=\202::<\1;;=\211::<\1" \ + "99;\202;;=\203::<\1;;=\205::<\1;;=\204::<\1;;=\206::<\203;;=\202::<\1" \ + ";;=\206::<\1;;=\213::<\1;;=\204::<\1;;=\202::<\3__a\221\221\223\316\316" \ + "\316\204\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\207" \ + "\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\267\377\377\377\202\376\376\376\210\377\377\377\1\376\376\376\207" \ + "\377\377\377\3\301\301\301\204\204\206SSU\203::<\3;;=::<;;=\202::<\2" \ + "99;;;=\215::<\1;;=\204::<\2;;=99;\202::<\202;;=\202::<\7""99;::<;;=:" \ + ":<;;=99;;;=\202::<\2""99;;;=\202::<\1;;=\207::<\1;;=\211::<\2""99;;;" \ + "=\202::<\3;;=::<;;=\202::<\2""99;;;=\206::<\4;;=::<;;=::<\202;;=\206" \ + "::<\3;;=::<;;=\202::<\5;;=::<;;=99;;;=\220::<\2;;=::<\202;;=\5""99;G" \ + "GIxxx\265\265\265\363\363\363\207\377\377\377\1\376\376\376\205\377\377" \ + "\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\274" \ + "\377\377\377\1\376\376\376\204\377\377\377\202\376\376\376\4\364\364" \ + "\364\265\265\265xxz;;=\20299;\202::<\1""99;\204::<\3;;=::<;;=\213::<" \ + "\1;;=\203::<\3;;=::<;;=\207::<\2;;=::<\202;;=\4""99;;;=::<;;=\202::<" \ + "\5__allnkkm\221\221\223\235\235\237\202\234\234\236\6\317\317\317\315" \ + "\315\315\317\317\317\315\315\315\316\316\316\346\346\346\213\377\377" \ + "\377\3\376\376\376\377\377\377\346\346\346\204\316\316\316\5\316\316" \ + "\320\251\251\253\234\234\236\233\233\235\235\235\237\203kkm\202::<\1" \ + ";;=\202::<\6;;=::<;;=99;::<;;=\205::<\2;;=::<\203;;=\202::<\1;;=\212" \ + "::<\1;;=\202::<\1;;=\202::<\1;;=\204::<\1;;=\202::<\3lln\250\250\252" \ + "\346\346\350\206\377\377\377\1\376\376\376\204\377\377\377\1\376\376" \ + "\376\377\377\377\377\377\377\377\377\377\377\377\377\271\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\4\362\362" \ + "\362\266\266\270xxz::<\202;;=\202::<\10;;=::<99;;;=::<;;=::<;;=\203:" \ + ":<\1;;=\213::<\3;;=::<;;=\205::<\1;;=\202::<\1<<>\202::<\7llnkkm\233" \ + "\233\235\235\235\237\302\302\304\316\316\320\347\347\351\241\377\377" \ + "\377\202\376\376\376\203\377\377\377\17\376\376\376\377\377\377\376\376" \ + "\376\377\377\377\376\376\376\363\363\363\316\316\316\315\315\315\234" \ + "\234\234\235\235\235xxxllnFFH::<;;=\205::<\5;;=99;;;=::<;;=\212::<\202" \ + ";;=\212::<\5;;=99;;;=::<99;\202::<\5__a\250\250\252\346\346\346\377\377" \ + "\377\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\271\377\377\377\202\376\376\376\2\377\377\377" \ + "\376\376\376\203\377\377\377\3\363\363\363\266\266\266wwy\202;;=\210" \ + "::<\1<<>\203::<\2<<>99;\215::<\1;;=\205::<\11;;=::<;;;___xxx\235\235" \ + "\235\266\266\266\315\315\315\364\364\364\207\377\377\377\1\376\376\376" \ + "\213\377\377\377\1\376\376\376\231\377\377\377\5\376\376\376\377\377" \ + "\377\376\376\376\377\377\377\376\376\376\202\377\377\377\1\376\376\376" \ + "\204\377\377\377\1\376\376\376\202\377\377\377\5\316\316\316\302\302" \ + "\302\233\233\233yyykkk\202::<\6;;=::<;;=::<99;;;=\211::<\1;;=\202::<" \ + "\1;;=\206::<\1""99;\202;;=\202::<\203;;=\1""99;\202::<\3__a\251\251\253" \ + "\346\346\346\204\377\377\377\3\376\376\376\377\377\377\376\376\376\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\266\377\377\377\1\376\376" \ + "\376\202\377\377\377\2\302\302\302xxx\203::<\3;;=::<;;=\232::<\1;;=\202" \ + "::<\6RRTkkm\235\235\237\301\301\303\332\332\334\376\376\376\222\377\377" \ + "\377\1\376\376\376\260\377\377\377\3\376\376\376\377\377\377\376\376" \ + "\376\202\377\377\377\5\345\345\347\316\316\320\235\235\237xxzSSU\215" \ + "::<\202;;=\202::<\203;;=\2::<;;=\203::<\1;;=\204::<\10;;=::<;;=::<;;" \ + "=kkm\266\266\266\363\363\363\202\377\377\377\1\376\376\376\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\245\377\377\377\1\376\376\376\214" \ + "\377\377\377\1\376\376\376\202\377\377\377\5\376\376\376\377\377\377" \ + "\332\332\332\205\205\207GGI\202::<\1;;=\211::<\202;;=\205::<\2;;=::<" \ + "\202;;=\203::<\14;;=99;::<;;=99;;;=FFFxxx\234\234\234\315\315\315\364" \ + "\364\364\376\376\376\323\377\377\377\4\317\317\317\250\250\250xxxSSS" \ + "\202::<\1;;=\206::<\2;;=::<\203;;=\202::<\2;;=99;\204::<\7;;=::<;;=:" \ + ":<;;=::<;;=\204::<\3\204\204\206\301\301\301\376\376\376\220\377\377" \ + "\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\225" \ + "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\206\377\377" \ + "\377\1\376\376\376\202\377\377\377\4\363\363\363\251\251\251___;;=\202" \ + "::<\1;;=\202::<\202;;=\204::<\1;;=\202::<\7;;=::<;;=::<;;=::<;;=\203" \ + "::<\3""99;::<;;=\202::<\5;;=__a\221\221\223\265\265\267\346\346\346\323" \ + "\377\377\377\1\376\376\376\211\377\377\377\5\363\363\363\301\301\303" \ + "\235\235\237lln::<\202;;=\203::<\1;;=\204::<\1;;=\202::<\2""99;;;=\205" \ + "::<\2;;=99;\203::<\1""99;\204::<\3TTT\233\233\233\346\346\346\207\377" \ + "\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\250\377\377\377\3\316\316\316\204\204\204;;=\203::<\1;;=\203::<\1;;" \ + "=\202::<\1;;=\205::<\3;;=::<;;=\202::<\4""99;;;=::<;;=\202::<\202;;=" \ + "\4___\221\221\221\301\301\303\363\363\365\203\377\377\377\1\376\376\376" \ + "\203\377\377\377\202\376\376\376\321\377\377\377\1\376\376\376\210\377" \ + "\377\377\1\376\376\376\202\377\377\377\4\316\316\316\235\235\235kkk;" \ + ";=\202::<\202;;=\203::<\5;;=::<;;=99;;;=\204::<\202;;=\7::<;;=99;::<" \ + ";;=::<;;=\202::<\202;;=\2xxz\302\302\304\213\377\377\377\1\376\376\376" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\224\377\377\377\1\376" \ + "\376\376\212\377\377\377\3\363\363\363\266\266\266TTV\203::<\3;;=::<" \ + ";;=\202::<\203;;=\202::<\202;;=\205::<\1;;=\202::<\1;;=\204::<\4SSU\221" \ + "\221\223\301\301\301\363\363\363\206\377\377\377\1\376\376\376\203\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\315\377\377\377" \ + "\202\376\376\376\202\377\377\377\1\376\376\376\210\377\377\377\1\376" \ + "\376\376\202\377\377\377\1\376\376\376\202\377\377\377\3\316\316\316" \ + "\221\221\223__a\203::<\1;;=\203::<\3;;=::<;;=\203::<\5;;=99;;;=::<;;" \ + "=\204::<\1""99;\205::<\3SSU\234\234\236\346\346\346\207\377\377\377\3" \ + "\376\376\376\377\377\377\376\376\376\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\233\377\377\377\4\376\376\376\347\347\347\221\221\221" \ + "FFH\207::<\4""99;;;=::<;;=\20299;\202;;=\202::<\1;;=\203::<\2;;=::<\202" \ + ";;=\202::<\3xxz\250\250\252\346\346\350\215\377\377\377\203\376\376\376" \ + "\316\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\211\377" \ + "\377\377\1\376\376\376\211\377\377\377\4\363\363\363\265\265\267\205" \ + "\205\207FFH\210::<\3;;=::<;;=\204::<\1;;=\207::<\2;;=::<\202;;=\2\203" \ + "\203\205\317\317\321\206\377\377\377\1\376\376\376\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\233\377\377\377\3\316\316\316yy{99;\206" \ + "::<\2;;=99;\202;;=\205::<\5""99;::<;;=::<;;=\202::<\6;;=::<;;=SSU\204" \ + "\204\204\301\301\301\226\377\377\377\1\376\376\376\317\377\377\377\1" \ + "\376\376\376\203\377\377\377\1\376\376\376\204\377\377\377\1\376\376" \ + "\376\204\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\202" \ + "\377\377\377\3\316\316\316\221\221\221SSU\203::<\3;;=::<99;\204::<\1" \ + ";;=\203::<\2""99;;;=\202::<\1;;=\204::<\5""99;<<>::<kkk\264\264\264\203" \ + "\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\232\377\377\377\2\266\266\270__a\202::<\5;;=::<;;=::<99;\202;;=" \ + "\10::<;;=::<;;=::<;;=99;;;=\202::<\11;;=::<99;;;=::<;;=SSU\221\221\223" \ + "\331\331\331\211\377\377\377\1\376\376\376\204\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\376\376\376\324\377\377\377\1\376\376\376\202" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\212\377\377\377\1" \ + "\376\376\376\214\377\377\377\14\332\332\332\251\251\251``b::<;;=::<;" \ + ";=99;::<;;=::<;;=\202::<\3;;=99;;;=\203::<\1;;=\202::<\10;;=99;;;=::" \ + "<;;=SSU\250\250\252\363\363\363\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\231\377\377\377\2\265\265\265SSU\216::<\4;;=::<99;;;=\205::" \ + "<\10;;=SSU\222\222\224\332\332\334\377\377\377\376\376\376\377\377\377" \ + "\376\376\376\205\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\376\376\376\327\377\377\377\1\376\376\376\202" \ + "\377\377\377\1\376\376\376\206\377\377\377\1\376\376\376\207\377\377" \ + "\377\1\376\376\376\216\377\377\377\4\347\347\351\250\250\252``b::<\202" \ + ";;=\202::<\1;;=\203::<\1;;=\203::<\1;;=\202::<\3;;=::<;;=\202::<\6""9" \ + "9;;;=::<FFF\233\233\233\363\363\363\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\206\377\377\377\3\376\376\376\377\377\377\376\376\376\213" \ + "\377\377\377\4\363\363\365\234\234\236FFH;;=\206::<\2""99;;;=\204::<" \ + "\202;;=\2::<;;=\206::<\4FFH\204\204\206\333\333\333\376\376\376\264\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\327\377\377\377\4\346" \ + "\346\346\221\221\221SSS:::\202::<\1;;=\204::<\3;;=::<;;=\214::<\3GGI" \ + "\221\221\223\347\347\347\211\377\377\377\1\376\376\376\203\377\377\377" \ + "\1\376\376\376\377\377\377\377\377\377\377\377\371\377\377\377\1\376" \ + "\376\376\207\377\377\377\5\363\363\363\234\234\234FFH::<;;=\204::<\1" \ + ";;=\202::<\1;;=\203::<\1;;=\204::<\1;;=\203::<\5;;=xxz\300\300\302\377" \ + "\377\377\376\376\376\267\377\377\377\1\376\376\376\202\377\377\377\1" \ + "\376\376\376\215\377\377\377\1\376\376\376\303\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\204\377\377\377\4\332\332\332\203\203\205" \ + "GGI99;\207::<\202;;=\203::<\6;;=::<;;=::<;;=99;\202;;=\202::<\3\204\204" \ + "\204\346\346\346\376\376\376\205\377\377\377\1\376\376\376\377\377\377" \ + "\377\377\377\377\377\373\377\377\377\1\376\376\376\203\377\377\377\1" \ + "\376\376\376\204\377\377\377\3\362\362\362\234\234\236GGI\203::<\15;" \ + ";=::<;;=::<;;=::<;;=99;;;=::<;;=::<99;\202;;=\7::<;;=99;::<```\250\250" \ + "\250\363\363\363\202\377\377\377\1\375\375\375\272\377\377\377\1\376" \ + "\376\376\214\377\377\377\1\376\376\376\306\377\377\377\1\375\375\375" \ + "\210\377\377\377\6\265\265\265lln::<;;=::<;;=\202::<\5;;=99;;;=::<99" \ + ";\205::<\1;;=\206::<\4\204\204\206\345\345\345\377\377\377\376\376\376" \ + "\207\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\372\377" \ + "\377\377\1\376\376\376\202\377\377\377\3\364\364\364\233\233\235GGI\202" \ + "::<\203;;=\2""99;;;=\202::<\3""99;::<;;=\202::<\13;;=99;::<;;=::<;;=" \ + "::<FFH\204\204\204\333\333\333\376\376\376\204\377\377\377\1\376\376" \ + "\376\204\377\377\377\1\376\376\376\304\377\377\377\1\376\376\376\317" \ + "\377\377\377\4\346\346\346\221\221\223GGI99;\204::<\1""99;\202;;=\2:" \ + ":<;;=\204::<\1;;=\204::<\202;;=\3::<\221\221\223\364\364\364\203\377" \ + "\377\377\1\376\376\376\203\377\377\377\1\376\376\376\377\377\377\377" \ + "\377\377\377\377\371\377\377\377\1\376\376\376\202\377\377\377\6\265" \ + "\265\267SSU::<99;::<;;=\203::<\1;;=\202::<\1;;=\204::<\3;;=::<;;=\202" \ + "::<\6;;=SSS\264\264\264\363\363\363\377\377\377\376\376\376\204\377\377" \ + "\377\3\376\376\376\377\377\377\376\376\376\267\377\377\377\1\376\376" \ + "\376\221\377\377\377\1\376\376\376\307\377\377\377\1\376\376\376\207" \ + "\377\377\377\4\376\376\376\377\377\377\266\266\266kkm\202::<\1;;=\202" \ + "::<\6;;=::<99;;;=99;;;=\205::<\3;;=::<99;\202::<\4GGI\234\234\234\363" \ + "\363\363\376\376\376\377\377\377\377\377\377\377\377\375\377\377\377" \ + "\4\376\376\376\377\377\377\265\265\265SSU\202::<\1;;=\204::<\1;;=\203" \ + "::<\3;;=99;;;=\205::<\202;;=\2yyy\316\316\316\203\377\377\377\1\376\376" \ + "\376\206\377\377\377\3\376\376\376\377\377\377\376\376\376\263\377\377" \ + "\377\1\376\376\376\205\377\377\377\2\315\315\315;;;\211::<\3;;;:::\315" \ + "\315\315\202\377\377\377\1\376\376\376\312\377\377\377\3\376\376\376" \ + "\377\377\377\376\376\376\205\377\377\377\5\346\346\346\204\204\204FF" \ + "H::<;;=\202::<\4;;=::<;;=::<\203;;=\203::<\2<<>99;\202::<\4""99;;;=F" \ + "FF\234\234\234\377\377\377\377\377\377\377\377\375\377\377\377\11\316" \ + "\316\320kkm::<;;=::<;;=99;::<;;=\203::<\202;;=\2::<99;\205::<\13;;=F" \ + "FH\221\221\221\346\346\346\376\376\376\377\377\377\376\376\376\377\377" \ + "\377\376\376\376\377\377\377\376\376\376\204\377\377\377\1\376\376\376" \ + "\273\377\377\377\2\376\376\376\317\317\317\212::<\6;;=;;;\316\316\316" \ + "\376\376\376\377\377\377\376\376\376\304\377\377\377\1\376\376\376\206" \ + "\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376\376" \ + "\376\204\377\377\377\4\363\363\363\235\235\235RRT;;=\202::<\202;;=\7" \ + "::<;;=99;::<;;=::<;;=\203::<\1;;=\202::<\6;;=::<SSU\264\264\264\377\377" \ + "\377\376\376\376\377\377\377\377\377\377\377\377\367\377\377\377\3\346" \ + "\346\346xxz;;=\205::<\1;;=\203::<\3;;=::<;;=\207::<\3SSU\247\247\251" \ + "\363\363\363\217\377\377\377\1\376\376\376\272\377\377\377\1\316\316" \ + "\316\213::<\2;;=\316\316\316\306\377\377\377\3\376\376\376\377\377\377" \ + "\376\376\376\221\377\377\377\4\265\265\267SSU;;=99;\202::<\2""99;;;=" \ + "\206::<\1;;=\204::<\1;;=\202::<\3jjj\317\317\317\376\376\376\377\377" \ + "\377\377\377\377\377\377\343\377\377\377\1\376\376\376\211\377\377\377" \ + "\1\376\376\376\206\377\377\377\2\363\363\363\233\233\233\210::<\1;;=" \ + "\203::<\1;;=\203::<\1;;=\203::<\2SSS\265\265\265\315\377\377\377\1\316" \ + "\316\316\214::<\1\316\316\316\334\377\377\377\3\316\316\316kkk::<\202" \ + ";;=\206::<\1;;=\202::<\1;;=\202::<\7""99;;;=::<;;=::<\204\204\206\346" \ + "\346\350\377\377\377\377\377\377\377\377\347\377\377\377\1\376\376\376" \ + "\212\377\377\377\3\265\265\265SSS::<\202;;=\205::<\1;;=\202::<\202;;" \ + "=\202::<\1;;=\203::<\2lln\265\265\267\203\377\377\377\1\376\376\376\313" \ + "\377\377\377\1\316\316\316\214::<\1\316\316\316\336\377\377\377\6\316" \ + "\316\316kkm::<;;=::<;;=\202::<\3;;=::<;;=\204::<\10;;=99;;;=::<99;;;" \ + "=FFH\234\234\234\210\377\377\377\3\376\376\376\377\377\377\376\376\376" \ + "\377\377\377\377\377\377\377\377\327\377\377\377\2\376\376\376\377\377" \ + "\377\202\376\376\376\205\377\377\377\1\376\376\376\203\377\377\377\5" \ + "\332\332\332kkk;;=::<;;=\205::<\4;;=::<;;=::<\202;;=\2::<;;=\203::<\2" \ + "kkm\317\317\317\204\377\377\377\1\376\376\376\314\377\377\377\1\316\316" \ + "\316\214::<\1\316\316\316\336\377\377\377\14\376\376\376\377\377\377" \ + "\316\316\316\204\204\206;;=::<;;=::<;;=99;::<;;=\205::<\11;;=99;;;=9" \ + "9;::<;;;RRR\317\317\317\376\376\376\204\377\377\377\1\376\376\376\377" \ + "\377\377\377\377\377\377\377\332\377\377\377\202\376\376\376\211\377" \ + "\377\377\2\363\363\363\221\221\223\203::<\1;;=\207::<\1;;=\202::<\202" \ + ";;=\10::<99;::<lln\316\316\316\376\376\376\377\377\377\376\376\376\206" \ + "\377\377\377\1\376\376\376\311\377\377\377\1\316\316\316\214::<\1\316" \ + "\316\316\335\377\377\377\7\376\376\376\377\377\377\376\376\376\377\377" \ + "\377\376\376\376\347\347\347kkm\202::<\2""88:;;=\203::<\1;;=\204::<\3" \ + ";;=99;;;=\202::<\4;;=::<xxx\346\346\346\206\377\377\377\1\376\376\376" \ + "\377\377\377\377\377\377\377\377\331\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\203\377\377\377\4\376\376\376\377\377\377\300\300\302" \ + "SSU\207::<\1;;=\202::<\1;;=\205::<\4""99;;;=SSU\316\316\316\204\377\377" \ + "\377\1\376\376\376\205\377\377\377\1\376\376\376\202\377\377\377\1\376" \ + "\376\376\307\377\377\377\1\316\316\316\214::<\1\316\316\316\334\377\377" \ + "\377\1\376\376\376\202\377\377\377\1\376\376\376\204\377\377\377\3\317" \ + "\317\317kkm;;=\205::<\3;;=::<99;\203::<\1;;=\204::<\3;;=FFH\250\250\250" \ + "\205\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377" \ + "\377\377\377\377\326\377\377\377\1\376\376\376\204\377\377\377\4\376" \ + "\376\376\377\377\377\347\347\351xxz\202::<\1;;=\204::<\1;;=\203::<\1" \ + ";;=\204::<\4""99;;;=SSU\266\266\266\205\377\377\377\1\376\376\376\202" \ + "\377\377\377\1\376\376\376\205\377\377\377\1\375\375\375\310\377\377" \ + "\377\1\316\316\316\214::<\1\316\316\316\344\377\377\377\7\376\376\376" \ + "\377\377\377\316\316\316kkm;;=::<99;\202::<\203;;=\2::<;;=\204::<\1;" \ + ";=\202::<\3;;=__a\332\332\334\377\377\377\377\377\377\377\377\335\377" \ + "\377\377\1\376\376\376\204\377\377\377\4\250\250\252FFH::<;;=\202::<" \ + "\3;;=::<;;=\202::<\3""99;::<;;=\202::<\1;;=\202::<\4HHJ\250\250\250\377" \ + "\377\377\376\376\376\206\377\377\377\202\376\376\376\205\377\377\377" \ + "\1\376\376\376\311\377\377\377\1\316\316\316\214::<\1\316\316\316\345" \ + "\377\377\377\1\376\376\376\202\377\377\377\2\301\301\301SSU\202::<\1" \ + ";;=\202::<\2""99;;;=\212::<\3;;=\233\233\233\363\363\363\377\377\377" \ + "\377\377\377\377\377\331\377\377\377\1\376\376\376\204\377\377\377\2" \ + "\346\346\346kkk\211::<\3;;=99;;;=\206::<\2\235\235\237\363\363\363\205" \ + "\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\321\377\377" \ + "\377\1\316\316\316\214::<\1\316\316\316\352\377\377\377\2\250\250\252" \ + "GGI\206::<\5;;=::<;;=::<;;=\202::<\202;;=\4::<:::SSS\316\316\316\203" \ + "\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\330\377\377" \ + "\377\2\251\251\251FFH\203::<\1""99;\207::<\1;;=\204::<\3;;=xxx\346\346" \ + "\346\334\377\377\377\1\316\316\316\214::<\1\316\316\316\350\377\377\377" \ + "\13\376\376\376\377\377\377\376\376\376\363\363\363\234\234\23699;;;" \ + "=::<;;=99;;;=\202::<\2""99;;;=\206::<\202;;=\2\221\221\223\363\363\363" \ + "\204\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377" \ + "\1\376\376\376\377\377\377\377\377\377\377\377\316\377\377\377\2\346" \ + "\346\346kkk\202;;=\206::<\1;;=\203::<\3;;=::<;;=\202::<\2``b\316\316" \ + "\320\336\377\377\377\1\316\316\316\214::<\1\316\316\316\353\377\377\377" \ + "\4\376\376\376\377\377\377\350\350\352kkm\206::<\2;;=99;\203::<\1;;=" \ + "\203::<\6;;=::<TTV\331\331\331\377\377\377\376\376\376\207\377\377\377" \ + "\1\376\376\376\377\377\377\377\377\377\377\377\306\377\377\377\1\376" \ + "\376\376\203\377\377\377\5\376\376\376\377\377\377\266\266\266EEG;;=" \ + "\203::<\1;;=\203::<\1;;=\204::<\202;;=\3::<GGI\250\250\252\205\377\377" \ + "\377\1\376\376\376\202\377\377\377\1\376\376\376\327\377\377\377\1\316" \ + "\316\316\214::<\1\316\316\316\351\377\377\377\1\376\376\376\203\377\377" \ + "\377\5\376\376\376\377\377\377\316\316\316TTV;;=\203::<\3;;=::<;;=\204" \ + "::<\202;;=\5::<;;=99;;;=\234\234\236\207\377\377\377\1\376\376\376\377" \ + "\377\377\377\377\377\377\377\303\377\377\377\3\376\376\376\377\377\377" \ + "\376\376\376\203\377\377\377\6\376\376\376\377\377\377\364\364\364ww" \ + "y::<;;=\202::<\202;;=\202::<\5;;=::<99;::<;;=\202::<\4;;=::<\204\204" \ + "\206\363\363\363\202\377\377\377\1\376\376\376\202\377\377\377\3\376" \ + "\376\376\377\377\377\376\376\376\331\377\377\377\1\316\316\316\214::" \ + "<\1\316\316\316\353\377\377\377\1\376\376\376\204\377\377\377\11\376" \ + "\376\376\234\234\234GGI::<;;=::<;;=::<;;=\207::<\1;;=\202::<\2__a\332" \ + "\332\332\377\377\377\377\377\377\377\377\320\377\377\377\4\316\316\316" \ + "FFH::<;;=\202::<\1;;=\207::<\2;;=99;\202;;=\3__a\316\316\320\376\376" \ + "\376\342\377\377\377\1\316\316\316\214::<\1\316\316\316\361\377\377\377" \ + "\5\376\376\376\347\347\347lln::<;;=\210::<\1""99;\202::<\7;;=::<99;G" \ + "GI\247\247\247\377\377\377\376\376\376\202\377\377\377\1\376\376\376" \ + "\377\377\377\377\377\377\377\377\305\377\377\377\1\376\376\376\203\377" \ + "\377\377\3\221\221\221:::;;=\203::<\1;;=\202::<\1;;=\203::<\1;;=\202" \ + "::<\4;;=FFH\234\234\234\376\376\376\202\377\377\377\1\375\375\375\202" \ + "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\332\377\377" \ + "\377\1\316\316\316\214::<\1\316\316\316\364\377\377\377\3\301\301\303" \ + "FFH;;=\206::<\1;;=\205::<\5;;=99;;;=yy{\363\363\363\377\377\377\377\377" \ + "\377\377\377\312\377\377\377\3\346\346\346^^`;;=\207::<\1;;=\203::<\1" \ + ";;=\203::<\2jjl\346\346\350\202\377\377\377\1\376\376\376\213\377\377" \ + "\377\1\375\375\375\327\377\377\377\1\316\316\316\214::<\1\316\316\316" \ + "\360\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377" \ + "\2\363\363\363\220\220\220\202;;=\203::<\2;;=99;\206::<\1;;=\202::<\2" \ + "SSU\316\316\320\202\377\377\377\1\376\376\376\377\377\377\377\377\377" \ + "\377\377\303\377\377\377\4\376\376\376\377\377\377\302\302\302FFH\217" \ + "::<\2GGI\250\250\252\205\377\377\377\1\376\376\376\211\377\377\377\3" \ + "\376\376\376\377\377\377\376\376\376\326\377\377\377\1\316\316\316\214" \ + "::<\1\316\316\316\356\377\377\377\1\376\376\376\210\377\377\377\3\316" \ + "\316\316SSU;;=\203::<\202;;=\207::<\1;;=\202::<\1\235\235\237\377\377" \ + "\377\377\377\377\377\377\306\377\377\377\1\221\221\221\202::<\2;;=99" \ + ";\203::<\3;;=::<;;=\203::<\1;;=\202::<\2kkm\346\346\346\351\377\377\377" \ + "\1\316\316\316\214::<\1\316\316\316\370\377\377\377\2\362\362\362\221" \ + "\221\221\204::<\3;;=::<;;=\206::<\1;;=\202::<\2xxz\362\362\364\377\377" \ + "\377\377\377\377\377\377\301\377\377\377\3\376\376\376\363\363\363__" \ + "_\204::<\3;;=::<;;=\202::<\2;;=99;\202;;=\4::<99;GGI\250\250\252\353" \ + "\377\377\377\1\316\316\316\214::<\1\316\316\316\366\377\377\377\1\376" \ + "\376\376\203\377\377\377\2\317\317\317SSS\211::<\202;;=\6""99;;;=99;" \ + "::<SSU\332\332\332\202\377\377\377\1\376\376\376\377\377\377\377\377" \ + "\377\377\377\267\377\377\377\11\376\376\376\377\377\377\376\376\376\377" \ + "\377\377\376\376\376\377\377\377\317\317\321FFH;;=\202::<\3;;=::<99;" \ + "\203::<\203;;=\202::<\4;;=lll\346\346\346\376\376\376\353\377\377\377" \ + "\1\316\316\316\214::<\1\316\316\316\367\377\377\377\1\376\376\376\202" \ + "\377\377\377\5\376\376\376\363\363\363\221\221\223;;=99;\202;;=\3::<" \ + "99;;;=\202::<\202;;=\6::<;;=::<;;=::<\265\265\265\202\377\377\377\1\376" \ + "\376\376\377\377\377\377\377\377\377\377\273\377\377\377\1\250\250\252" \ + "\202::<\2""99;;;=\203::<\1;;=\202::<\1;;=\204::<\3;;=\250\250\250\376" \ + "\376\376\205\377\377\377\1\376\376\376\347\377\377\377\1\316\316\316" \ + "\214::<\1\316\316\316\373\377\377\377\5\376\376\376\377\377\377\300\300" \ + "\300FFH;;=\202::<\1;;=\202::<\3;;=::<;;=\202::<\2;;=::<\202;;=\4\205" \ + "\205\207\376\376\376\377\377\377\376\376\376\377\377\377\377\377\377" \ + "\377\377\267\377\377\377\3\376\376\376\364\364\364\205\205\207\202::" \ + "<\202;;=\15""99;;;=::<;;=::<;;=::<99;;;=99;;;=__a\331\331\331\357\377" \ + "\377\377\1\316\316\316\214::<\1\316\316\316\366\377\377\377\1\376\376" \ + "\376\203\377\377\377\1\376\376\376\203\377\377\377\2\363\363\363kkm\215" \ + "::<\4;;=99;__a\363\363\363\202\377\377\377\1\376\376\376\377\377\377" \ + "\377\377\377\377\377\265\377\377\377\4\347\347\351__a::<;;=\203::<\1" \ + ";;=\202::<\1;;=\203::<\1;;=\202::<\2\221\221\223\363\363\363\360\377" \ + "\377\377\1\316\316\316\214::<\1\316\316\316\364\377\377\377\1\376\376" \ + "\376\203\377\377\377\1\376\376\376\207\377\377\377\2\251\251\253;;=\203" \ + "::<\1;;=\203::<\1;;=\203::<\203;;=\3FFH\332\332\332\376\376\376\377\377" \ + "\377\377\377\377\377\377\265\377\377\377\4\331\331\331FFH::<;;=\203:" \ + ":<\1;;=\202::<\1;;=\205::<\2FFH\302\302\302\205\377\377\377\7\376\376" \ + "\376\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377\376" \ + "\376\376\346\377\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377" \ + "\377\202\377\377\377\2\332\332\332SSU\203::<\1;;=\203::<\12""99;;;=:" \ + ":<99;::<;;=99;;;=\266\266\266\376\376\376\377\377\377\377\377\377\377" \ + "\377\263\377\377\377\1\265\265\265\202::<\1;;=\205::<\202;;=\202::<\1" \ + ";;=\202::<\2__a\346\346\350\203\377\377\377\1\376\376\376\357\377\377" \ + "\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\203\377\377\377" \ + "\2\363\363\363\204\204\204\202::<\1;;=\203::<\1;;=\205::<\1;;=\202::" \ + "<\1\221\221\221\377\377\377\377\377\377\377\377\262\377\377\377\4\235" \ + "\235\237;;=::<;;=\203::<\1;;=\206::<\3;;=::<\222\222\222\202\377\377" \ + "\377\1\376\376\376\362\377\377\377\1\316\316\316\214::<\1\316\316\316" \ + "\377\377\377\377\205\377\377\377\3\265\265\265:::;;=\206::<\5;;=::<;" \ + ";=::<;;=\202::<\2\204\204\206\363\363\363\212\377\377\377\1\376\376\376" \ + "\377\377\377\377\377\377\377\377\236\377\377\377\1\376\376\376\202\377" \ + "\377\377\4\376\376\376\377\377\377\376\376\377\204\204\206\206::<\12" \ + ";;=::<;;=::<;;=::<;;=::<FFH\301\301\301\366\377\377\377\1\316\316\316" \ + "\214::<\1\316\316\316\377\377\377\377\206\377\377\377\4\333\333\333S" \ + "SU::<;;=\205::<\4;;=::<;;=::<\202;;=\3::<__a\364\364\364\202\377\377" \ + "\377\1\376\376\376\205\377\377\377\1\376\376\376\202\377\377\377\1\376" \ + "\376\376\377\377\377\377\377\377\377\377\236\377\377\377\4\376\376\376" \ + "\377\377\377\363\363\365__a\203::<\10""99;;;=::<;;=99;;;=99;;;=\203:" \ + ":<\2__a\332\332\332\203\377\377\377\1\376\376\376\363\377\377\377\1\316" \ + "\316\316\214::<\1\316\316\316\377\377\377\377\207\377\377\377\7\363\363" \ + "\363kkm;;=::<;;=::<;;=\204::<\202;;=\10""99;;;=::<SSU\332\332\332\376" \ + "\376\376\377\377\377\376\376\376\205\377\377\377\1\376\376\376\377\377" \ + "\377\377\377\377\377\377\236\377\377\377\1\376\376\376\202\377\377\377" \ + "\2\346\346\350__a\202::<\4;;=::<;;=99;\204::<\1;;=\203::<\3xxz\362\362" \ + "\362\377\377\377\202\376\376\376\365\377\377\377\1\316\316\316\214::" \ + "<\1\316\316\316\377\377\377\377\210\377\377\377\5\376\376\376\234\234" \ + "\234;;=::<;;=\202::<\14;;=::<;;=99;;;=::<;;=::<;;=FFH\332\332\332\376" \ + "\376\376\203\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376" \ + "\377\377\377\376\376\376\377\377\377\377\377\377\377\377\235\377\377" \ + "\377\4\332\332\332FFH::<;;=\205::<\1;;=\205::<\2;;=\234\234\234\372\377" \ + "\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\212\377\377" \ + "\377\2\300\300\300FFH\203::<\1""99;\202::<\2;;=99;\203::<\4;;=::<FFH" \ + "\266\266\266\205\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \ + "\376\377\377\377\377\377\377\377\377\235\377\377\377\3\332\332\332FF" \ + "H;;=\205::<\1;;=\202::<\1""99;\203::<\6FFH\301\301\301\377\377\377\376" \ + "\376\376\377\377\377\376\376\376\207\377\377\377\1\376\376\376\357\377" \ + "\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\211\377\377" \ + "\377\4\376\376\376\377\377\377\331\331\331SSU\204::<\6""99;::<;;=::<" \ + ";;=::<\202;;=\202::<\1\266\266\270\203\377\377\377\1\376\376\376\377" \ + "\377\377\377\377\377\377\377\240\377\377\377\2\265\265\265EEG\202::<" \ + "\6;;=::<;;=::<;;=99;\203::<\4;;=::<SSU\332\332\332\203\377\377\377\1" \ + "\376\376\376\207\377\377\377\1\376\376\376\360\377\377\377\1\316\316" \ + "\316\214::<\1\316\316\316\377\377\377\377\212\377\377\377\15\376\376" \ + "\376\377\377\377\363\363\363__a::<;;=99;;;=::<99;;;=::<;;=\202::<\4;" \ + ";=99;;;=\250\250\252\204\377\377\377\1\376\376\376\377\377\377\377\377" \ + "\377\377\377\235\377\377\377\5\265\265\265::<;;=::<;;=\202::<\202;;=" \ + "\2::<;;=\204::<\2__a\364\364\364\206\377\377\377\1\376\376\376\366\377" \ + "\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\211\377\377" \ + "\377\1\376\376\376\204\377\377\377\2\204\204\20699;\204::<\1;;=\204:" \ + ":<\5""99;;;=99;::<\204\204\204\377\377\377\377\377\377\377\377\232\377" \ + "\377\377\1\376\376\376\205\377\377\377\2\265\265\267;;=\211::<\1;;=\203" \ + "::<\1\205\205\205\377\377\377\377\1\316\316\316\214::<\1\316\316\316" \ + "\377\377\377\377\215\377\377\377\12\376\376\376\377\377\377\250\250\250" \ + "::<;;=::<99;;;=::<;;=\202::<\3;;=::<99;\202::<\1\205\205\207\212\377" \ + "\377\377\1\376\376\376\377\377\377\377\377\377\377\377\223\377\377\377" \ + "\1\265\265\267\203::<\202;;=\1""99;\204::<\5;;=::<;;=::<\235\235\237" \ + "\377\377\377\377\2\377\377\377\316\316\316\214::<\1\316\316\316\377\377" \ + "\377\377\216\377\377\377\3\376\376\376\377\377\377\265\265\267\202::" \ + "<\3;;=::<;;=\205::<\1;;=\203::<\1\204\204\204\210\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\220" \ + "\377\377\377\6\234\234\236::<;;=::<;;=99;\204::<\1;;=\204::<\1\265\265" \ + "\265\377\377\377\377\202\377\377\377\1\316\316\316\214::<\1\316\316\316" \ + "\377\377\377\377\215\377\377\377\1\376\376\376\203\377\377\377\2\334" \ + "\334\334FFH\207::<\202;;=\203::<\3;;=\204\204\206\376\376\376\207\377" \ + "\377\377\1\376\376\376\377\377\377\377\377\377\377\377\216\377\377\377" \ + "\11\376\376\376\377\377\377\376\376\376\204\204\206::<99;;;=::<;;=\204" \ + "::<\6;;=99;;;=::<FFH\301\301\301\377\377\377\377\203\377\377\377\1\316" \ + "\316\316\214::<\1\316\316\316\377\377\377\377\215\377\377\377\1\376\376" \ + "\376\202\377\377\377\202\376\376\376\3\332\332\332FFH::<\202;;=\203:" \ + ":<\3;;=99;;;=\204::<\2\205\205\207\376\376\376\203\377\377\377\1\376" \ + "\376\376\203\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377" \ + "\377\377\377\377\377\377\212\377\377\377\7\376\376\376\377\377\377\376" \ + "\376\376\204\204\20499;::<;;=\202::<\1""99;\205::<\4;;=::<GGI\332\332" \ + "\334\377\377\377\377\204\377\377\377\1\316\316\316\214::<\1\316\316\316" \ + "\377\377\377\377\217\377\377\377\6\376\376\376\377\377\377\376\376\376" \ + "\377\377\377\362\362\362__a\203::<\202;;=\11""99;;;=::<99;;;=::<;;=:" \ + ":<\204\204\204\205\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \ + "\376\377\377\377\377\377\377\377\377\215\377\377\377\1\204\204\204\202" \ + "::<\1;;=\207::<\1<<>\202::<\2FFH\331\331\333\377\377\377\377\205\377" \ + "\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\216\377\377" \ + "\377\1\376\376\376\203\377\377\377\4\376\376\376\377\377\377\363\363" \ + "\363__a\204::<\2;;=99;\206::<\2;;=\204\204\204\203\377\377\377\1\376" \ + "\376\376\377\377\377\377\377\377\377\377\220\377\377\377\1\204\204\204" \ + "\205::<\1;;=\203::<\1;;=\203::<\4__a\363\363\363\377\377\377\376\376" \ + "\376\377\377\377\377\204\377\377\377\1\316\316\316\214::<\1\316\316\316" \ + "\377\377\377\377\224\377\377\377\4\376\376\376\363\363\363xxx::<\202" \ + ";;=\202::<\1;;=\203::<\1;;=\203::<\1\205\205\207\204\377\377\377\1\376" \ + "\376\376\377\377\377\377\377\377\377\377\215\377\377\377\1\250\250\250" \ + "\205::<\1;;=\203::<\12;;=99;;;=::<__a\363\363\365\377\377\377\376\376" \ + "\376\377\377\377\376\376\376\377\377\377\377\203\377\377\377\1\316\316" \ + "\316\214::<\1\316\316\316\377\377\377\377\227\377\377\377\5\204\204\204" \ + "::<;;=::<;;=\204::<\1""99;\204::<\1\204\204\204\377\377\377\377\377\377" \ + "\377\377\213\377\377\377\1\376\376\376\202\377\377\377\4\376\376\376" \ + "\377\377\377\265\265\267;;=\212::<\4;;=::<__a\363\363\363\217\377\377" \ + "\377\1\376\376\376\367\377\377\377\1\316\316\316\214::<\1\316\316\316" \ + "\376\377\377\377\202\377\377\375\3\377\376\377\377\377\377\376\377\375" \ + "\224\377\377\377\3\204\204\206::<;;=\211::<\7""99;::<\203\203\205\377" \ + "\377\377\376\376\376\377\377\377\376\376\376\205\377\377\377\1\376\376" \ + "\376\202\377\377\377\202\376\376\376\377\377\377\377\377\377\377\377" \ + "\2\264\264\266;;=\202::<\202;;=\1""99;\207::<\2__a\363\363\365\217\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\366\377\377\377\1\316" \ + "\316\316\214::<\1\316\316\316\375\377\377\377\5\377\377\375\377\376\377" \ + "\377\375\377\377\377\375\377\377\377\202\377\376\377\221\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\204\204\206\203::<\1;;=\202::<\2;;=" \ + "::<\202;;=\202::<\3;;=\204\204\204\376\376\376\211\377\377\377\3\376" \ + "\376\376\377\377\377\376\376\376\377\377\377\377\375\377\377\377\7\376" \ + "\376\376\264\264\266;;=99;::<;;=99;\204::<\1;;=\203::<\2aac\363\363\363" \ + "\221\377\377\377\1\376\376\376\367\377\377\377\1\316\316\316\214::<\1" \ + "\316\316\316\375\377\377\377\202\376\376\376\203\377\377\377\202\376" \ + "\377\377\222\377\377\377\10\376\376\376\377\377\377\376\376\376\204\204" \ + "\206::<;;=::<;;=\203::<\202;;=\202::<\6""99;;;=\205\205\207\376\376\376" \ + "\377\377\377\376\376\376\203\377\377\377\202\376\376\376\202\377\377" \ + "\377\1\376\376\376\377\377\377\377\375\377\377\377\3\376\376\376\302" \ + "\302\304;;=\203::<\1;;=\204::<\6;;=99;;;=::<aac\362\362\362\223\377\377" \ + "\377\1\376\376\376\366\377\377\377\1\316\316\316\214::<\1\316\316\316" \ + "\374\377\377\377\6\375\377\376\377\377\375\377\376\377\376\377\377\376" \ + "\376\376\377\377\375\202\377\376\377\225\377\377\377\2\376\376\376\204" \ + "\204\206\206::<\1""99;\203::<\1;;=\202::<\1\251\251\253\204\377\377\377" \ + "\1\376\376\376\377\377\377\377\377\377\377\377\203\377\377\377\4\332" \ + "\332\332FFH::<;;=\202::<\1""99;\205::<\4;;=::<__a\363\363\365\202\377" \ + "\377\377\1\376\376\376\377\377\377\377\211\377\377\377\1\316\316\316" \ + "\214::<\1\316\316\316\374\377\377\377\5\376\377\377\376\376\376\377\376" \ + "\377\377\377\375\376\377\375\202\376\377\377\1\377\377\375\221\377\377" \ + "\377\3\376\376\376\377\377\377\376\376\376\203\377\377\377\2\204\204" \ + "\206;;=\205::<\1;;=\203::<\7;;=::<;;=\265\265\265\376\376\376\377\377" \ + "\377\376\376\376\202\377\377\377\5\376\376\376\377\377\377\376\376\376" \ + "\377\377\377\376\376\376\377\377\377\377\373\377\377\377\6\331\331\331" \ + "GGI::<;;=::<;;=\205::<\1<<>\202::<\2__a\363\363\365\202\377\377\377\1" \ + "\376\376\376\213\377\377\377\1\376\376\376\375\377\377\377\1\316\316" \ + "\316\214::<\1\316\316\316\374\377\377\377\7\377\376\377\376\377\377\376" \ + "\376\374\377\376\377\377\377\375\376\377\377\377\377\375\226\377\377" \ + "\377\1\376\376\376\202\377\377\377\1\203\203\203\214::<\2;;=\265\265" \ + "\265\206\377\377\377\1\376\376\376\377\377\377\377\374\377\377\377\4" \ + "\364\364\364GGI99;;;=\206::<\1;;=\203::<\2__a\363\363\363\205\377\377" \ + "\377\1\376\376\376\212\377\377\377\1\363\363\363\203\377\377\377\1\376" \ + "\376\376\370\377\377\377\1\316\316\316\214::<\1\316\316\316\374\377\377" \ + "\377\10\377\377\375\377\376\377\377\377\377\377\377\375\377\376\377\370" \ + "\373\362\370\373\364\377\376\377\220\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\204\204\204\203::<\1;;=\210::<\2FFH\332\332\334\204\377\377\377\1" \ + "\376\376\376\377\377\377\377\374\377\377\377\3\363\363\363___;;=\202" \ + "::<\1;;=\204::<\6;;=99;;;=::<__a\363\363\365\220\377\377\377\3\265\265" \ + "\265FFF\333\333\333\373\377\377\377\1\316\316\316\214::<\1\316\316\316" \ + "\376\377\377\377\6\374\377\377\377\377\375\371\374\365\242\320c\240\322" \ + "c\371\372\362\221\377\377\377\1\376\376\376\210\377\377\377\2\203\203" \ + "\203;;=\202::<\1;;=\203::<\1;;=\203::<\3;;=FFH\333\333\333\202\377\377" \ + "\377\1\376\376\376\377\377\377\377\371\377\377\377\1\376\376\376\203" \ + "\377\377\377\2kkm::<\202;;=\1""99;\205::<\202;;=\3::<__a\363\363\363" \ + "\220\377\377\377\5\265\265\267::<;;=FFH\332\332\332\206\377\377\377\3" \ + "\376\376\376\377\377\377\376\376\376\361\377\377\377\1\316\316\316\213" \ + "::<\2;;=\316\316\316\365\377\377\377\22\376\376\377\377\377\375\377\377" \ + "\377\377\377\375\377\377\377\377\376\377\377\377\375\377\377\377\376" \ + "\376\377\377\377\377\371\374\365\242\320c\215\307\77\215\305@\242\322" \ + "e\372\373\365\376\377\375\377\376\377\230\377\377\377\3\205\205\207:" \ + ":<;;=\206::<\1;;=\202::<\4;;=SSU\363\363\365\376\376\376\377\377\377" \ + "\377\374\377\377\377\13\376\376\376\204\204\204::<;;=99;::<;;=::<;;=" \ + "::<;;=\203::<\3__a\364\364\366\376\376\376\217\377\377\377\1\265\265" \ + "\267\203::<\3;;=FFF\332\332\332\206\377\377\377\1\376\376\376\361\377" \ + "\377\377\2\376\376\376\317\317\317\212::<\6;;=;;;\316\316\316\376\376" \ + "\376\377\377\377\376\376\376\361\377\377\377\6\376\376\377\377\376\377" \ + "\375\376\377\376\377\377\377\377\375\375\377\376\202\377\377\377\17\376" \ + "\376\376\377\377\377\371\372\364\240\322a\215\305@\212\307>\215\307\77" \ + "\215\305>\242\320c\370\372\365\377\377\377\377\376\377\376\377\375\377" \ + "\377\375\377\376\377\225\377\377\377\5kkm::<;;=99;;;=\210::<\4__a\364" \ + "\364\364\376\376\376\377\377\377\202\376\376\376\377\377\377\377\363" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\4" \ + "\250\250\252::<;;=99;\202;;=\205::<\202;;=\3FFH\345\345\345\376\376\376" \ + "\217\377\377\377\4\264\264\266;;=::<;;=\203::<\2GGI\332\332\332\203\377" \ + "\377\377\1\376\376\376\356\377\377\377\1\376\376\376\205\377\377\377" \ + "\2\315\315\315;;;\211::<\3;;;:::\315\315\315\202\377\377\377\1\376\376" \ + "\376\361\377\377\377\23\377\377\375\375\376\377\376\377\377\376\377\375" \ + "\377\374\377\377\377\375\375\377\376\377\377\377\377\377\375\371\372" \ + "\364\242\321g\215\306A\212\307>\215\306A\212\306@\214\305@\212\306B\241" \ + "\322_\367\372\361\204\377\377\377\1\377\377\375\220\377\377\377\1\376" \ + "\376\376\203\377\377\377\3\363\363\363__a99;\202::<\6;;=::<99;;;=99;" \ + ";;=\203::<\1\205\205\207\204\377\377\377\1\376\376\376\377\377\377\377" \ + "\362\377\377\377\1\376\376\376\202\377\377\377\22\376\376\376\265\265" \ + "\267::<99;;;=::<;;=99;;;=::<;;=::<;;=::<FFH\331\331\331\377\377\377\376" \ + "\376\376\216\377\377\377\1\265\265\267\203::<\1;;=\202::<\4;;=::<GGI" \ + "\332\332\332\210\377\377\377\1\376\376\376\353\377\377\377\1\376\376" \ + "\376\221\377\377\377\1\376\376\376\363\377\377\377\17\376\377\377\376" \ + "\377\375\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377" \ + "\367\374\365\240\320b\215\307=\213\305=\215\306A\215\305>\214\305@\214" \ + "\306>\202\214\305@\4\241\321a\371\374\365\376\376\377\377\377\375\202" \ + "\376\377\377\221\377\377\377\1\376\376\376\203\377\377\377\3\362\362" \ + "\362``b99;\205::<\1;;=\203::<\6;;=99;\235\235\237\376\376\376\377\377" \ + "\377\376\376\376\377\377\377\377\366\377\377\377\2\332\332\332FFH\202" \ + ";;=\4""99;;;=::<;;=\205::<\2FFH\332\332\334\202\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\213\377\377\377\4\266\266\26699;::<;;=\202" \ + "::<\1;;=\202::<\4;;=::<FFF\332\332\332\203\377\377\377\1\376\376\376" \ + "\202\377\377\377\1\376\376\376\375\377\377\377\1\376\376\376\363\377" \ + "\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202\377" \ + "\377\377\21\370\373\364\241\321c\216\306\77\212\306@\214\306>\215\305" \ + "@\212\306@\213\310=\214\306<\216\306\77\214\304=\214\306>\241\321c\372" \ + "\375\362\376\376\376\377\376\377\376\376\374\220\377\377\377\2\376\376" \ + "\376\377\377\377\203\376\376\376\4\377\377\377\364\364\364FFH;;=\202" \ + "::<\1;;=\202::<\1;;=\203::<\3;;=::<\265\265\265\377\377\377\377\367\377" \ + "\377\377\4\362\362\362SSU::<;;=\205::<\1""99;\202;;=\3::<;;=\265\265" \ + "\267\216\377\377\377\3\376\376\376\377\377\377\265\265\265\202::<\5;" \ + ";=99;;;=::<;;=\204::<\4;;=FFH\332\332\332\376\376\376\205\377\377\377" \ + "\1\376\376\376\355\377\377\377\1\376\376\376\214\377\377\377\1\376\376" \ + "\376\366\377\377\377\1\375\377\376\202\377\377\375\24\377\377\377\376" \ + "\376\376\373\373\363\243\322b\213\307A\214\306>\215\305@\214\305@\212" \ + "\307>\214\306>\215\305>\213\307A\214\305@\216\310@\214\306>\215\305>" \ + "\242\320c\366\373\364\375\377\376\377\376\377\221\377\377\377\1\376\376" \ + "\376\204\377\377\377\3\376\376\376\333\333\333EEG\202;;=\2::<;;=\207" \ + "::<\3GGI\332\332\332\376\376\376\377\377\377\377\365\377\377\377\1__" \ + "a\205::<\10;;=::<;;=::<;;=::<;;=\265\265\265\202\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\213\377\377\377\1\266\266\266\203::<\5""9" \ + "9;<<>::<;;=::<\202;;=\203::<\4;;=FFH\333\333\333\376\376\376\202\377" \ + "\377\377\1\376\376\376\355\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\376\376\376\215\377\377\377\1\376\376\376\363\377\377\377\3\377\376" \ + "\377\377\377\377\375\377\376\202\377\377\377\2\373\373\363\241\321d\202" \ + "\214\306>\17\216\306=\215\305@\215\307\77\214\306>\217\304>\214\306>" \ + "\214\305B\215\307\77\211\305A\215\306A\216\306\77\214\305@\242\322e\370" \ + "\373\364\377\377\375\230\377\377\377\1\333\333\335\203::<\202;;=\206" \ + "::<\3;;=FFH\363\363\363\377\377\377\377\364\377\377\377\1\204\204\206" \ + "\203::<\1;;=\207::<\2;;=\204\204\206\220\377\377\377\1\346\346\346\204" \ + "::<\1;;=\203::<\1;;=\202::<\202;;=\203::<\2FFH\332\332\332\357\377\377" \ + "\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377\204\377\377" \ + "\377\1\377\377\375\202\377\377\377\17\377\376\377\370\373\364\243\322" \ + "b\214\306>\213\310\77\212\307>\214\306>\215\306C\212\307>\214\306<\213" \ + "\310\77\214\305@\214\306<\214\306>\216\306\77\203\214\306>\3\214\306" \ + "<\265\334\211\376\376\376\222\377\377\377\1\376\376\376\205\377\377\377" \ + "\4\376\376\377\265\265\267::<;;=\212::<\1___\377\377\377\377\363\377" \ + "\377\377\1\265\265\267\204::<\1;;=\206::<\2;;=\203\203\203\222\377\377" \ + "\377\2\265\265\265;;=\203::<\1;;=\205::<\1;;=\204::<\3;;=FFH\332\332" \ + "\332\206\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377" \ + "\377\345\377\377\377\10\376\376\377\377\377\375\377\377\377\377\377\375" \ + "\377\377\377\377\376\377\377\377\375\376\377\377\202\377\377\377\6\370" \ + "\373\362\243\322b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4" \ + "\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306" \ + ">\215\307\77\214\305@\244\317c\367\375\361\233\377\377\377\3\234\234" \ + "\236::<99;\211::<\2;;=\204\204\206\377\377\377\377\360\377\377\377\13" \ + "\376\376\376\332\332\33299;::<99;;;=::<99;;;=::<;;=\202::<\3;;=^^`\364" \ + "\364\364\223\377\377\377\12\265\265\267;;=::<;;=99;;;=::<;;=::<;;=\202" \ + "::<\1;;=\203::<\3;;=FFF\332\332\332\206\377\377\377\1\376\376\376\377" \ + "\377\377\377\345\377\377\377\6\376\376\377\377\376\377\375\376\377\376" \ + "\377\377\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373" \ + "\366\241\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212" \ + "\306@\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306" \ + ">\215\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\233" \ + "\377\377\377\1\204\204\206\203::<\13;;=::<;;=::<;;=::<;;=::<;;=\266\266" \ + "\266\376\376\376\203\377\377\377\1\376\376\376\377\377\377\377\352\377" \ + "\377\377\2\363\363\363TTV\202::<\3;;=99;;;=\204::<\4;;=99;FFH\363\363" \ + "\363\224\377\377\377\7\376\376\376\265\265\265;;=::<;;=::<;;=\203::<" \ + "\1;;=\203::<\1;;=\203::<\2GGI\332\332\332\203\377\377\377\1\376\376\376" \ + "\377\377\377\377\347\377\377\377\7\377\377\375\375\376\377\376\377\377" \ + "\376\377\375\377\374\377\377\377\375\375\377\376\202\377\377\377\5\372" \ + "\373\366\240\320b\215\307\77\212\306@\215\305>\202\214\305@\20\215\305" \ + "@\212\306@\214\305D\216\306\77\214\306>\215\307\77\214\306>\212\306@" \ + "\214\306>\215\307\77\215\305@\242\320c\370\373\362\377\377\373\377\376" \ + "\377\377\377\375\232\377\377\377\3\376\376\376\377\377\377^^`\202;;=" \ + "\205::<\1""99;\202;;=\5::<;;=\332\332\332\377\377\377\376\376\376\377" \ + "\377\377\377\347\377\377\377\1\376\376\376\204\377\377\377\1lln\204:" \ + ":<\202;;=\203::<\6;;=99;GGI\332\332\332\377\377\377\376\376\376\225\377" \ + "\377\377\2\264\264\264;;=\202::<\2""99;;;=\202::<\3""99;;;=::<\202;;" \ + "=\202::<\4;;=::<GGI\332\332\332\210\377\377\377\1\376\376\376\377\377" \ + "\377\377\342\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377" \ + "\376\377\377\375\377\377\377\377\376\377\370\373\362\241\321a\215\307" \ + "\77\215\307=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216" \ + "\306\77\215\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306" \ + ">\242\321a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377" \ + "\234\377\377\377\2\364\364\364RRT\202::<\4""99;;;=::<;;=\205::<\3SSU" \ + "\362\362\362\377\377\377\202\376\376\376\377\377\377\377\351\377\377" \ + "\377\1\234\234\236\204::<\1;;=\203::<\1;;=\203::<\1\265\265\267\231\377" \ + "\377\377\2\265\265\267;;=\203::<\2""99;;;=\202::<\1;;=\202::<\1;;=\202" \ + "::<\4;;=::<FFF\332\332\332\203\377\377\377\1\376\376\376\202\377\377" \ + "\377\1\376\376\376\377\377\377\377\342\377\377\377\202\377\377\375\3" \ + "\377\374\377\375\377\376\376\377\377\202\377\377\377\25\370\373\364\243" \ + "\322b\217\304@\212\306@\214\305@\215\305>\212\307>\212\306@\214\305B" \ + "\214\305@\214\305B\214\306>\212\307>\212\310\77\214\306>\217\304@\214" \ + "\306>\214\305@\242\322b\370\373\362\377\377\377\202\377\376\377\1\377" \ + "\377\375\235\377\377\377\3\376\376\376\332\332\334GGI\202;;=\6::<;;=" \ + "99;;;=::<;;=\203::<\1yyy\202\376\376\376\202\377\377\377\1\376\376\376" \ + "\377\377\377\377\345\377\377\377\4\376\376\376\317\317\317::<;;=\202" \ + "::<\3;;=99;;;=\204::<\6;;=\221\221\223\377\377\377\376\376\376\377\377" \ + "\377\376\376\376\226\377\377\377\3\376\376\376\265\265\267;;=\202::<" \ + "\2;;=99;\205::<\1;;=\204::<\4;;=FFH\332\332\332\376\376\376\205\377\377" \ + "\377\1\376\376\376\377\377\377\377\342\377\377\377\1\375\377\376\202" \ + "\377\377\375\34\377\377\377\376\376\376\373\373\363\243\322b\211\307" \ + "B\212\307<\215\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214" \ + "\306<\214\306>\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307" \ + ">\244\317c\370\373\362\377\377\373\376\377\377\377\376\377\375\376\377" \ + "\377\377\375\377\376\377\236\377\377\377\4\265\265\267::<;;=99;\202;" \ + ";=\205::<\202;;=\1\250\250\250\202\377\377\377\1\376\376\376\377\377" \ + "\377\377\343\377\377\377\1\376\376\376\202\377\377\377\3\363\363\363" \ + "FFH;;=\202::<\5;;=::<;;=::<99;\202;;=\2::<kkm\205\377\377\377\1\376\376" \ + "\376\227\377\377\377\1\265\265\265\204::<\6;;=::<;;=::<;;=::<\202;;=" \ + "\203::<\4;;=FFH\333\333\333\376\376\376\202\377\377\377\1\376\376\376" \ + "\377\377\377\377\343\377\377\377\3\377\376\377\377\377\377\375\377\376" \ + "\202\377\377\377\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214" \ + "\305@\213\310=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214" \ + "\306>\215\305>\217\304@\215\307\77\215\307=\242\320c\367\375\361\376" \ + "\376\377\377\376\377\376\376\376\202\377\377\375\2\374\377\377\377\376" \ + "\377\234\377\377\377\1\376\376\376\202\377\377\377\10\221\221\221::<" \ + ";;=99;::<;;=::<;;=\205::<\2\333\333\333\376\376\376\377\377\377\377\347" \ + "\377\377\377\1kkk\202::<\1;;=\205::<\1;;=\202::<\2RRT\363\363\365\236" \ + "\377\377\377\1\265\265\267\203::<\2""99;;;=\203::<\1;;=\202::<\202;;" \ + "=\203::<\2FFH\332\332\332\377\377\377\377\346\377\377\377\1\377\377\375" \ + "\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306>\213\310" \ + "\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215\307=\214" \ + "\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<\244\317c" \ + "\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377\377\377" \ + "\377\202\377\376\377\241\377\377\377\2kkm::<\202;;=\1""99;\204::<\203" \ + ";;=\2SSU\364\364\364\377\377\377\377\336\377\377\377\3\376\376\376\377" \ + "\377\377\376\376\376\204\377\377\377\2\376\376\376\250\250\252\202::" \ + "<\1;;=\210::<\2FFH\333\333\333\202\377\377\377\1\376\376\376\235\377" \ + "\377\377\2\265\265\265;;=\203::<\1;;=\205::<\1;;=\204::<\3;;=FFH\332" \ + "\332\332\206\377\377\377\3\376\376\376\377\377\377\376\376\376\243\377" \ + "\377\377\4\376\377\377\377\377\375\377\376\377\376\376\377\202\377\377" \ + "\377\2\376\377\375\376\377\377\230\377\377\377\10\376\377\377\377\376" \ + "\377\376\377\377\376\377\375\376\376\376\376\377\377\377\377\377\377" \ + "\376\377\231\377\377\377\7\377\376\377\376\376\374\376\377\377\377\377" \ + "\375\374\377\377\376\377\377\377\376\377\231\377\377\377\17\375\377\374" \ + "\377\377\375\377\377\377\377\376\377\376\377\377\377\376\377\377\377" \ + "\377\376\377\377\376\376\374\377\377\377\377\377\373\377\377\377\376" \ + "\377\377\377\377\377\377\377\375\220\377\377\377\4\377\377\373\377\377" \ + "\377\377\377\375\377\377\377\202\376\377\377\2\377\377\375\377\377\373" \ + "\251\377\377\377\10\376\376\377\377\377\375\377\377\377\377\377\375\377" \ + "\377\377\377\376\377\377\377\375\376\377\377\202\377\377\377\6\370\373" \ + "\362\243\322b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4\214" \ + "\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306>\215" \ + "\307\77\214\305@\244\317c\367\375\361\251\377\377\377\6\363\363\363T" \ + "TT::<;;=::<;;=\206::<\2;;=www\204\377\377\377\1\376\376\376\377\377\377" \ + "\377\340\377\377\377\2\332\332\332;;=\203::<\3;;=99;;;=\203::<\3;;=:" \ + ":<\265\265\267\204\377\377\377\1\376\376\376\235\377\377\377\12\265\265" \ + "\267;;=::<;;=99;;;=::<;;=::<;;=\202::<\1;;=\203::<\3;;=FFF\332\332\332" \ + "\206\377\377\377\1\376\376\376\244\377\377\377\202\377\377\375\1\377" \ + "\377\377\202\376\377\375\3\376\376\377\377\377\377\377\376\377\230\377" \ + "\377\377\3\376\377\375\377\377\377\377\377\373\202\377\376\377\2\377" \ + "\377\377\376\376\376\231\377\377\377\10\376\377\373\376\375\377\377\377" \ + "\375\377\376\377\377\375\377\377\377\373\377\376\377\377\377\375\230" \ + "\377\377\377\12\377\376\377\377\377\377\377\375\376\376\377\377\376\377" \ + "\372\376\377\377\377\377\377\376\377\375\377\376\377\377\377\375\203" \ + "\377\377\377\202\376\377\375\1\375\376\377\227\377\377\377\1\377\374" \ + "\377\250\377\377\377\6\376\376\377\377\376\377\375\376\377\376\377\377" \ + "\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373\366\241" \ + "\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306@" \ + "\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215" \ + "\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\251\377" \ + "\377\377\2\331\331\331;;=\206::<\1;;=\203::<\2;;=\265\265\265\204\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377" \ + "\322\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\202\377\377\377\2\363\363\363SSU\203::<\2;;=::<\202" \ + ";;=\2""99;;;=\202::<\1\204\204\204\206\377\377\377\1\376\376\376\234" \ + "\377\377\377\7\376\376\376\265\265\265;;=::<;;=::<;;=\203::<\1;;=\203" \ + "::<\1;;=\203::<\2GGI\332\332\332\203\377\377\377\1\376\376\376\247\377" \ + "\377\377\1\377\377\375\202\377\376\377\1\377\375\377\202\377\377\377" \ + "\1\377\376\377\232\377\377\377\6\377\377\375\377\377\377\375\377\376" \ + "\376\377\375\377\377\375\377\375\377\230\377\377\377\202\377\377\375" \ + "\2\377\377\377\376\376\376\202\377\377\377\2\376\377\377\374\377\377" \ + "\230\377\377\377\1\377\377\375\202\377\376\377\1\375\376\377\203\377" \ + "\377\377\1\377\377\375\202\377\377\377\6\376\376\377\377\377\375\377" \ + "\377\377\377\375\377\377\376\377\377\377\375\220\377\377\377\1\376\377" \ + "\377\202\377\377\377\3\376\377\375\376\376\376\377\376\377\252\377\377" \ + "\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374\377\377" \ + "\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215\307\77" \ + "\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D\216\306" \ + "\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77\215\305" \ + "@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\252\377\377" \ + "\377\2\250\250\25099;\204::<\12;;=99;::<;;=99;::<FFH\346\346\346\377" \ + "\377\377\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377\330" \ + "\377\377\377\1\376\376\376\204\377\377\377\3\221\221\221::<;;=\202::" \ + "<\5;;=::<;;=::<;;=\202::<\4___\363\363\363\377\377\377\376\376\376\202" \ + "\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376\376" \ + "\376\234\377\377\377\2\264\264\264;;=\202::<\2""99;;;=\202::<\3""99;" \ + ";;=::<\202;;=\202::<\4;;=::<GGI\332\332\332\210\377\377\377\1\376\376" \ + "\376\241\377\377\377\7\376\377\377\376\376\377\377\377\377\377\377\375" \ + "\376\377\375\375\377\376\376\377\377\230\377\377\377\3\376\376\377\376" \ + "\377\377\376\376\377\203\377\377\377\1\376\376\374\231\377\377\377\1" \ + "\377\376\377\202\377\377\377\202\376\377\377\1\376\376\376\232\377\377" \ + "\377\11\376\377\377\376\376\376\377\377\377\376\377\377\377\377\377\377" \ + "\377\375\376\377\377\376\376\377\376\377\377\202\377\377\377\5\377\377" \ + "\375\377\377\377\377\376\377\377\377\377\376\377\377\220\377\377\377" \ + "\10\376\376\377\377\376\377\377\377\377\376\376\376\377\376\377\377\377" \ + "\375\377\376\377\377\377\375\251\377\377\377\37\376\377\377\376\377\375" \ + "\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377\370\373" \ + "\362\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<\214\306" \ + ">\214\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215\305>\212" \ + "\307>\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376\377\377" \ + "\376\376\376\376\377\377\253\377\377\377\1yyy\205::<\3;;=::<99;\202;" \ + ";=\3::<__a\376\376\376\377\377\377\377\335\377\377\377\1\376\376\376" \ + "\202\377\377\377\5\301\301\301::<;;=99;;;=\207::<\2GGI\332\332\332\203" \ + "\377\377\377\1\376\376\376\243\377\377\377\2\265\265\267;;=\203::<\2" \ + "99;;;=\202::<\1;;=\202::<\1;;=\202::<\4;;=::<FFF\332\332\332\203\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\242\377\377\377" \ + "\1\377\377\375\204\377\377\377\1\376\377\377\231\377\377\377\202\377" \ + "\376\377\202\377\377\377\4\377\377\375\377\377\377\376\377\377\375\377" \ + "\376\230\377\377\377\203\377\377\375\202\377\377\377\2\376\376\376\376" \ + "\377\377\231\377\377\377\1\376\376\376\202\376\377\377\13\377\376\374" \ + "\377\376\377\376\376\374\376\377\377\377\377\377\376\377\377\377\377" \ + "\377\377\377\375\376\376\376\377\377\377\377\376\377\222\377\377\377" \ + "\202\377\377\375\5\377\377\377\376\377\377\377\377\377\377\377\375\376" \ + "\377\377\251\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376" \ + "\377\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214" \ + "\305@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>" \ + "\212\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370" \ + "\373\362\377\377\377\202\377\376\377\1\377\377\375\254\377\377\377\4" \ + "\363\363\363SSU;;=99;\202;;=\1""99;\204::<\3;;=::<\235\235\237\377\377" \ + "\377\377\334\377\377\377\1\376\376\376\202\377\377\377\2\363\363\363" \ + "GGI\202::<\7;;=::<99;::<;;=::<;;=\202::<\2\266\266\266\376\376\376\204" \ + "\377\377\377\202\376\376\376\202\377\377\377\1\376\376\376\236\377\377" \ + "\377\3\376\376\376\265\265\267;;=\202::<\2;;=99;\205::<\1;;=\204::<\4" \ + ";;=FFH\332\332\332\376\376\376\205\377\377\377\1\376\376\376\240\377" \ + "\377\377\10\376\377\375\377\375\377\377\377\375\376\377\375\377\377\377" \ + "\377\376\377\377\377\377\376\376\374\230\377\377\377\10\374\377\377\377" \ + "\376\374\377\377\377\376\376\374\377\376\377\376\377\377\377\377\377" \ + "\377\376\377\230\377\377\377\3\377\377\375\377\377\377\376\377\375\203" \ + "\377\377\377\1\377\376\377\231\377\377\377\6\377\375\377\376\376\374" \ + "\377\377\377\377\376\377\376\377\375\377\376\377\202\377\377\377\2\377" \ + "\376\377\377\377\377\202\376\377\377\2\376\376\377\376\377\377\222\377" \ + "\377\377\2\377\377\375\377\375\377\202\376\377\377\4\376\376\376\376" \ + "\377\377\375\377\374\377\375\377\251\377\377\377\1\375\377\376\202\377" \ + "\377\375\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212" \ + "\307<\215\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<" \ + "\214\306>\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244" \ + "\317c\370\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377" \ + "\377\375\377\376\377\252\377\377\377\5\376\376\376\377\377\377\333\333" \ + "\33399;;;=\202::<\5;;=99;;;=99;;;=\203::<\1\332\332\334\377\377\377\377" \ + "\330\377\377\377\1\376\376\376\205\377\377\377\1xxx\202::<\1;;=\202:" \ + ":<\1;;=\204::<\4:::xxx\376\376\376\377\377\377\202\376\376\376\205\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\237\377\377\377\1\265" \ + "\265\265\204::<\6;;=::<;;=::<;;=::<\202;;=\203::<\4;;=FFH\333\333\333" \ + "\376\376\376\202\377\377\377\1\376\376\376\242\377\377\377\7\376\376" \ + "\376\377\376\377\326\352\267\247\324o\247\324m\252\324r\247\324o\231" \ + "\252\324p\10\323\353\271\377\376\377\377\377\377\376\377\377\350\365" \ + "\333\253\323p\250\324r\251\324k\230\252\324p\10\250\325n\252\324p\277" \ + "\337\223\376\377\377\377\377\377\375\377\376\376\377\377\276\336\222" \ + "\230\252\324p\7\250\325p\250\324r\247\324o\253\324n\251\323m\346\364" \ + "\332\377\376\377\202\377\377\377\7\323\352\266\253\323p\251\323m\253" \ + "\323r\251\323o\247\324m\252\324r\220\252\324p\10\252\324n\253\324n\247" \ + "\324k\252\324p\254\325o\247\324m\252\324p\324\353\267\250\377\377\377" \ + "\3\377\376\377\377\377\377\375\377\376\202\377\377\377\11\373\373\363" \ + "\241\321d\214\306>\213\310=\214\306>\214\305@\213\310=\212\306@\217\304" \ + ">\202\215\307=\14\214\306>\215\305>\214\306>\215\305>\217\304@\215\307" \ + "\77\215\307=\242\320c\367\375\361\376\376\377\377\376\377\376\376\376" \ + "\202\377\377\375\2\374\377\377\377\376\377\254\377\377\377\2\376\376" \ + "\376\251\251\251\202::<\5;;=::<;;=99;;;=\204::<\1``b\377\377\377\377" \ + "\334\377\377\377\3\376\376\376\301\301\301:::\205::<\1""99;\202::<\4" \ + ";;=::<SSS\362\362\362\207\377\377\377\1\376\376\376\202\377\377\377\202" \ + "\376\376\376\240\377\377\377\1\265\265\267\203::<\2""99;;;=\203::<\1" \ + ";;=\202::<\202;;=\203::<\2FFH\332\332\332\245\377\377\377\10\376\377" \ + "\377\377\377\377\305\342\237\215\306A\215\307\77\215\305@\213\310=\214" \ + "\305@\230\214\306>\10\304\341\237\377\374\377\377\376\377\377\377\377" \ + "\341\362\322\215\305>\212\307>\215\305>\230\214\306>\4\215\305<\214\305" \ + "@\252\324r\376\377\377\202\377\377\377\2\377\377\375\250\324r\230\214" \ + "\306>\20\215\307\77\214\306>\214\306<\214\305B\212\307>\337\363\320\377" \ + "\376\377\376\377\377\376\376\374\305\342\240\214\305@\213\310=\215\305" \ + "@\214\306>\212\307<\214\305@\220\214\306>\10\214\305@\215\306C\212\307" \ + "<\214\306>\215\305>\212\306@\215\305>\304\343\237\250\377\377\377\1\377" \ + "\377\375\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306" \ + ">\213\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215" \ + "\307=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<" \ + "\244\317c\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377" \ + "\377\377\377\202\377\376\377\257\377\377\377\1kkm\202::<\2;;=::<\202" \ + ";;=\3::<;;=::<\202;;=\1\233\233\233\377\377\377\377\330\377\377\377\1" \ + "\376\376\376\202\377\377\377\3\364\364\366FFH;;=\205::<\3;;=::<;;=\202" \ + "::<\1\316\316\316\256\377\377\377\2\265\265\265;;=\203::<\1;;=\205::" \ + "<\1;;=\204::<\3;;=FFH\332\332\332\206\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\235\377\377\377\1\304\343\240\235\214\306>\1\305\342" \ + "\237\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377" \ + "\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377" \ + "\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306" \ + ">\1\214\305@\205\214\306>\1\305\342\237\241\377\377\377\10\376\376\377" \ + "\377\377\375\377\377\377\377\377\375\377\377\377\377\376\377\377\377" \ + "\375\376\377\377\202\377\377\377\6\370\373\362\243\322b\211\307B\213" \ + "\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305@\214\306<\215" \ + "\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214\305@\244\317" \ + "c\367\375\361\267\377\377\377\2\363\363\363FFF\204::<\1;;=\203::<\4:" \ + "9>::<;;=\332\332\332\377\377\377\377\332\377\377\377\1yy{\202::<\2""9" \ + "9;;;=\202::<\6;;=99;::<;;=::<\234\234\236\260\377\377\377\12\265\265" \ + "\267;;=::<;;=99;;;=::<;;=::<;;=\202::<\1;;=\203::<\3;;=FFF\332\332\332" \ + "\206\377\377\377\1\376\376\376\236\377\377\377\1\304\343\240\235\214" \ + "\306>\1\305\342\237\203\377\377\377\1\342\362\316\235\214\306>\1\250" \ + "\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316" \ + "\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305" \ + "@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\240\377\377\377" \ + "\6\376\376\377\377\376\377\375\376\377\376\377\377\377\377\375\375\377" \ + "\376\203\377\377\377\27\377\377\375\372\373\366\241\321a\217\304@\212" \ + "\307<\214\306>\215\305>\215\305@\213\310=\212\306@\214\306>\214\305B" \ + "\215\307\77\215\305>\215\306A\212\307>\214\306>\215\307\77\214\306>\242" \ + "\322b\370\373\362\376\376\377\377\375\376\267\377\377\377\1\301\301\301" \ + "\205::<\3;;=::<;;=\202::<\2""99;```\377\377\377\377\331\377\377\377\1" \ + "\301\301\301\202::<\1;;=\203::<\1;;=\202::<\3<<>::<__a\261\377\377\377" \ + "\7\376\376\376\265\265\265;;=::<;;=::<;;=\203::<\1;;=\203::<\1;;=\203" \ + "::<\2GGI\332\332\332\203\377\377\377\1\376\376\376\240\377\377\377\1" \ + "\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316" \ + "\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215" \ + "\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202" \ + "\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237" \ + "\240\377\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377" \ + "\374\377\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320" \ + "b\215\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214" \ + "\305D\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307" \ + "\77\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375" \ + "\270\377\377\377\3\204\204\204::<;;=\206::<\4;;=::<;;=\234\234\236\377" \ + "\377\377\377\325\377\377\377\4\376\376\376\377\377\377\363\363\363SS" \ + "U\211::<\4""99;::<\332\332\334\376\376\376\202\377\377\377\1\376\376" \ + "\376\257\377\377\377\2\264\264\264;;=\202::<\2""99;;;=\202::<\3""99;" \ + ";;=::<\202;;=\202::<\4;;=::<GGI\332\332\332\210\377\377\377\1\376\376" \ + "\376\232\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377" \ + "\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252" \ + "\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342" \ + "\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305" \ + "@\205\214\306>\1\305\342\237\241\377\377\377\37\376\377\377\376\377\375" \ + "\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377\370\373" \ + "\362\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<\214\306" \ + ">\214\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215\305>\212" \ + "\307>\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376\377\377" \ + "\376\376\376\376\377\377\270\377\377\377\3\363\363\363TTT;;=\202::<\1" \ + ";;=\203::<\5""99;;;=::<;;=\332\332\332\377\377\377\377\323\377\377\377" \ + "\1\376\376\376\202\377\377\377\4\221\221\221;;=99;;;=\202::<\1;;=\202" \ + "::<\1;;=\202::<\1\233\233\233\202\377\377\377\1\376\376\376\262\377\377" \ + "\377\2\265\265\267;;=\203::<\2""99;;;=\202::<\1;;=\202::<\1;;=\202::" \ + "<\4;;=::<FFF\332\332\332\203\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\376\376\376\233\377\377\377\1\304\343\240\235\214\306>\1\305\342\237" \ + "\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377" \ + "\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305" \ + "\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214" \ + "\305@\205\214\306>\1\305\342\237\240\377\377\377\202\377\377\375\3\377" \ + "\374\377\375\377\376\376\377\377\202\377\377\377\25\370\373\364\243\322" \ + "b\217\304@\212\306@\214\305@\215\305>\212\307>\212\306@\214\305B\214" \ + "\305@\214\305B\214\306>\212\307>\212\310\77\214\306>\217\304@\214\306" \ + ">\214\305@\242\322b\370\373\362\377\377\377\202\377\376\377\1\377\377" \ + "\375\272\377\377\377\7\316\316\316::<;;=::<99;::<;;=\205::<\1kkm\377" \ + "\377\377\377\325\377\377\377\1\315\315\315\206::<\6""99;::<99;;;=::<" \ + "```\206\377\377\377\1\376\376\376\257\377\377\377\3\376\376\376\265\265" \ + "\267;;=\202::<\2;;=99;\205::<\1;;=\204::<\4;;=FFH\332\332\332\376\376" \ + "\376\205\377\377\377\1\376\376\376\232\377\377\377\1\304\343\240\235" \ + "\214\306>\1\305\342\237\203\377\377\377\1\342\362\316\235\214\306>\1" \ + "\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307\77\342\362" \ + "\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214\306>\1\214" \ + "\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\241\377\377" \ + "\377\1\375\377\376\202\377\377\375\34\377\377\377\376\376\376\373\373" \ + "\363\243\322b\211\307B\212\307<\215\305>\214\306>\212\307>\214\305@\217" \ + "\304>\212\307<\214\306<\214\306>\215\307\77\213\307A\214\306>\215\305" \ + "@\215\307\77\212\307>\244\317c\370\373\362\377\377\373\376\377\377\377" \ + "\376\377\375\376\377\377\377\375\377\376\377\272\377\377\377\2\222\222" \ + "\22299;\205::<\1;;=\203::<\2;;=\250\250\250\377\377\377\377\324\377\377" \ + "\377\4```;;=99;;;=\204::<\5;;=::<;;=::<\331\331\331\207\377\377\377\1" \ + "\376\376\376\260\377\377\377\1\265\265\265\204::<\6;;=::<;;=::<;;=::" \ + "<\202;;=\203::<\4;;=FFH\333\333\333\376\376\376\202\377\377\377\1\376" \ + "\376\376\234\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203" \ + "\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1" \ + "\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305" \ + "\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214" \ + "\305@\205\214\306>\1\305\342\237\240\377\377\377\3\377\376\377\377\377" \ + "\377\375\377\376\202\377\377\377\11\373\373\363\241\321d\214\306>\213" \ + "\310=\214\306>\214\305@\213\310=\212\306@\217\304>\202\215\307=\14\214" \ + "\306>\215\305>\214\306>\215\305>\217\304@\215\307\77\215\307=\242\320" \ + "c\367\375\361\376\376\377\377\376\377\376\376\376\202\377\377\375\2\374" \ + "\377\377\377\376\377\262\377\377\377\2\376\376\376\377\377\377\202\376" \ + "\376\376\204\377\377\377\5\363\363\363SSU99;::<;;=\207::<\2GGG\363\363" \ + "\363\377\377\377\377\322\377\377\377\4\234\234\234:::::<;;=\202::<\1" \ + ";;=\203::<\202;;=\1\234\234\236\207\377\377\377\1\376\376\376\262\377" \ + "\377\377\1\265\265\267\203::<\2""99;;;=\203::<\1;;=\202::<\202;;=\203" \ + "::<\2FFH\332\332\332\237\377\377\377\1\304\343\240\235\214\306>\1\305" \ + "\342\237\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377" \ + "\377\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377" \ + "\377\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214" \ + "\306>\1\214\305@\205\214\306>\1\305\342\237\240\377\377\377\1\377\377" \ + "\375\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306>\213" \ + "\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215\307" \ + "=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<\244" \ + "\317c\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377\377" \ + "\377\377\202\377\376\377\273\377\377\377\2\376\376\376\316\316\316\206" \ + "::<\202;;=\4::<;;=::<xxx\377\377\377\377\321\377\377\377\2\346\346\350" \ + "FFH\203::<\1;;=\206::<\1__a\202\377\377\377\1\377\377\375\271\377\377" \ + "\377\2\265\265\265;;=\203::<\1;;=\205::<\1;;=\203::<\4;;=::<GGI\331\331" \ + "\331\236\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377" \ + "\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252" \ + "\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342" \ + "\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305" \ + "@\205\214\306>\1\305\342\237\231\377\377\377\10\376\376\377\377\377\375" \ + "\377\377\377\377\377\375\377\377\377\377\376\377\377\377\375\376\377" \ + "\377\202\377\377\377\6\370\373\362\243\322b\211\307B\213\310=\214\305" \ + "@\214\306<\202\215\305@\4\214\306<\214\305@\214\306<\215\307\77\202\214" \ + "\306>\6\212\307>\214\306>\215\307\77\214\305@\244\317c\367\375\361\305" \ + "\377\377\377\2xxz;;=\203::<\3;;=::<;;=\203::<\2;;=\315\315\315\377\377" \ + "\377\377\313\377\377\377\203\376\376\376\202\377\377\377\3xxz;;=::<\202" \ + ";;=\1""99;\202;;=\202::<\4;;=::<\333\333\335\376\376\376\274\377\377" \ + "\377\12\265\265\267;;=::<;;=99;;;=::<;;=::<;;=\202::<\1;;=\202::<\4;" \ + ";=99;GGI\332\332\332\235\377\377\377\1\304\343\240\235\214\306>\1\305" \ + "\342\237\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377" \ + "\377\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377" \ + "\377\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214" \ + "\306>\1\214\305@\205\214\306>\1\305\342\237\230\377\377\377\6\376\376" \ + "\377\377\376\377\375\376\377\376\377\377\377\377\375\375\377\376\203" \ + "\377\377\377\27\377\377\375\372\373\366\241\321a\217\304@\212\307<\214" \ + "\306>\215\305>\215\305@\213\310=\212\306@\214\306>\214\305B\215\307\77" \ + "\215\305>\215\306A\212\307>\214\306>\215\307\77\214\306>\242\322b\370" \ + "\373\362\376\376\377\377\375\376\304\377\377\377\2\364\364\364FFH\203" \ + "::<\2""99;;;=\203::<\4<<>99;TTT\376\376\376\377\377\377\377\310\377\377" \ + "\377\1\376\376\376\205\377\377\377\3\316\316\316::<99;\206::<\1;;=\202" \ + "::<\1\221\221\221\203\377\377\377\1\376\376\376\272\377\377\377\7\376" \ + "\376\376\265\265\265;;=::<;;=::<;;=\203::<\1;;=\203::<\6;;=::<;;=::<" \ + "FFH\332\332\332\234\377\377\377\1\304\343\240\235\214\306>\1\305\342" \ + "\237\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377" \ + "\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377" \ + "\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306" \ + ">\1\214\305@\205\214\306>\1\305\342\237\230\377\377\377\7\377\377\375" \ + "\375\376\377\376\377\377\376\377\375\377\374\377\377\377\375\375\377" \ + "\376\202\377\377\377\5\372\373\366\240\320b\215\307\77\212\306@\215\305" \ + ">\202\214\305@\20\215\305@\212\306@\214\305D\216\306\77\214\306>\215" \ + "\307\77\214\306>\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373" \ + "\362\377\377\373\377\376\377\377\377\375\304\377\377\377\3\376\376\376" \ + "\265\265\267;;=\204::<\1""99;\203::<\3;;=::<\234\234\234\203\377\377" \ + "\377\1\376\376\376\377\377\377\377\306\377\377\377\7\376\376\376\377" \ + "\377\377\376\376\376\377\377\377__a::<;;=\203::<\7;;=::<;;=::<;;=SSU" \ + "\363\363\363\300\377\377\377\2\264\264\264;;=\202::<\2""99;;;=\202::" \ + "<\3""99;;;=::<\202;;=\204::<\2FFH\332\332\332\233\377\377\377\1\304\343" \ + "\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316\235\214" \ + "\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307\77" \ + "\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214" \ + "\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\231" \ + "\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377\376\377\377" \ + "\375\377\377\377\377\376\377\370\373\362\241\321a\215\307\77\215\307" \ + "=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216\306\77\215" \ + "\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>\242\321" \ + "a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377\301\377" \ + "\377\377\1\376\376\376\204\377\377\377\2kkm99;\203::<\202;;=\1""99;\203" \ + "::<\2FFH\363\363\363\377\377\377\377\310\377\377\377\1\376\376\376\203" \ + "\377\377\377\3\250\250\252::<;;=\203::<\1;;=\202::<\5;;=::<;;=\301\301" \ + "\301\376\376\376\301\377\377\377\2\265\265\267;;=\203::<\2""99;;;=\202" \ + "::<\1;;=\202::<\2;;=::<\202;;=\3::<GGI\332\332\332\232\377\377\377\1" \ + "\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316" \ + "\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215" \ + "\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202" \ + "\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237" \ + "\230\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377" \ + "\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215" \ + "\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>" \ + "\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362" \ + "\377\377\377\202\377\376\377\1\377\377\375\301\377\377\377\1\376\376" \ + "\376\204\377\377\377\2\376\376\376\346\346\350\203::<\4;;=99;::<;;=\204" \ + "::<\3\203\203\203\377\377\377\376\376\376\377\377\377\377\311\377\377" \ + "\377\2\364\364\364FFH\202::<\5;;=::<;;=::<;;=\202::<\2;;=kkm\202\377" \ + "\377\377\1\376\376\376\300\377\377\377\3\376\376\376\265\265\267;;=\202" \ + "::<\2;;=99;\204::<\3;;=99;;;=\202::<\3;;=::<\265\265\265\232\377\377" \ + "\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362" \ + "\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>" \ + "\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215" \ + "\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1" \ + "\305\342\237\231\377\377\377\1\375\377\376\202\377\377\375\34\377\377" \ + "\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215\305>\214" \ + "\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>\215\307\77" \ + "\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362" \ + "\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376" \ + "\377\301\377\377\377\202\376\376\376\2\377\377\377\376\376\376\202\377" \ + "\377\377\1\234\234\236\203::<\1;;=\206::<\2;;=\331\331\331\377\377\377" \ + "\377\306\377\377\377\1\376\376\376\203\377\377\377\4\233\233\233;;=:" \ + ":<;;=\202::<\3;;=99;;;=\203::<\1\346\346\350\305\377\377\377\1\265\265" \ + "\265\204::<\3;;=::<;;=\203::<\5;;=99;;;=::<\265\265\267\233\377\377\377" \ + "\1\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316" \ + "\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215" \ + "\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202" \ + "\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237" \ + "\230\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \ + "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \ + "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \ + ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \ + "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\301\377\377" \ + "\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\6\364" \ + "\364\364SSU::<;;=::<;;=\205::<\4""99;kkk\377\377\377\376\376\376\377" \ + "\377\377\377\307\377\377\377\2\346\346\346;;;\204::<\3;;=99;;;=\203:" \ + ":<\1\234\234\236\205\377\377\377\1\376\376\376\301\377\377\377\1\265" \ + "\265\267\203::<\2""99;;;=\202::<\1;;;\204::<\1\265\265\267\234\377\377" \ + "\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362" \ + "\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>" \ + "\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215" \ + "\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1" \ + "\305\342\237\230\377\377\377\1\377\377\375\202\377\377\377\32\377\376" \ + "\377\370\373\364\243\322b\214\306>\213\310\77\214\305@\215\305>\215\305" \ + "@\214\306>\214\305B\212\307<\215\307=\214\305B\214\306>\215\306A\212" \ + "\306@\212\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377\377" \ + "\375\376\377\377\375\376\377\377\377\377\377\202\377\376\377\306\377" \ + "\377\377\1\376\376\376\202\377\377\377\2\301\301\303::<\202;;=\11::<" \ + ";;=::<;;=::<99;;;=::<\301\301\301\377\377\377\377\306\377\377\377\12" \ + "\376\376\376\377\377\377\204\204\204;;=::<:9>;;=::<99;;;=\203::<\5SS" \ + "U\363\363\363\376\376\376\377\377\377\376\376\376\305\377\377\377\5\265" \ + "\265\26599;;;=::<;;=\206::<\1\266\266\270\235\377\377\377\1\304\343\240" \ + "\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316\235\214\306" \ + ">\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307\77\342" \ + "\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214\306" \ + ">\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\221\377" \ + "\377\377\10\376\376\377\377\377\375\377\377\377\377\377\375\377\377\377" \ + "\377\376\377\377\377\375\376\377\377\202\377\377\377\6\370\373\362\243" \ + "\322b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214" \ + "\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77" \ + "\214\305@\244\317c\367\375\361\322\377\377\377\1kkk\203::<\4;;=99;::" \ + "<;;=\203::<\1SSU\210\377\377\377\1\376\376\376\377\377\377\377\276\377" \ + "\377\377\1\316\316\316\202::<\1;;=\202::<\202;;=\202::<\4;;=::<\265\265" \ + "\267\376\376\376\307\377\377\377\3\376\376\376\377\377\377\265\265\267" \ + "\207::<\3""99;\266\266\270\376\376\377\202\377\377\377\1\376\376\376" \ + "\232\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377" \ + "\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324" \ + "p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237" \ + "\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205" \ + "\214\306>\1\305\342\237\220\377\377\377\6\376\376\377\377\376\377\375" \ + "\376\377\376\377\377\377\377\375\375\377\376\203\377\377\377\27\377\377" \ + "\375\372\373\366\241\321a\217\304@\212\307<\214\306>\215\305>\215\305" \ + "@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305>\215\306A\212" \ + "\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362\376\376\377\377" \ + "\375\376\321\377\377\377\1\346\346\346\204::<\1;;=\202::<\5;;=99;;;=" \ + "::<\266\266\266\205\377\377\377\202\376\376\376\2\377\377\377\376\376" \ + "\376\377\377\377\377\273\377\377\377\5\376\376\376\377\377\377kkm::<" \ + ";;=\202::<\1;;=\203::<\3;;=::<kkm\203\377\377\377\1\376\376\376\306\377" \ + "\377\377\4\376\376\376\377\377\377\265\265\265::<\202;;=\202::<\2""9" \ + "9;\266\266\270\237\377\377\377\1\304\343\240\235\214\306>\1\305\342\237" \ + "\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377" \ + "\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305" \ + "\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214" \ + "\305@\205\214\306>\1\305\342\237\220\377\377\377\7\377\377\375\375\376" \ + "\377\376\377\377\376\377\375\377\374\377\377\377\375\375\377\376\202" \ + "\377\377\377\5\372\373\366\240\320b\215\307\77\212\306@\215\305>\202" \ + "\214\305@\20\215\305@\212\306@\214\305D\216\306\77\214\306>\215\307\77" \ + "\214\306>\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373\362" \ + "\377\377\373\377\376\377\377\377\375\322\377\377\377\1\221\221\223\202" \ + "::<\12;;=99;::<;;=::<;;=99;;;=EEG\364\364\364\203\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\376\376\376\377\377\377\377\275\377\377\377\2" \ + "\316\316\320;;=\205::<\2""99;;;=\203::<\3\316\316\316\377\377\377\376" \ + "\376\376\313\377\377\377\3\265\265\265;;=99;\202::<\1\266\266\270\203" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\232\377\377\377\1" \ + "\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316" \ + "\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215" \ + "\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202" \ + "\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237" \ + "\221\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377\376\377" \ + "\377\375\377\377\377\377\376\377\370\373\362\241\321a\215\307\77\215" \ + "\307=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216\306\77" \ + "\215\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>\242" \ + "\321a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377\322" \ + "\377\377\377\2\363\363\363FFH\203::<\202;;=\203::<\3;;=::<\235\235\235" \ + "\204\377\377\377\1\376\376\376\377\377\377\377\277\377\377\377\1__a\202" \ + "::<\1;;=\203::<\5;;=::<;;=::<\204\204\206\312\377\377\377\1\376\376\376" \ + "\202\377\377\377\7\376\376\376\377\377\377\265\265\267;;=99;\266\266" \ + "\270\376\376\377\203\377\377\377\202\376\376\376\233\377\377\377\1\304" \ + "\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316\235" \ + "\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307" \ + "\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214" \ + "\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\220" \ + "\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202" \ + "\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215\305" \ + ">\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>\212" \ + "\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377" \ + "\377\377\202\377\376\377\1\377\377\375\324\377\377\377\4\234\234\234" \ + ";;=::<<<>\204::<\1;;=\202::<\2FFH\363\363\363\204\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\376\376\376\377\377\377\377\272\377\377\377\1" \ + "\265\265\265\202::<\5;;=99;::<;;=::<\202;;=\3""99;;;=\346\346\346\320" \ + "\377\377\377\2\264\264\266\265\265\267\203\377\377\377\202\376\376\376" \ + "\235\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377" \ + "\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324" \ + "p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237" \ + "\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205" \ + "\214\306>\1\305\342\237\221\377\377\377\1\375\377\376\202\377\377\375" \ + "\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215" \ + "\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>" \ + "\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370" \ + "\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375" \ + "\377\376\377\320\377\377\377\1\376\376\376\203\377\377\377\2SSU;;=\203" \ + "::<\1;;=\203::<\3""99;::<\234\234\236\203\377\377\377\1\376\376\376\377" \ + "\377\377\377\276\377\377\377\5RRT99;;;=99;;;=\203::<\4""99;;;=::<\234" \ + "\234\236\314\377\377\377\1\376\376\376\212\377\377\377\1\376\376\376" \ + "\235\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377" \ + "\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324" \ + "p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237" \ + "\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205" \ + "\214\306>\1\305\342\237\220\377\377\377\3\377\376\377\377\377\377\375" \ + "\377\376\202\377\377\377\11\373\373\363\241\321d\214\306>\213\310=\214" \ + "\306>\214\305@\213\310=\212\306@\217\304>\202\215\307=\14\214\306>\215" \ + "\305>\214\306>\215\305>\217\304@\215\307\77\215\307=\242\320c\367\375" \ + "\361\376\376\377\377\376\377\376\376\376\202\377\377\375\2\374\377\377" \ + "\377\376\377\324\377\377\377\3\265\265\265;;=99;\202;;=\1""99;\202;;" \ + "=\5::<;;=::<GGI\363\363\363\206\377\377\377\1\376\376\376\377\377\377" \ + "\377\271\377\377\377\2\266\266\270;;=\202::<\1;;=\202::<\6;;=::<;;=:" \ + ":<FFH\363\363\363\324\377\377\377\3\376\376\376\377\377\377\376\376\376" \ + "\236\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377" \ + "\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324" \ + "p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237" \ + "\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205" \ + "\214\306>\1\305\342\237\220\377\377\377\1\377\377\375\202\377\377\377" \ + "\32\377\376\377\370\373\364\243\322b\214\306>\213\310\77\214\305@\215" \ + "\305>\215\305@\214\306>\214\305B\212\307<\215\307=\214\305B\214\306>" \ + "\215\306A\212\306@\212\307>\214\306>\212\307<\244\317c\370\373\364\377" \ + "\377\377\377\375\376\377\377\375\376\377\377\377\377\377\202\377\376" \ + "\377\326\377\377\377\1__a\203::<\1;;=\203::<\1;;=\202::<\1\234\234\234" \ + "\377\377\377\377\274\377\377\377\1\376\376\376\203\377\377\377\3SSU;" \ + ";=99;\210::<\1\234\234\234\365\377\377\377\7\376\377\375\304\341\236" \ + "\215\306A\214\305B\215\307=\212\307>\212\306@\230\214\305@\1\304\341" \ + "\236\203\377\377\377\4\341\362\320\214\306>\213\310\77\215\305@\231\214" \ + "\305@\2\215\307\77\252\322q\202\377\376\377\202\377\377\377\1\250\325" \ + "n\230\214\305@\3\215\305>\215\306A\215\307\77\202\214\306<\10\342\360" \ + "\317\376\377\377\377\377\375\376\377\377\305\342\240\215\305@\212\306" \ + "@\215\305>\202\214\305@\1\215\307=\220\214\305@\10\214\306>\212\306@" \ + "\216\306A\212\307>\215\305>\215\305@\214\305@\304\343\237\211\377\377" \ + "\377\10\376\376\377\377\377\375\377\377\377\377\377\375\377\377\377\377" \ + "\376\377\377\377\375\376\377\377\202\377\377\377\6\370\373\362\243\322" \ + "b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305" \ + "@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214" \ + "\305@\244\317c\367\375\361\335\377\377\377\2\376\376\376\316\316\316" \ + "\211::<\3;;=GGI\363\363\365\203\377\377\377\1\376\376\376\377\377\377" \ + "\377\266\377\377\377\10\376\376\376\377\377\377\376\376\376\377\377\377" \ + "\265\265\265;;=::<;;=\207::<\2GGI\363\363\363\364\377\377\377\7\377\376" \ + "\377\377\377\375\304\341\236\215\305>\215\307\77\214\306>\214\305@\231" \ + "\214\306>\7\304\343\237\377\377\377\375\376\377\377\377\375\341\360\321" \ + "\215\306A\214\305@\233\214\306>\6\252\324n\376\376\376\377\377\377\376" \ + "\377\377\377\376\377\252\324p\230\214\306>\7\215\306A\212\307>\214\306" \ + ">\212\307>\214\306>\343\361\320\376\377\377\202\377\377\377\7\305\342" \ + "\237\215\305>\213\310\77\214\306>\214\305@\212\306@\215\307\77\222\214" \ + "\306>\6\215\305>\212\307>\214\306>\215\307=\215\305@\305\342\237\210" \ + "\377\377\377\6\376\376\377\377\376\377\375\376\377\376\377\377\377\377" \ + "\375\375\377\376\203\377\377\377\27\377\377\375\372\373\366\241\321a" \ + "\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306@\214\306" \ + ">\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215\307\77" \ + "\214\306>\242\322b\370\373\362\376\376\377\377\375\376\336\377\377\377" \ + "\1kkm\202::<\1;;=\205::<\202;;=\3\233\233\235\377\377\377\376\376\376" \ + "\377\377\377\377\274\377\377\377\3SSU99;;;=\20299;\1;;=\203::<\3;;=:" \ + ":<\234\234\236\366\377\377\377\7\376\377\375\305\342\240\213\304\77\213" \ + "\310\77\214\305@\215\306A\216\306=\230\214\306>\10\305\342\240\377\377" \ + "\375\376\377\377\377\376\377\341\360\317\214\306<\214\305@\212\306@\231" \ + "\214\306>\7\215\305@\252\324p\377\377\377\377\377\375\376\377\377\377" \ + "\376\374\252\324p\230\214\306>\7\212\307>\215\307\77\216\306A\212\307" \ + ">\213\304\77\343\361\320\377\377\375\202\377\377\377\3\307\342\237\214" \ + "\304\77\213\310\77\203\214\306>\1\215\307\77\220\214\306>\4\214\305@" \ + "\214\306<\215\304B\213\310\77\202\212\307>\2\215\305@\305\342\240\210" \ + "\377\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374" \ + "\377\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215" \ + "\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D" \ + "\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77" \ + "\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\331" \ + "\377\377\377\1\376\376\376\203\377\377\377\4\376\376\376\317\317\321" \ + "::<;;=\203::<\3;;=::<;;=\202::<\4FFH\363\363\363\377\377\377\376\376" \ + "\376\377\377\377\377\264\377\377\377\1\376\376\376\205\377\377\377\1" \ + "\265\265\267\202;;=\3::<99;;;=\202::<\202;;=\2::<SSU\366\377\377\377" \ + "\7\377\376\377\375\377\374\304\341\237\216\306\77\212\307<\213\310\77" \ + "\212\307>\231\214\306>\2\305\342\240\377\377\377\202\377\376\377\3\341" \ + "\362\316\216\306\77\214\306<\231\214\306>\3\215\305@\212\307>\252\324" \ + "p\203\377\377\377\2\377\376\377\247\324o\230\214\306>\20\215\306A\214" \ + "\305B\215\307\77\211\305\77\214\304;\342\362\315\377\377\377\377\376" \ + "\377\376\376\376\305\342\237\215\306A\210\307;\215\306A\216\306A\214" \ + "\306>\212\306@\220\214\306>\202\214\305@\6\216\305C\213\305=\214\305" \ + "B\215\307\77\216\306\77\303\344\237\211\377\377\377\37\376\377\377\376" \ + "\377\375\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377" \ + "\370\373\362\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<" \ + "\214\306>\214\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215" \ + "\305>\212\307>\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376" \ + "\377\377\376\376\376\376\377\377\331\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\203\377\377\377\1kkm\202::<\6;;=::<;;=::<;;=::<\202" \ + ";;=\1\233\233\235\377\377\377\377\267\377\377\377\1\376\376\376\204\377" \ + "\377\377\2kkm;;=\202::<\2;;=::<\202;;=\203::<\5\265\265\267\377\377\377" \ + "\376\376\376\377\377\377\376\376\376\362\377\377\377\2\376\377\377\377" \ + "\376\377\202\377\377\377\202\377\376\377\2\377\377\377\377\377\375\231" \ + "\377\377\377\4\377\376\377\376\377\377\375\377\376\377\377\377\202\376" \ + "\377\377\231\377\377\377\10\374\377\375\377\376\377\377\377\375\376\376" \ + "\376\377\377\377\376\377\377\376\376\374\377\376\377\230\377\377\377" \ + "\1\377\376\377\203\377\377\375\4\376\377\377\377\375\377\377\377\377" \ + "\376\377\377\202\377\377\377\3\376\376\376\377\376\377\377\377\375\202" \ + "\376\377\377\1\377\377\375\220\377\377\377\10\377\377\375\377\377\377" \ + "\376\376\376\377\377\377\377\377\375\377\377\377\376\377\377\377\375" \ + "\377\210\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377" \ + "\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305" \ + "@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212" \ + "\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373" \ + "\362\377\377\377\202\377\376\377\1\377\377\375\340\377\377\377\1\316" \ + "\316\316\203::<\3;;=99;;;=\204::<\2FFH\363\363\363\202\377\377\377\1" \ + "\376\376\376\377\377\377\377\264\377\377\377\1\376\376\376\202\377\377" \ + "\377\1\316\316\320\206::<\1;;=\203::<\2SSU\376\376\376\366\377\377\377" \ + "\1\377\377\375\202\377\376\377\202\377\377\377\3\377\377\375\377\377" \ + "\377\376\377\377\230\377\377\377\202\376\377\377\6\377\377\375\377\377" \ + "\377\376\377\375\377\377\377\376\377\375\377\377\375\231\377\377\377" \ + "\2\376\377\377\377\377\375\202\377\377\377\1\376\376\376\232\377\377" \ + "\377\5\377\376\377\377\377\377\376\377\375\377\377\377\377\377\375\204" \ + "\377\377\377\202\376\377\377\1\376\376\376\202\377\377\377\202\376\377" \ + "\377\220\377\377\377\1\377\377\375\202\377\377\377\4\376\376\374\377" \ + "\376\377\377\377\377\376\377\375\212\377\377\377\1\375\377\376\202\377" \ + "\377\375\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212" \ + "\307<\215\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<" \ + "\214\306>\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244" \ + "\317c\370\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377" \ + "\377\375\377\376\377\334\377\377\377\1\376\376\376\202\377\377\377\10" \ + "\376\376\376kkm::<;;=99;;;=::<;;=\202::<\202;;=\1\234\234\236\203\377" \ + "\377\377\1\376\376\376\377\377\377\377\262\377\377\377\5\376\376\376" \ + "\377\377\377\376\376\376\377\377\377lln\210::<\3""99;;;=\265\265\265" \ + "\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\370\377" \ + "\377\377\1\376\377\377\230\377\377\377\7\377\376\377\377\377\375\377" \ + "\376\377\376\376\377\377\377\375\377\377\377\377\377\375\233\377\377" \ + "\377\1\377\376\377\203\377\377\377\1\376\377\375\231\377\377\377\5\377" \ + "\377\375\377\377\377\377\377\375\377\377\377\377\377\375\202\377\377" \ + "\377\1\377\377\375\203\377\377\377\2\376\376\376\377\376\377\226\377" \ + "\377\377\5\377\377\375\377\377\377\376\377\377\377\377\375\376\377\377" \ + "\210\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \ + "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \ + "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \ + ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \ + "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\333\377\377" \ + "\377\1\376\376\376\202\377\377\377\3\376\376\376\377\377\377\316\316" \ + "\320\203::<\1;;=\202::<\1;;=\203::<\2FFH\377\377\377\202\376\376\376" \ + "\377\377\377\377\262\377\377\377\5\376\376\376\377\377\377\376\376\376" \ + "\377\377\377\332\332\332\206::<\1;;=\202::<\5;;=FFH\363\363\363\377\377" \ + "\377\376\376\376\203\377\377\377\1\376\376\376\365\377\377\377\1\377" \ + "\377\375\202\377\377\377\1\377\377\375\230\377\377\377\2\376\377\377" \ + "\377\377\375\204\377\377\377\2\377\376\377\376\377\375\230\377\377\377" \ + "\4\377\377\375\377\377\377\377\377\373\376\377\377\203\377\377\377\1" \ + "\377\376\377\230\377\377\377\13\376\377\377\377\377\375\377\377\377\376" \ + "\377\377\377\375\376\377\377\377\377\377\375\376\377\377\377\376\377" \ + "\377\377\377\376\376\376\202\377\377\377\1\377\377\375\226\377\377\377" \ + "\202\376\377\377\2\377\377\375\377\376\377\210\377\377\377\1\377\377" \ + "\375\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306>\213" \ + "\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215\307" \ + "=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<\244" \ + "\317c\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377\377" \ + "\377\377\202\377\376\377\333\377\377\377\1\376\376\376\204\377\377\377" \ + "\11\376\376\376\377\377\377kkm::<;;=99;;;=::<;;=\202::<\3;;=::<\264\264" \ + "\264\377\377\377\377\265\377\377\377\1\376\376\376\202\377\377\377\1" \ + "\204\204\204\203::<\1;;=\206::<\1\235\235\237\377\377\377\377\377\377" \ + "\377\377\203\377\377\377\10\376\376\377\377\377\375\377\377\377\377\377" \ + "\375\377\377\377\377\376\377\377\377\375\376\377\377\202\377\377\377" \ + "\6\370\373\362\243\322b\211\307B\213\310=\214\305@\214\306<\202\215\305" \ + "@\4\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214" \ + "\306>\215\307\77\214\305@\244\317c\367\375\361\352\377\377\377\1\316" \ + "\316\316\203::<\1;;=\203::<\202;;=\2::<RRT\377\377\377\377\267\377\377" \ + "\377\3\346\346\346::<;;=\203::<\202;;=\5""99;::<;;=FFH\363\363\365\377" \ + "\377\377\377\377\377\377\377\202\377\377\377\6\376\376\377\377\376\377" \ + "\375\376\377\376\377\377\377\377\375\375\377\376\203\377\377\377\27\377" \ + "\377\375\372\373\366\241\321a\217\304@\212\307<\214\306>\215\305>\215" \ + "\305@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305>\215\306" \ + "A\212\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362\376\376" \ + "\377\377\375\376\352\377\377\377\2kkm;;=\207::<\3;;=::<\301\301\301\377" \ + "\377\377\377\266\377\377\377\2\221\221\221;;=\202::<\202;;=\202::<\1" \ + ";;=\202::<\1\235\235\237\377\377\377\377\377\377\377\377\203\377\377" \ + "\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374\377\377" \ + "\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215\307\77" \ + "\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D\216\306" \ + "\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77\215\305" \ + "@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\350\377\377" \ + "\377\4\376\376\376\377\377\377\265\265\26799;\203::<\3;;=::<;;=\203:" \ + ":<\2kkk\376\376\376\377\377\377\377\264\377\377\377\2\362\362\362FFH" \ + "\202::<\1;;=\203::<\5;;=::<;;=::<\363\363\363\377\377\377\377\377\377" \ + "\377\377\204\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377" \ + "\376\377\377\375\377\377\377\377\376\377\370\373\362\241\321a\215\307" \ + "\77\215\307=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216" \ + "\306\77\215\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306" \ + ">\242\321a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377" \ + "\352\377\377\377\2\376\376\376TTV\204::<\7;;=99;::<;;=99;::<\332\332" \ + "\332\377\377\377\377\263\377\377\377\3\376\376\376\266\266\266;;=\203" \ + "::<\202;;=\204::<\1\205\205\207\377\377\377\377\377\377\377\377\204\377" \ + "\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202\377" \ + "\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215\305>" \ + "\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>\212\310" \ + "\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377\377" \ + "\377\202\377\376\377\1\377\377\375\354\377\377\377\2\265\265\267::<\202" \ + ";;=\205::<\4;;=::<\204\204\204\376\376\376\377\377\377\377\263\377\377" \ + "\377\1SSU\202::<\1;;=\206::<\2;;=\346\346\346\377\377\377\377\377\377" \ + "\377\377\205\377\377\377\1\375\377\376\202\377\377\375\34\377\377\377" \ + "\376\376\376\373\373\363\243\322b\211\307B\212\307<\215\305>\214\306" \ + ">\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>\215\307\77\213" \ + "\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362\377" \ + "\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376\377" \ + "\354\377\377\377\4FFH;;=99;;;=\203::<\5;;=99;;;=99;\364\364\364\377\377" \ + "\377\377\262\377\377\377\1\316\316\316\202;;=\1""99;\203::<\1;;=\203" \ + "::<\1xxz\377\377\377\377\377\377\377\377\205\377\377\377\3\377\376\377" \ + "\377\377\377\375\377\376\202\377\377\377\11\373\373\363\241\321d\214" \ + "\306>\213\310=\214\306>\214\305@\213\310=\212\306@\217\304>\202\215\307" \ + "=\14\214\306>\215\305>\214\306>\215\305>\217\304@\215\307\77\215\307" \ + "=\242\320c\367\375\361\376\376\377\377\376\377\376\376\376\202\377\377" \ + "\375\2\374\377\377\377\376\377\354\377\377\377\1\235\235\237\204::<\1" \ + "<<>\202::<\4;;=::<;;=\247\247\251\377\377\377\377\262\377\377\377\4\204" \ + "\204\204;;=::<;;=\206::<\2;;=\316\316\316\377\377\377\377\377\377\377" \ + "\377\205\377\377\377\1\377\377\375\202\377\377\377\32\377\376\377\370" \ + "\373\364\243\322b\214\306>\213\310\77\214\305@\215\305>\215\305@\214" \ + "\306>\214\305B\212\307<\215\307=\214\305B\214\306>\215\306A\212\306@" \ + "\212\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377\377\375" \ + "\376\377\377\375\376\377\377\377\377\377\202\377\376\377\355\377\377" \ + "\377\1\363\363\363\212::<\1TTV\377\377\377\377\261\377\377\377\5\347" \ + "\347\351::<;;=::<;;=\204::<\3;;=::<TTT\377\377\377\377\376\377\377\377" \ + "\10\376\376\377\377\377\375\377\377\377\377\377\375\377\377\377\377\376" \ + "\377\377\377\375\376\377\377\202\377\377\377\6\370\373\362\243\322b\211" \ + "\307B\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305@\214" \ + "\306<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214\305" \ + "@\244\317c\367\375\361\361\377\377\377\1\376\376\376\204\377\377\377" \ + "\1\204\204\204\202;;=\203::<\1;;=\202::<\202;;=\1\302\302\302\203\377" \ + "\377\377\1\376\376\376\377\377\377\377\244\377\377\377\1\376\376\376" \ + "\203\377\377\377\1\376\376\376\203\377\377\377\1\234\234\236\202::<\1" \ + ";;=\204::<\6;;=::<;;=\264\264\264\377\377\377\376\376\376\377\377\377" \ + "\377\373\377\377\377\6\376\376\377\377\376\377\375\376\377\376\377\377" \ + "\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373\366\241" \ + "\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306@" \ + "\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215" \ + "\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\365\377" \ + "\377\377\1\332\332\332\202::<\1;;=\202::<\6""99;::<;;=99;;;=xxx\205\377" \ + "\377\377\1\376\376\376\377\377\377\377\243\377\377\377\1\376\376\376" \ + "\206\377\377\377\4SSU;;=::<;;=\202::<\1;;=\203::<\3GGI\362\362\362\376" \ + "\376\376\377\377\377\377\374\377\377\377\7\377\377\375\375\376\377\376" \ + "\377\377\376\377\375\377\374\377\377\377\375\375\377\376\202\377\377" \ + "\377\5\372\373\366\240\320b\215\307\77\212\306@\215\305>\202\214\305" \ + "@\20\215\305@\212\306@\214\305D\216\306\77\214\306>\215\307\77\214\306" \ + ">\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373\362\377\377" \ + "\373\377\376\377\377\377\375\364\377\377\377\3\376\376\376\377\377\377" \ + "__a\203::<\202;;=\6::<99;;;=::<;;=\345\345\345\203\377\377\377\1\376" \ + "\376\376\377\377\377\377\245\377\377\377\3\376\376\376\377\377\377\376" \ + "\376\376\202\377\377\377\2\316\316\316::<\202;;=\205::<\202;;=\1\203" \ + "\203\205\204\377\377\377\1\376\376\376\377\377\377\377\372\377\377\377" \ + "\37\376\377\377\376\377\375\377\375\376\375\377\376\377\377\375\377\377" \ + "\377\377\376\377\370\373\362\241\321a\215\307\77\215\307=\214\305@\214" \ + "\306>\212\307<\214\306>\214\306<\214\306>\216\306\77\215\305<\212\307" \ + ">\213\307A\215\305>\212\307>\215\307\77\214\306>\242\321a\373\374\364" \ + "\377\377\377\376\377\377\376\376\376\376\377\377\362\377\377\377\202" \ + "\376\376\376\3\377\377\377\376\376\376\265\265\267\202::<\1;;=\207::" \ + "<\3\251\251\253\377\377\377\376\376\376\203\377\377\377\1\376\376\376" \ + "\377\377\377\377\247\377\377\377\2\376\376\376\204\204\206\207::<\1;" \ + ";=\202::<\3\346\346\346\377\377\377\376\376\376\377\377\377\377\374\377" \ + "\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202\377" \ + "\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215\305>" \ + "\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>\212\310" \ + "\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377\377" \ + "\377\202\377\376\377\1\377\377\375\364\377\377\377\17\376\376\376\377" \ + "\377\377\376\376\376\377\377\377FFH;;=99;::<;;=::<;;=99;;;=::<SSU\377" \ + "\377\377\377\251\377\377\377\1\376\376\376\203\377\377\377\3\363\363" \ + "\365::<;;=\202::<\11;;=::<;;=::<;;=::<kkm\377\377\377\376\376\376\377" \ + "\377\377\377\376\377\377\377\1\375\377\376\202\377\377\375\34\377\377" \ + "\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215\305>\214" \ + "\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>\215\307\77" \ + "\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362" \ + "\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376" \ + "\377\361\377\377\377\202\376\376\376\2\377\377\377\376\376\376\202\377" \ + "\377\377\1\221\221\221\205::<\202;;=\5::<;;=99;\316\316\320\376\376\376" \ + "\377\377\377\377\250\377\377\377\1\376\376\376\202\377\377\377\4\266" \ + "\266\270::<99;;;=\203::<\1;;=\203::<\1\265\265\265\377\377\377\377\377" \ + "\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377\11" \ + "\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310=\212" \ + "\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305>\217" \ + "\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376\377" \ + "\376\376\376\202\377\377\375\2\374\377\377\377\376\377\360\377\377\377" \ + "\1\376\376\376\202\377\377\377\202\376\376\376\202\377\377\377\6\346" \ + "\346\346;;=99;::<99;;;=\204::<\2;;=\204\204\206\202\377\377\377\1\376" \ + "\376\376\377\377\377\377\251\377\377\377\1__a\203::<\3;;=::<;;=\203:" \ + ":<\4FFF\363\363\363\377\377\377\376\376\376\377\377\377\377\375\377\377" \ + "\377\1\377\377\375\202\377\377\377\32\377\376\377\370\373\364\243\322" \ + "b\214\306>\213\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212" \ + "\307<\215\307=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>" \ + "\212\307<\244\317c\370\373\364\377\377\377\377\375\376\377\377\375\376" \ + "\377\377\377\377\377\202\377\376\377\371\377\377\377\4^^`;;=::<;;=\202" \ + "::<\5;;=::<;;=::<FFH\377\377\377\377\253\377\377\377\3\346\346\346::" \ + "<;;=\210::<\1\204\204\204\202\377\377\377\202\376\376\376\377\377\377" \ + "\377\365\377\377\377\10\376\376\377\377\377\375\377\377\377\377\377\375" \ + "\377\377\377\377\376\377\377\377\375\376\377\377\202\377\377\377\6\370" \ + "\373\362\243\322b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4" \ + "\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306" \ + ">\215\307\77\214\305@\244\317c\367\375\361\377\377\377\377\202\377\377" \ + "\377\3\265\265\267::<;;=\204::<\1;;=\202::<\2;;=\265\265\265\202\377" \ + "\377\377\1\376\376\376\377\377\377\377\246\377\377\377\2\376\376\376" \ + "\234\234\234\202;;=\203::<\1;;=\202::<\3""99;::<\332\332\332\377\377" \ + "\377\377\370\377\377\377\6\376\376\377\377\376\377\375\376\377\376\377" \ + "\377\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373\366" \ + "\241\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306" \ + "@\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215" \ + "\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\377\377" \ + "\377\377\5\377\377\377\363\363\365;;=::<;;=\202::<\3;;=::<;;=\202::<" \ + "\3xxz\377\377\377\376\376\376\377\377\377\377\246\377\377\377\3\376\376" \ + "\376\377\377\377SSS\202::<\1;;=\202::<\1;;=\202::<\6;;=SSU\377\377\377" \ + "\376\376\376\377\377\377\376\376\376\202\377\377\377\1\376\376\376\377" \ + "\377\377\377\362\377\377\377\7\377\377\375\375\376\377\376\377\377\376" \ + "\377\375\377\374\377\377\377\375\375\377\376\202\377\377\377\5\372\373" \ + "\366\240\320b\215\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212" \ + "\306@\214\305D\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306" \ + ">\215\307\77\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377" \ + "\377\375\377\377\377\377\11\377\377\377\376\376\376\204\204\206;;=::" \ + "<99;;;=::<;;=\204::<\3\362\362\362\377\377\377\376\376\376\377\377\377" \ + "\377\246\377\377\377\1\333\333\333\203::<\202;;=\202::<\5<<>99;::<\250" \ + "\250\252\376\376\376\203\377\377\377\1\376\376\376\377\377\377\377\365" \ + "\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377\376\377\377" \ + "\375\377\377\377\377\376\377\370\373\362\241\321a\215\307\77\215\307" \ + "=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216\306\77\215" \ + "\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>\242\321" \ + "a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377\377\377" \ + "\377\377\202\377\377\377\1\301\301\301\202::<\1;;=\203::<\1;;=\203::" \ + "<\1\266\266\270\377\377\377\377\250\377\377\377\2\220\220\220;;=\204" \ + "::<\6;;=::<99;;;=::<\346\346\346\205\377\377\377\1\376\376\376\377\377" \ + "\377\377\363\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376" \ + "\377\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214" \ + "\305@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>" \ + "\212\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370" \ + "\373\362\377\377\377\202\377\376\377\1\377\377\375\377\377\377\377\204" \ + "\377\377\377\2TTV99;\202::<\1;;=\202::<\6;;=::<;;=__a\377\377\377\376" \ + "\376\376\377\377\377\377\244\377\377\377\3\376\376\376\377\377\377TT" \ + "V\207::<\3;;=99;```\377\377\377\377\373\377\377\377\1\375\377\376\202" \ + "\377\377\375\34\377\377\377\376\376\376\373\373\363\243\322b\211\307" \ + "B\212\307<\215\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214" \ + "\306<\214\306>\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307" \ + ">\244\317c\370\373\362\377\377\373\376\377\377\377\376\377\375\376\377" \ + "\377\377\375\377\376\377\377\377\377\377\203\377\377\377\3\221\221\221" \ + "::<;;=\202::<\202;;=\203::<\2;;=\345\345\347\377\377\377\377\246\377" \ + "\377\377\4\332\332\332;;=::<;;=\203::<\1;;=\203::<\1\265\265\265\203" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377\364" \ + "\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377\11" \ + "\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310=\212" \ + "\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305>\217" \ + "\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376\377" \ + "\376\376\376\202\377\377\375\2\374\377\377\377\376\377\377\377\377\377" \ + "\202\377\377\377\5\376\376\376\332\332\332;;=::<;;=\202::<\6;;=::<;;" \ + "=99;::<\250\250\252\377\377\377\377\244\377\377\377\6\376\376\376\377" \ + "\377\377\221\221\223::<;;=99;\202::<\3;;=::<;;=\202::<\1\363\363\363" \ + "\377\377\377\377\372\377\377\377\1\377\377\375\202\377\377\377\32\377" \ + "\376\377\370\373\364\243\322b\214\306>\213\310\77\214\305@\215\305>\215" \ + "\305@\214\306>\214\305B\212\307<\215\307=\214\305B\214\306>\215\306A" \ + "\212\306@\212\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377" \ + "\377\375\376\377\377\375\376\377\377\377\377\377\202\377\376\377\377" \ + "\377\377\377\204\377\377\377\2\376\376\376SSU\204::<\204;;=\2::<__a\377" \ + "\377\377\377\243\377\377\377\6\376\376\376\377\377\377\376\376\376TT" \ + "V99;;;=\204::<\4;;=99;<<>xxz\377\377\377\377\364\377\377\377\10\376\376" \ + "\377\377\377\375\377\377\377\377\377\375\377\377\377\377\376\377\377" \ + "\377\375\376\377\377\202\377\377\377\6\370\373\362\243\322b\211\307B" \ + "\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305@\214\306" \ + "<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214\305@\244" \ + "\317c\367\375\361\377\377\377\377\213\377\377\377\5\376\376\376\377\377" \ + "\377\221\221\223::<;;=\204::<\5;;=::<;;=::<\363\363\363\204\377\377\377" \ + "\1\376\376\376\202\377\377\377\202\376\376\376\377\377\377\377\233\377" \ + "\377\377\5\332\332\332::<;;=99;<<>\202::<\1;;=\203::<\1\265\265\267\377" \ + "\377\377\377\363\377\377\377\6\376\376\377\377\376\377\375\376\377\376" \ + "\377\377\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373" \ + "\366\241\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212" \ + "\306@\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306" \ + ">\215\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\377" \ + "\377\377\377\213\377\377\377\2\375\375\375\333\333\333\202::<\1;;=\202" \ + "::<\1;;=\202::<\3""99;::<\265\265\265\206\377\377\377\3\376\376\376\377" \ + "\377\377\376\376\376\377\377\377\377\233\377\377\377\2\235\235\23599" \ + ";\202;;=\1""99;\202;;=\202::<\3;;=::<\363\363\365\377\377\377\377\363" \ + "\377\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374" \ + "\377\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215" \ + "\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D" \ + "\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77" \ + "\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\377" \ + "\377\377\377\214\377\377\377\2\376\376\376SSU\207::<\3;;=::<xxx\203\377" \ + "\377\377\202\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377" \ + "\234\377\377\377\1^^`\211::<\3xxz\377\377\377\376\376\376\377\377\377" \ + "\377\363\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377\376" \ + "\377\377\375\377\377\377\377\376\377\370\373\362\241\321a\215\307\77" \ + "\215\307=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216\306" \ + "\77\215\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>" \ + "\242\321a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377" \ + "\377\377\377\377\212\377\377\377\4\376\376\376\377\377\377\376\376\376" \ + "\222\222\222\205::<\1;;=\20299;\202::<\3\363\363\363\377\377\377\376" \ + "\376\376\377\377\377\377\240\377\377\377\1\346\346\346\202::<\1;;=\204" \ + "::<\1;;=\202::<\1\250\250\252\202\377\377\377\1\376\376\376\377\377\377" \ + "\377\361\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377" \ + "\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305" \ + "@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212" \ + "\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373" \ + "\362\377\377\377\202\377\376\377\1\377\377\375\377\377\377\377\212\377" \ + "\377\377\1\376\376\376\203\377\377\377\2\332\332\332<<>\203::<\3;;=:" \ + ":<<<>\203::<\2\301\301\303\376\376\376\202\377\377\377\5\376\376\376" \ + "\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377\377\231" \ + "\377\377\377\4\376\376\376\251\251\253::<;;=\204::<\5;;=::<99;::<\346" \ + "\346\346\377\377\377\377\365\377\377\377\1\375\377\376\202\377\377\375" \ + "\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215" \ + "\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>" \ + "\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370" \ + "\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375" \ + "\377\376\377\377\377\377\377\212\377\377\377\1\376\376\376\203\377\377" \ + "\377\1SSS\207::<\3;;=::<\205\205\207\205\377\377\377\1\376\376\376\377" \ + "\377\377\377\234\377\377\377\3wwy::<;;=\206::<\2;;=__a\377\377\377\377" \ + "\365\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \ + "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \ + "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \ + ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \ + "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\377\377\377" \ + "\377\211\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376\204" \ + "\204\204::<\202;;=\1::<\202;;=\203::<\1SSU\204\377\377\377\1\376\376" \ + "\376\377\377\377\377\235\377\377\377\1;;=\203::<\1;;=\202::<\1;;=\202" \ + "::<\1\234\234\234\202\377\377\377\1\376\376\376\377\377\377\377\362\377" \ + "\377\377\1\377\377\375\202\377\377\377\32\377\376\377\370\373\364\243" \ + "\322b\214\306>\213\310\77\214\305@\215\305>\215\305@\214\306>\214\305" \ + "B\212\307<\215\307=\214\305B\214\306>\215\306A\212\306@\212\307>\214" \ + "\306>\212\307<\244\317c\370\373\364\377\377\377\377\375\376\377\377\375" \ + "\376\377\377\377\377\377\202\377\376\377\377\377\377\377\212\377\377" \ + "\377\1\376\376\376\204\377\377\377\6\301\301\301;;=::<;;=::<;;=\205:" \ + ":<\1\333\333\333\202\377\377\377\1\376\376\376\377\377\377\377\231\377" \ + "\377\377\1\376\376\376\203\377\377\377\1\301\301\303\204::<\1;;=\202" \ + "::<\1:9>\202::<\1\332\332\332\377\377\377\377\356\377\377\377\10\376" \ + "\376\377\377\377\375\377\377\377\377\377\375\377\377\377\377\376\377" \ + "\377\377\375\376\377\377\202\377\377\377\6\370\373\362\243\322b\211\307" \ + "B\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305@\214\306" \ + "<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214\305@\244" \ + "\317c\367\375\361\377\377\377\377\230\377\377\377\2""99;;;=\210::<\1" \ + "\250\250\250\377\377\377\377\240\377\377\377\3\221\221\223::<;;=\207" \ + "::<\2SSU\376\376\376\377\377\377\377\355\377\377\377\6\376\376\377\377" \ + "\376\377\375\376\377\376\377\377\377\377\375\375\377\376\203\377\377" \ + "\377\27\377\377\375\372\373\366\241\321a\217\304@\212\307<\214\306>\215" \ + "\305>\215\305@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305" \ + ">\215\306A\212\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362" \ + "\376\376\377\377\375\376\377\377\377\377\227\377\377\377\1yy{\211::<" \ + "\6lll\376\376\376\377\377\377\376\376\376\377\377\377\376\376\376\377" \ + "\377\377\377\224\377\377\377\202\376\376\376\7\377\377\377\376\376\376" \ + "\377\377\377\376\376\376\377\377\377__a;;=\202::<\4<<>;;=::<;;=\202:" \ + ":<\1\204\204\206\203\377\377\377\1\376\376\376\377\377\377\377\352\377" \ + "\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374\377" \ + "\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215\307" \ + "\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D\216" \ + "\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77\215" \ + "\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\377\377" \ + "\377\377\221\377\377\377\3\376\376\376\377\377\377\376\376\376\203\377" \ + "\377\377\1\265\265\267\212::<\1\363\363\363\377\377\377\377\227\377\377" \ + "\377\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377\1\345" \ + "\345\345\202::<\202;;=\1""99;\203::<\4;;=::<\301\301\301\376\376\376" \ + "\203\377\377\377\1\376\376\376\377\377\377\377\352\377\377\377\37\376" \ + "\377\377\376\377\375\377\375\376\375\377\376\377\377\375\377\377\377" \ + "\377\376\377\370\373\362\241\321a\215\307\77\215\307=\214\305@\214\306" \ + ">\212\307<\214\306>\214\306<\214\306>\216\306\77\215\305<\212\307>\213" \ + "\307A\215\305>\212\307>\215\307\77\214\306>\242\321a\373\374\364\377" \ + "\377\377\376\377\377\376\376\376\376\377\377\377\377\377\377\222\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\1\347" \ + "\347\347\212::<\1\302\302\304\205\377\377\377\1\376\376\376\377\377\377" \ + "\377\222\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202" \ + "\377\377\377\5\265\265\265::<;;=99;;;=\203::<\1;;=\202::<\1\363\363\363" \ + "\377\377\377\377\356\377\377\377\202\377\377\375\3\377\374\377\375\377" \ + "\376\376\377\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212" \ + "\306@\214\305@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B" \ + "\214\306>\212\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242" \ + "\322b\370\373\362\377\377\377\202\377\376\377\1\377\377\375\377\377\377" \ + "\377\230\377\377\377\2\376\376\376TTT\211::<\3\221\221\223\377\377\377" \ + "\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377\231\377\377" \ + "\377\2\204\204\204::<\202;;=\202::<\1;;=\203::<\2``b\376\376\376\377" \ + "\377\377\377\357\377\377\377\1\375\377\376\202\377\377\375\34\377\377" \ + "\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215\305>\214" \ + "\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>\215\307\77" \ + "\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362" \ + "\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376" \ + "\377\377\377\377\377\225\377\377\377\1\376\376\376\202\377\377\377\1" \ + "\221\221\221\210::<\2;;=__a\202\377\377\377\1\376\376\376\377\377\377" \ + "\377\227\377\377\377\1\376\376\376\203\377\377\377\1SSU\202::<\1;;=\204" \ + "::<\202;;=\1\234\234\234\204\377\377\377\1\376\376\376\377\377\377\377" \ + "\352\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \ + "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \ + "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \ + ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \ + "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\377\377\377" \ + "\377\222\377\377\377\1\376\376\376\205\377\377\377\1\301\301\301\210" \ + "::<\4""99;;;=\364\364\366\376\376\376\377\377\377\377\233\377\377\377" \ + "\1\346\346\346\207::<\4;;=99;::<\316\316\316\203\377\377\377\1\376\376" \ + "\376\377\377\377\377\353\377\377\377\1\377\377\375\202\377\377\377\32" \ + "\377\376\377\370\373\364\243\322b\214\306>\213\310\77\214\305@\215\305" \ + ">\215\305@\214\306>\214\305B\212\307<\215\307=\214\305B\214\306>\215" \ + "\306A\212\306@\212\307>\214\306>\212\307<\244\317c\370\373\364\377\377" \ + "\377\377\375\376\377\377\375\376\377\377\377\377\377\202\377\376\377" \ + "\377\377\377\377\224\377\377\377\1\376\376\376\204\377\377\377\1\363" \ + "\363\363\210::<\3;;=::<\302\302\304\377\377\377\377\231\377\377\377\1" \ + "\376\376\376\202\377\377\377\1\266\266\270\203::<\203;;=\203::<\1:::" \ + "\377\377\377\377\351\377\377\377\10\376\376\377\377\377\375\377\377\377" \ + "\377\377\375\377\377\377\377\376\377\377\377\375\376\377\377\202\377" \ + "\377\377\6\370\373\362\243\322b\211\307B\213\310=\214\305@\214\306<\202" \ + "\215\305@\4\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212" \ + "\307>\214\306>\215\307\77\214\305@\244\317c\367\375\361\377\377\377\377" \ + "\242\377\377\377\3__a::<;;=\207::<\1\221\221\221\377\377\377\377\234" \ + "\377\377\377\1\204\204\206\204::<\202;;=\203::<\1lll\203\377\377\377" \ + "\1\375\375\375\377\377\377\377\344\377\377\377\6\376\376\377\377\376" \ + "\377\375\376\377\376\377\377\377\377\375\375\377\376\203\377\377\377" \ + "\27\377\377\375\372\373\366\241\321a\217\304@\212\307<\214\306>\215\305" \ + ">\215\305@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305>\215" \ + "\306A\212\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362\376" \ + "\376\377\377\375\376\377\377\377\377\241\377\377\377\2\221\221\223;;" \ + "=\202::<\202;;=\203::<\2;;=^^^\204\377\377\377\1\376\376\376\377\377" \ + "\377\377\224\377\377\377\1\376\376\376\202\377\377\377\1``b\202::<\1" \ + ";;=\206::<\1\234\234\234\205\377\377\377\1\376\376\376\377\377\377\377" \ + "\342\377\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377" \ + "\374\377\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320" \ + "b\215\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214" \ + "\305D\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307" \ + "\77\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375" \ + "\377\377\377\377\241\377\377\377\6\301\301\303::<;;=::<99;;;=\203::<" \ + "\6;;=:::\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377" \ + "\377\224\377\377\377\1\376\376\376\202\377\377\377\2\363\363\363;;=\211" \ + "::<\1\316\316\316\203\377\377\377\1\376\376\376\202\377\377\377\1\376" \ + "\376\376\377\377\377\377\342\377\377\377\37\376\377\377\376\377\375\377" \ + "\375\376\375\377\376\377\377\375\377\377\377\377\376\377\370\373\362" \ + "\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<\214\306>\214" \ + "\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215\305>\212\307" \ + ">\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376\377\377\376" \ + "\376\376\376\377\377\377\377\377\377\241\377\377\377\1\363\363\365\202" \ + "::<\1;;=\202::<\2""99;;;=\202::<\2;;=\316\316\316\377\377\377\377\231" \ + "\377\377\377\10\376\376\376\316\316\316::<;;=::<;;=99;;;=\204::<\202" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377\344" \ + "\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202" \ + "\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215\305" \ + ">\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>\212" \ + "\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377" \ + "\377\377\202\377\376\377\1\377\377\375\377\377\377\377\243\377\377\377" \ + "\1``b\203::<\203;;=\6::<<<>::<\234\234\234\377\377\377\376\376\376\377" \ + "\377\377\377\230\377\377\377\1\234\234\236\204::<\12;;=99;::<;;=::<k" \ + "km\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377\377\346" \ + "\377\377\377\1\375\377\376\202\377\377\375\34\377\377\377\376\376\376" \ + "\373\373\363\243\322b\211\307B\212\307<\215\305>\214\306>\212\307>\214" \ + "\305@\217\304>\212\307<\214\306<\214\306>\215\307\77\213\307A\214\306" \ + ">\215\305@\215\307\77\212\307>\244\317c\370\373\362\377\377\373\376\377" \ + "\377\377\376\377\375\376\377\377\377\375\377\376\377\377\377\377\377" \ + "\242\377\377\377\2\222\222\222::<\202;;=\7""99;::<;;=::<99;;;=lln\202" \ + "\377\377\377\1\376\376\376\377\377\377\377\225\377\377\377\3\376\376" \ + "\376\377\377\377jjl\204;;=\2""99;;;=\202::<\2;;=\221\221\223\202\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377" \ + "\343\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \ + "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \ + "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \ + ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \ + "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\377\377\377" \ + "\377\242\377\377\377\2\264\264\264;;=\206::<\6;;=::<FFH\376\376\376\377" \ + "\377\377\376\376\376\377\377\377\377\227\377\377\377\1GGI\204::<\6;;" \ + "=::<;;=::<;;=\302\302\304\206\377\377\377\1\376\376\376\377\377\377\377" \ + "\342\377\377\377\1\377\377\375\202\377\377\377\32\377\376\377\370\373" \ + "\364\243\322b\214\306>\213\310\77\214\305@\215\305>\215\305@\214\306" \ + ">\214\305B\212\307<\215\307=\214\305B\214\306>\215\306A\212\306@\212" \ + "\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377\377\375\376" \ + "\377\377\375\376\377\377\377\377\377\202\377\376\377\377\377\377\377" \ + "\243\377\377\377\2\346\346\346;;=\211::<\1\346\346\350\377\377\377\377" \ + "\230\377\377\377\3\346\346\350::<;;=\202::<\1;;=\205::<\1\346\346\346" \ + "\302\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376" \ + "\376\376\377\377\377\377\233\377\377\377\10\376\376\377\377\377\375\377" \ + "\377\377\377\377\375\377\377\377\377\376\377\377\377\375\376\377\377" \ + "\202\377\377\377\6\370\373\362\243\322b\211\307B\213\310=\214\305@\214" \ + "\306<\202\215\305@\4\214\306<\214\305@\214\306<\215\307\77\202\214\306" \ + ">\6\212\307>\214\306>\215\307\77\214\305@\244\317c\367\375\361\345\377" \ + "\377\377\1\376\376\376\305\377\377\377\3FFF::<;;=\202::<\3;;=::<;;=\202" \ + "::<\1\301\301\303\377\377\377\377\230\377\377\377\4\301\301\30399;::" \ + "<;;=\204::<\3;;=::<GGI\215\377\377\377\1\376\376\376\266\377\377\377" \ + "\1\376\376\376\203\377\377\377\1\376\376\376\377\377\377\377\231\377" \ + "\377\377\6\376\376\377\377\376\377\375\376\377\376\377\377\377\377\375" \ + "\375\377\376\203\377\377\377\27\377\377\375\372\373\366\241\321a\217" \ + "\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306@\214\306>" \ + "\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215\307\77\214" \ + "\306>\242\322b\370\373\362\376\376\377\377\375\376\341\377\377\377\5" \ + "\376\376\376\377\377\377\376\376\376\377\377\377\376\376\376\265\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\212\377\377\377\3\376" \ + "\376\376\377\377\377lll\206::<\202;;=\2::<\234\234\236\377\377\377\377" \ + "\224\377\377\377\1\376\376\376\203\377\377\377\2\233\233\235;;=\203:" \ + ":<\2""99;;;=\202::<\2;;=xxz\213\377\377\377\1\376\376\376\265\377\377" \ + "\377\1\376\376\376\377\377\377\377\240\377\377\377\7\377\377\375\375" \ + "\376\377\376\377\377\376\377\375\377\374\377\377\377\375\375\377\376" \ + "\202\377\377\377\5\372\373\366\240\320b\215\307\77\212\306@\215\305>" \ + "\202\214\305@\20\215\305@\212\306@\214\305D\216\306\77\214\306>\215\307" \ + "\77\214\306>\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373\362" \ + "\377\377\373\377\376\377\377\377\375\377\377\377\377\233\377\377\377" \ + "\3\376\376\376\377\377\377\376\376\376\213\377\377\377\6\376\376\376" \ + "\377\377\377\233\233\233;;=::<;;=\206::<\1lln\377\377\377\377\226\377" \ + "\377\377\3\376\376\376\377\377\377kkm\210::<\2;;=\234\234\236\214\377" \ + "\377\377\1\315\315\315\202\234\234\234\262\234\234\236\2\234\234\234" \ + "\265\265\265\377\377\377\377\240\377\377\377\37\376\377\377\376\377\375" \ + "\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377\370\373" \ + "\362\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<\214\306" \ + ">\214\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215\305>\212" \ + "\307>\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376\377\377" \ + "\376\376\376\376\377\377\344\377\377\377\4\376\376\376\347\347\347\234" \ + "\234\234\235\235\235\260\234\234\236\204\234\234\234\216\377\377\377" \ + "\1\301\301\301\202::<\1;;=\203::<\202;;=\2::<EEG\377\377\377\377\230" \ + "\377\377\377\1FFH\204::<\202;;=\4::<;;=99;\302\302\304\212\377\377\377" \ + "\5\376\376\376\377\377\377\234\234\234::<;;=\263::<\1jjj\205\377\377" \ + "\377\1\376\376\376\377\377\377\377\231\377\377\377\202\377\377\375\3" \ + "\377\374\377\375\377\376\376\377\377\202\377\377\377\25\370\373\364\243" \ + "\322b\217\304@\212\306@\214\305@\215\305>\212\307>\212\306@\214\305B" \ + "\214\305@\214\305B\214\306>\212\307>\212\310\77\214\306>\217\304@\214" \ + "\306>\214\305@\242\322b\370\373\362\377\377\377\202\377\376\377\1\377" \ + "\377\375\346\377\377\377\2\316\316\316:::\263::<\4;;=:::\377\377\377" \ + "\376\376\376\214\377\377\377\3\346\346\346::<;;=\205::<\4;;=::<;;=\346" \ + "\346\346\377\377\377\377\226\377\377\377\2\362\362\362;;=\204::<\3""9" \ + "9;::<;;=\202::<\1\346\346\350\214\377\377\377\2\234\234\234;;=\264::" \ + "<\1kkm\377\377\377\377\240\377\377\377\1\375\377\376\202\377\377\375" \ + "\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215" \ + "\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>" \ + "\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370" \ + "\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375" \ + "\377\376\377\345\377\377\377\2\316\316\31699;\265::<\216\377\377\377" \ + "\2\376\376\376FFH\203::<\1;;=\203::<\3;;=99;\316\316\316\377\377\377" \ + "\377\226\377\377\377\1\317\317\317\206::<\202;;=\4""99;FFH\377\377\377" \ + "\376\376\376\213\377\377\377\1\234\234\236\202::<\1;;=\261::<\2;;=kk" \ + "m\205\377\377\377\1\376\376\376\377\377\377\377\231\377\377\377\3\377" \ + "\376\377\377\377\377\375\377\376\202\377\377\377\11\373\373\363\241\321" \ + "d\214\306>\213\310=\214\306>\214\305@\213\310=\212\306@\217\304>\202" \ + "\215\307=\14\214\306>\215\305>\214\306>\215\305>\217\304@\215\307\77" \ + "\215\307=\242\320c\367\375\361\376\376\377\377\376\377\376\376\376\202" \ + "\377\377\375\2\374\377\377\377\376\377\345\377\377\377\1\316\316\316" \ + "\264::<\202;;=\215\377\377\377\4\376\376\376\377\377\377lln99;\210::" \ + "<\2\234\234\234\376\376\376\377\377\377\377\225\377\377\377\5\234\234" \ + "\234::<;;=99;::<\202;;=\5::<;;=::<kkm\376\376\377\214\377\377\377\1\234" \ + "\234\236\203::<\1:9>\261::<\1kkm\377\377\377\377\237\377\377\377\1\377" \ + "\377\375\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306" \ + ">\213\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215" \ + "\307=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<" \ + "\244\317c\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377" \ + "\377\377\377\202\377\376\377\346\377\377\377\1\316\316\316\266::<\217" \ + "\377\377\377\2\234\234\236;;=\206::<\3""99;;;=www\377\377\377\377\226" \ + "\377\377\377\3\204\204\206::<;;=\207::<\3\222\222\222\377\377\377\376" \ + "\376\376\213\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\210" \ + "\377\377\377\7\376\376\376\377\377\377\377\377\375\376\377\375\376\377" \ + "\377\377\377\377\377\376\377\203\377\377\377\1\376\376\376\203\377\377" \ + "\377\1\376\377\377\203\377\377\377\16\377\377\375\377\377\377\377\376" \ + "\377\377\377\377\377\377\373\376\377\377\377\377\377\377\377\373\371" \ + "\372\364\242\322d\214\306<\215\307\77\214\305@\214\306<\202\215\305@" \ + "\4\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214" \ + "\306>\215\307\77\214\305@\244\317c\367\375\361\356\377\377\377\1\316" \ + "\316\316\266::<\214\377\377\377\1\376\376\376\202\377\377\377\1\266\266" \ + "\266\202::<\1;;=\203::<\1;;=\202::<\3__a\377\377\377\376\376\376\377" \ + "\377\377\377\224\377\377\377\2kkm;;=\202::<\202;;=\202::<\3;;=::<\265" \ + "\265\265\215\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\214" \ + "\377\377\377\2\376\377\377\376\377\375\202\377\377\375\203\377\377\377" \ + "\204\377\377\375\205\377\377\377\1\376\376\377\202\377\377\377\6\377" \ + "\377\375\377\377\377\371\372\362\242\320c\214\305@\215\305@\202\214\306" \ + ">\20\215\305@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305" \ + ">\215\306A\212\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362" \ + "\376\376\377\377\375\376\355\377\377\377\1\316\316\316\266::<\215\377" \ + "\377\377\4\376\376\376\377\377\377\315\315\315;;=\203::<\1;;=\203::<" \ + "\2;;=99;\377\377\377\377\226\377\377\377\203::<\1;;=\202::<\1;;=\203" \ + "::<\2\317\317\317\376\376\376\214\377\377\377\1\234\234\236\265::<\1" \ + "kkm\377\377\377\377\211\377\377\377\3\376\376\376\377\376\377\377\377" \ + "\377\203\377\376\377\204\377\377\377\1\376\376\376\202\377\377\377\1" \ + "\377\376\377\203\377\377\377\1\376\376\376\203\377\377\377\31\376\376" \ + "\377\377\376\377\371\372\365\241\322e\212\307<\216\306\77\212\311<\216" \ + "\303\77\212\307>\215\305@\212\306@\214\305D\216\306\77\214\306>\215\307" \ + "\77\214\306>\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373\362" \ + "\377\377\373\377\376\377\377\377\375\355\377\377\377\1\316\316\316\266" \ + "::<\220\377\377\377\202::<\4;;=::<;;=::<\202;;=\3""99;;;=\346\346\346" \ + "\377\377\377\377\224\377\377\377\2\362\362\362;;=\202::<\7""99;::<;;" \ + "=88:;;=::<;;=\216\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377" \ + "\212\377\377\377\202\376\377\377\202\377\377\377\1\377\376\377\206\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377" \ + "\1\376\376\376\202\377\377\377\6\370\373\364\242\322b\214\306>\214\305" \ + "@\215\305>\214\305@\202\215\306A\20\214\306<\214\306>\216\306\77\215" \ + "\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>\242\321" \ + "a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377\355\377" \ + "\377\377\1\316\316\316\266::<\216\377\377\377\6\376\376\376\377\377\377" \ + "SSU;;=99;;;=\206::<\1\316\316\316\377\377\377\377\224\377\377\377\2\316" \ + "\316\31699;\205::<\1;;=\202::<\1FFH\216\377\377\377\1\234\234\236\265" \ + "::<\1kkm\377\377\377\377\207\377\377\377\202\377\376\377\2\377\377\377" \ + "\377\377\375\203\377\377\377\1\376\377\375\202\377\377\375\203\377\377" \ + "\377\202\377\377\375\2\377\377\377\377\377\375\205\377\377\377\26\377" \ + "\377\375\371\372\362\243\322b\211\305A\215\305>\215\307\77\214\305@\214" \ + "\306>\215\305@\212\307>\214\305@\214\305B\214\306>\212\307>\212\310\77" \ + "\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377\377\377" \ + "\202\377\376\377\1\377\377\375\356\377\377\377\1\316\316\316\266::<\220" \ + "\377\377\377\3kkm::<;;=\202::<\6;;=::<;;=::<;;=\233\233\233\377\377\377" \ + "\377\223\377\377\377\2\376\376\376\265\265\265\205::<\1;;=\202::<\2""9" \ + "9;lln\216\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\207\377" \ + "\377\377\3\376\377\375\375\377\376\377\377\377\202\377\376\377\3\377" \ + "\376\374\377\377\377\376\377\377\202\377\377\377\1\377\377\375\204\377" \ + "\377\377\2\375\377\376\377\377\375\202\377\377\377\1\377\377\375\202" \ + "\377\377\377\32\376\376\374\365\367\354\223\312K\215\305>\214\306<\211" \ + "\305\77\214\306>\212\307>\215\307\77\214\306>\214\306<\214\306>\215\307" \ + "\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362" \ + "\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376" \ + "\377\355\377\377\377\1\316\316\316\266::<\217\377\377\377\5\376\376\376" \ + "\234\234\236;;=::<;;=\202::<\2""99;::<\202;;=\1\221\221\221\377\377\377" \ + "\377\224\377\377\377\1\235\235\235\211::<\2\221\221\223\376\376\376\215" \ + "\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\207\377\377\377" \ + "\1\377\376\377\202\377\377\375\202\377\377\377\202\377\377\375\1\377" \ + "\377\377\202\376\377\377\1\377\377\377\202\377\377\375\5\376\376\377" \ + "\377\377\377\377\377\373\377\377\377\376\376\376\203\377\377\377\27\376" \ + "\376\376\377\377\375\376\377\372\347\365\333\225\311K\217\304>\214\305" \ + "B\215\307\77\212\306B\214\306>\215\306A\214\306>\215\305>\214\306>\215" \ + "\305>\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377" \ + "\376\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\355\377" \ + "\377\377\1\316\316\316\266::<\214\377\377\377\1\376\376\376\203\377\377" \ + "\377\3\250\250\252::<;;=\203::<\202;;=\202::<\1kkk\377\377\377\377\224" \ + "\377\377\377\4www;;=::<;;=\202::<\202;;=\202::<\1\234\234\236\216\377" \ + "\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\207\377\377\377\15" \ + "\367\374\365\343\361\316\316\346\254\305\342\240\304\343\240\303\342" \ + "\236\305\342\237\312\346\251\345\356\317\365\373\357\376\377\377\376" \ + "\376\377\377\377\375\214\377\377\377\24\350\365\333\223\312K\216\306" \ + "\77\212\307>\215\304B\214\306>\215\307=\214\306>\215\306A\212\306@\212" \ + "\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377\377\375\376" \ + "\377\377\375\376\377\377\377\377\377\202\377\376\377\356\377\377\377" \ + "\1\316\316\316\266::<\217\377\377\377\2\376\376\376\316\316\320\207:" \ + ":<\3;;=::<SSS\377\377\377\377\223\377\377\377\2\376\376\376kkm\202::" \ + "<\1;;=\206::<\1\316\316\316\377\377\377\377\276\377\377\377\4\377\377" \ + "\375\376\377\377\377\377\377\377\376\377\202\377\377\377\10\377\377\375" \ + "\377\376\377\376\377\375\376\376\376\377\377\377\350\365\333\277\337" \ + "\224\232\315V\210\214\306>\10\212\306@\212\307>\232\315W\277\337\224" \ + "\352\364\333\377\377\377\377\376\377\377\377\375\202\376\377\377\202" \ + "\377\377\377\2\377\376\377\377\377\375\202\377\377\377\17\377\377\375" \ + "\377\376\377\347\365\333\226\312L\215\306A\213\310=\212\306@\217\304" \ + ">\216\307<\214\305@\215\305<\214\305@\215\307=\244\317c\366\373\364\377" \ + "\377\377\377\276\377\377\377\6\346\346\346;;=99;;;=::<;;=\205::<\377" \ + "\377\377\377\224\377\377\377\1::<\202;;=\2::<;;=\203::<\4;;=::<\316\316" \ + "\316\376\376\376\377\377\377\377\274\377\377\377\14\377\375\377\377\377" \ + "\377\376\376\374\377\377\375\377\376\377\377\377\375\376\377\377\377" \ + "\377\377\376\377\377\377\376\377\324\353\265\231\316Z\202\214\306<\1" \ + "\215\305>\210\214\306>\202\215\305>\16\214\306>\213\307A\211\306;\233" \ + "\314V\324\353\265\377\377\377\377\376\377\377\377\375\375\377\376\376" \ + "\377\377\377\377\377\377\376\377\376\377\377\377\377\373\202\377\377" \ + "\377\6\376\376\377\350\365\333\222\312K\215\306A\217\304>\212\306@\202" \ + "\214\305@\6\213\310\77\212\307>\242\322d\370\373\364\377\377\377\377" \ + "\377\375\377\377\377\377\276\377\377\377\203::<\3;;=::<99;\202;;=\202" \ + "::<\1\346\346\350\377\377\377\377\222\377\377\377\2\376\376\376;;=\202" \ + "::<\202;;=\205::<\377\377\377\377\275\377\377\377\4\377\377\375\377\377" \ + "\377\377\377\373\377\376\374\202\376\377\377\12\377\377\375\377\377\377" \ + "\376\377\375\342\360\317\232\315V\214\306<\220\306=\215\306A\215\306" \ + "C\215\306A\210\214\306>\202\215\307\77\7\215\306A\214\306>\214\305@\213" \ + "\307A\214\305@\230\315W\341\361\315\203\377\377\377\2\376\376\374\374" \ + "\377\375\202\377\377\377\2\377\377\375\377\376\377\202\377\377\377\13" \ + "\352\364\331\221\311J\215\306A\213\310=\216\306\77\214\305@\214\306<" \ + "\242\322e\370\373\364\376\376\377\377\377\375\377\377\377\377\277\377" \ + "\377\377\1``b\202::<\2;;=99;\202;;=\4::<;;=::<\316\316\320\377\377\377" \ + "\377\222\377\377\377\4\316\316\316;;=::<99;\202::<\2;;=::<\202;;=\3:" \ + ":<\376\376\376\377\377\377\202\376\376\376\377\377\377\377\271\377\377" \ + "\377\17\376\377\377\376\376\374\377\376\374\376\377\377\377\377\377\377" \ + "\377\375\376\377\377\370\373\364\277\336\222\215\305<\214\305@\215\307" \ + "\77\212\307>\215\307\77\213\307A\211\214\306>\16\216\306A\214\305B\213" \ + "\307A\214\306>\215\305<\213\305=\215\306A\214\306<\215\305>\300\337\223" \ + "\370\373\362\376\376\377\377\377\375\376\377\377\204\377\377\377\16\377" \ + "\376\377\376\376\377\376\377\377\352\364\331\222\312K\215\306A\214\306" \ + "<\214\305@\243\321d\371\373\360\376\376\377\376\377\377\377\377\377\376" \ + "\377\377\377\377\377\377\273\377\377\377\4\376\376\376\377\377\377\376" \ + "\376\376lln\203::<\1;;=\20299;\1;;=\202::<\1\266\266\270\377\377\377" \ + "\377\222\377\377\377\5\316\316\316::<;;=::<;;=\205::<\3kkm\377\377\377" \ + "\376\376\376\377\377\377\377\274\377\377\377\14\377\377\375\376\377\377" \ + "\377\377\377\377\377\375\376\376\376\367\374\365\244\317c\214\305@\215" \ + "\307=\211\306=\213\307A\215\306A\202\212\306@\1\213\310<\210\214\306" \ + ">\202\212\307>\3\212\307<\214\306>\216\306\77\202\214\306>\12\215\305" \ + "<\215\307\77\212\306@\242\322b\371\374\365\377\377\375\376\376\374\376" \ + "\377\377\377\376\377\376\377\377\202\377\377\377\13\376\377\375\376\376" \ + "\377\377\377\377\350\365\333\225\311K\214\305B\242\320c\371\374\361\377" \ + "\377\377\376\377\377\377\376\377\377\377\377\377\300\377\377\377\7\221" \ + "\221\223::<99;::<;;=::<;;=\203::<\1\234\234\236\377\377\377\377\222\377" \ + "\377\377\2\250\250\25099;\206::<\3;;=::<jjl\377\377\377\377\275\377\377" \ + "\377\202\377\376\377\16\376\377\377\377\377\375\376\376\376\352\364\333" \ + "\223\312K\220\306=\215\306A\214\305B\213\310=\215\306C\215\305>\216\306" \ + "\77\215\305>\215\305@\210\214\306>\37\215\305@\215\307\77\212\306@\215" \ + "\307\77\214\304\77\215\306A\212\307;\212\306@\214\306>\216\307B\214\306" \ + ">\222\312K\354\364\334\377\376\377\377\377\377\377\377\373\376\377\377" \ + "\377\375\376\376\377\375\377\377\377\377\376\377\377\377\377\376\376" \ + "\377\347\365\333\260\327z\371\374\363\375\377\376\376\377\377\377\376" \ + "\377\377\377\377\377\377\375\377\377\377\377\276\377\377\377\3\376\376" \ + "\376\234\234\23699;\203;;=\205::<\1\221\221\223\377\377\377\377\222\377" \ + "\377\377\2\234\234\234;;=\204::<\202;;=\3::<;;=\235\235\237\377\377\377" \ + "\377\276\377\377\377\202\377\377\375\15\376\377\377\367\374\365\223\312" \ + "K\214\306>\213\310\77\215\305@\214\306<\215\307=\214\305@\213\307A\211" \ + "\305\77\215\307\77\215\305>\210\214\306>\20\215\306A\213\305=\215\307" \ + "=\214\305@\215\306A\214\306>\213\304A\220\305\77\216\306\77\212\306@" \ + "\215\305@\213\307A\221\311L\367\375\363\376\377\377\377\377\377\202\377" \ + "\377\373\1\377\375\376\202\377\377\377\4\377\376\377\376\377\377\377" \ + "\376\377\376\377\377\203\377\377\377\3\377\376\377\376\376\377\374\377" \ + "\375\377\377\377\377\277\377\377\377\2\265\265\267<<>\20299;\7::<;;=" \ + "::<99;;;=::<lln\377\377\377\377\222\377\377\377\3\221\221\221::<;;=\205" \ + "::<\3;;=::<\234\234\236\377\377\377\377\276\377\377\377\17\376\377\377" \ + "\377\377\377\366\373\364\244\317c\220\306=\213\310\77\212\306@\211\307" \ + "@\216\306\77\215\305@\215\307\77\213\310\77\215\307\77\215\305>\214\305" \ + "@\210\214\306>\22\216\306A\215\307\77\213\305=\216\306\77\214\306>\212" \ + "\307>\213\310\77\214\305@\215\306C\214\306<\215\307=\215\305>\213\310" \ + "=\242\320d\372\372\362\376\377\375\377\375\377\377\377\375\202\376\377" \ + "\377\5\377\377\377\377\377\375\377\377\377\377\377\375\377\377\377\202" \ + "\377\376\377\5\376\377\375\376\377\377\377\377\377\377\375\376\377\377" \ + "\375\377\377\377\377\274\377\377\377\5\376\376\376\377\377\377\316\316" \ + "\320::<;;=\202::<\1;;=\202::<\3""99;::<kkm\377\377\377\377\222\377\377" \ + "\377\2kkm::<\203;;=\205::<\1\264\264\264\377\377\377\377\275\377\377" \ + "\377\10\377\376\377\376\377\377\377\377\377\300\336\224\212\307>\214" \ + "\306<\214\306>\211\307>\231\214\306>\1\216\306\77\203\214\306>\2\214" \ + "\305@\266\334\207\202\377\377\377\7\377\376\377\377\377\377\377\376\377" \ + "\377\377\375\377\377\377\377\377\375\376\377\377\377\377\377\377\303" \ + "\377\377\377\1\376\376\376\202\377\377\377\1\316\316\316\206::<\6;;=" \ + "::<;;=FFH\377\377\377\376\376\376\205\377\377\377\1\376\376\376\377\377" \ + "\377\377\212\377\377\377\1lln\202::<\3;;=99;;;=\204::<\3\317\317\317" \ + "\377\377\377\376\376\376\377\377\377\377\273\377\377\377\10\377\375\377" \ + "\374\377\375\343\361\320\214\306>\215\306A\214\304=\212\307>\215\305" \ + ">\230\214\306>\20\214\306<\213\304\77\212\307>\212\306B\214\306<\212" \ + "\307>\220\304>\337\363\316\377\376\377\377\377\377\376\377\377\377\377" \ + "\377\376\376\377\377\377\377\376\376\376\376\377\377\377\377\377\377" \ + "\302\377\377\377\1\376\376\376\202\377\377\377\2\376\376\376\377\377" \ + "\377\204::<\1;;=\202::<\3;;=99;;;=\203\377\377\377\1\376\376\376\202" \ + "\377\377\377\1\376\376\376\377\377\377\377\213\377\377\377\2SSU;;=\202" \ + "::<\2;;=99;\204::<\1\315\315\315\203\377\377\377\1\376\376\376\377\377" \ + "\377\377\271\377\377\377\10\376\376\376\377\377\377\233\316W\214\305" \ + "@\212\306@\216\306=\214\305@\215\305@\230\214\306>\17\214\306<\215\306" \ + "C\211\306=\213\307A\214\304\77\212\306@\214\305B\234\313W\376\377\375" \ + "\377\377\377\376\377\375\377\377\375\376\377\377\376\376\377\376\377" \ + "\375\377\377\377\377\302\377\377\377\1\376\376\376\202\377\377\377\4" \ + "\376\376\376\377\377\377\376\376\376;;=\206::<\202;;=\3::<\377\377\377" \ + "\376\376\376\203\377\377\377\3\376\376\376\377\377\377\376\376\376\377" \ + "\377\377\377\212\377\377\377\3::<99;;;=\202::<\10;;=::<;;=99;;;=\363" \ + "\363\363\377\377\377\376\376\376\377\377\377\377\274\377\377\377\7\323" \ + "\354\265\214\305@\215\307\77\215\306A\216\305C\213\304\77\212\307<\230" \ + "\214\306>\20\215\307\77\215\304B\214\305@\214\306>\215\305>\215\307=" \ + "\212\307<\215\307\77\323\351\270\377\376\377\377\377\377\376\376\376" \ + "\376\377\375\376\376\376\376\377\377\377\376\374\377\377\377\377\302" \ + "\377\377\377\202\376\376\376\202\377\377\377\2\376\376\376FFH\210::<" \ + "\2;;=\316\316\316\202\377\377\377\1\376\376\376\377\377\377\377\215\377" \ + "\377\377\1\376\376\376\202;;=\4""99;;;=::<;;=\202::<\2;;=::<\377\377" \ + "\377\377\277\377\377\377\7\231\316X\220\304>\214\305@\215\307\77\214" \ + "\306<\214\311>\214\305@\231\214\306>\11\215\304B\214\306>\215\306A\214" \ + "\306<\215\306A\214\305B\215\307\77\234\315X\375\377\374\204\377\377\377" \ + "\2\376\377\377\377\376\377\377\377\377\377\304\377\377\377\202\376\376" \ + "\376\4\377\377\377jjl::<99;\202;;=\205::<\7\316\316\316\377\377\377\376" \ + "\376\376\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377" \ + "\377\212\377\377\377\6\363\363\363::<99;;;=::<;;=\202::<\1;;=\202::<" \ + "\377\377\377\377\276\377\377\377\2\342\361\320\214\306<\202\215\305>" \ + "\4\212\307>\215\307=\211\306=\215\305>\230\214\306>\2\213\310=\214\306" \ + "<\202\214\305@\7\215\306A\214\306>\215\307=\214\304\77\211\310<\343\362" \ + "\321\377\377\375\202\377\376\377\2\377\377\375\376\376\376\377\377\377" \ + "\377\310\377\377\377\4kkm::<;;=::<\202;;=\202::<\3;;=::<\316\316\316" \ + "\202\377\377\377\1\376\376\376\377\377\377\377\215\377\377\377\3\316" \ + "\316\316::<;;=\202::<\1;;=\204::<\1__a\202\377\377\377\3\376\376\376" \ + "\377\377\377\376\376\376\377\377\377\377\271\377\377\377\4\270\333\207" \ + "\214\306>\214\305@\214\306>\203\214\305@\1\215\305>\230\214\306>\17\215" \ + "\306A\213\310=\212\307<\214\306>\214\306<\215\306A\214\306>\214\305@" \ + "\213\306E\267\332\206\377\377\375\376\377\377\377\377\375\377\377\377" \ + "\377\377\375\377\377\377\377\303\377\377\377\1\376\376\376\204\377\377" \ + "\377\6lln;;=::<99;::<;;=\204::<\1\250\250\250\204\377\377\377\1\376\376" \ + "\376\377\377\377\377\213\377\377\377\1\316\316\316\203::<\1;;=\205::" \ + "<\1lln\203\377\377\377\1\376\376\376\377\377\377\377\272\377\377\377" \ + "\10\232\315V\215\305@\212\306@\215\305>\214\306<\215\304D\215\305<\212" \ + "\306@\230\214\306>\3\217\304@\214\306<\215\306A\202\215\305@\7\214\306" \ + ">\214\305@\212\307>\215\305<\233\316W\376\376\377\376\377\375\203\377" \ + "\377\377\1\376\377\377\377\377\377\377\305\377\377\377\3\376\376\376" \ + "\377\377\377\234\234\236\203::<\2;;=99;\204::<\1\234\234\234\202\377" \ + "\377\377\1\376\376\376\377\377\377\377\215\377\377\377\5\316\316\320" \ + "::<;;=::<;;=\202::<\1;;=\202::<\1kkm\377\377\377\377\266\377\377\377" \ + "\10\375\377\374\376\377\377\376\376\376\377\377\375\377\377\377\376\377" \ + "\377\377\377\375\360\371\350\250\214\306>\4\214\305@\212\307>\360\371" \ + "\346\376\377\375\202\377\377\377\1\377\377\375\377\377\377\377\304\377" \ + "\377\377\1\376\376\376\203\377\377\377\1\234\234\234\211::<\1\234\234" \ + "\234\205\377\377\377\1\376\376\376\377\377\377\377\212\377\377\377\4" \ + "\316\316\320llnkkmlln\203kkm\1jjl\202kkm\1\221\221\223\377\377\377\377" \ + "\270\377\377\377\1\377\376\377\202\377\377\377\3\375\376\377\377\377" \ + "\375\341\361\315\251\214\306>\2\215\307\77\342\360\314\377\377\377\377" \ + "\310\377\377\377\202\376\376\376\202\377\377\377\2\266\266\266kkk\210" \ + "kkm\1\265\265\265\206\377\377\377\1\376\376\376\377\377\377\377\211\377" \ + "\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377\377\377\376" \ + "\376\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376" \ + "\377\377\377\377\264\377\377\377\1\377\376\377\205\377\377\377\2\375" \ + "\377\374\310\340\246\252\214\306>\1\310\340\246\377\377\377\377\307\377" \ + "\377\377\1\376\376\376\202\377\377\377\3\375\375\375\377\377\377\376" \ + "\376\376\211\377\377\377\7\376\376\376\377\377\377\376\376\376\377\377" \ + "\377\376\376\376\377\377\377\376\376\376\377\377\377\377\213\377\377" \ + "\377\1\376\376\376\204\377\377\377\1\376\376\376\206\377\377\377\1\376" \ + "\376\376\377\377\377\377\263\377\377\377\1\377\376\377\204\377\377\377" \ + "\3\376\376\377\376\377\375\304\342\234\251\214\306>\7\215\305@\305\343" \ + "\235\376\376\377\377\377\377\376\376\377\377\376\377\377\377\375\377" \ + "\377\377\377\306\377\377\377\1\376\376\376\217\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\377\377\377\377\214\377\377\377\5\376\376" \ + "\376\377\377\377\376\376\376\377\377\377\376\376\376\203\377\377\377" \ + "\1\376\376\376\377\377\377\377\267\377\377\377\1\377\377\375\202\377" \ + "\377\377\3\377\376\377\376\377\375\305\342\237\251\214\306>\3\215\305" \ + "@\303\344\235\376\376\376\202\377\377\377\1\377\376\377\377\377\377\377" \ + "\305\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\214\377" \ + "\377\377\1\376\376\376\377\377\377\377\216\377\377\377\1\376\376\376" \ + "\203\377\377\377\1\376\376\376\206\377\377\377\1\376\376\376\377\377" \ + "\377\377\266\377\377\377\5\376\377\377\376\376\377\377\376\377\377\377" \ + "\377\305\342\242\251\214\306>\4\215\306A\302\341\236\377\377\375\376" \ + "\376\376\377\377\377\377\305\377\377\377\1\376\376\376\203\377\377\377" \ + "\1\376\376\376\214\377\377\377\1\376\376\376\377\377\377\377\231\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377\264\377" \ + "\377\377\2\376\376\376\377\376\377\202\376\377\377\202\377\377\377\1" \ + "\305\342\240\251\214\306>\7\214\305@\306\343\240\377\376\374\377\377" \ + "\377\376\377\377\377\377\377\376\376\376\377\377\377\377\325\377\377" \ + "\377\1\376\376\376\377\377\377\377\222\377\377\377\1\376\376\376\205" \ + "\377\377\377\1\376\376\376\377\377\377\377\265\377\377\377\4\377\377" \ + "\375\377\376\377\375\377\376\376\377\375\202\377\377\377\1\305\343\235" \ + "\251\214\306>\4\213\310\77\306\341\234\377\376\377\377\377\377\202\376" \ + "\377\375\377\377\377\377\311\377\377\377\1\377\377\375\215\377\377\377" \ + "\1\376\376\376\377\377\377\377\377\377\377\377\314\377\377\377\3\377" \ + "\377\375\377\377\377\376\377\375\203\377\377\377\11\376\377\377\345\360" \ + "\320\214\305@\214\306>\214\305@\214\304\77\214\306<\215\305>\212\307" \ + ">\231\214\306>\1\214\305@\202\215\307\77\205\214\306>\5\212\307>\214" \ + "\306>\342\360\315\377\377\377\376\376\376\202\377\377\377\1\377\377\375" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\244" \ + "\377\377\377\3\377\376\377\377\377\377\376\377\375\203\377\377\377\11" \ + "\376\377\377\362\371\347\214\306>\214\305B\215\310<\215\306A\214\305" \ + "@\215\307\77\214\305@\231\214\306>\4\215\307\77\213\305=\214\306>\215" \ + "\307\77\202\214\306>\5\215\307\77\214\306>\216\306\77\215\306A\360\367" \ + "\345\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\251\377\377\377\2\377\376\377\377\377\375\203\377\377\377\13\377\377" \ + "\375\377\377\377\375\377\374\233\316W\214\305@\213\304\77\212\306@\215" \ + "\307\77\214\305@\215\306A\214\305@\230\214\306>\3\215\307\77\214\306" \ + ">\215\306A\203\214\305@\7\215\306A\214\305@\215\304B\232\315T\377\377" \ + "\375\376\377\377\377\377\375\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\250\377\377\377\1\377\377\375\205\377\377\377" \ + "\11\377\376\377\267\333\204\213\307A\213\307C\215\307\77\213\304\77\215" \ + "\307\77\215\305<\212\306@\231\214\306>\1\215\307\77\203\214\305@\202" \ + "\214\306>\7\215\307\77\212\306@\267\333\204\377\376\377\376\377\377\377" \ + "\377\375\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\247\377\377\377\17\377\377\375\377\377\377\377\377\375" \ + "\376\376\376\377\377\377\377\377\375\376\376\377\334\354\305\211\306" \ + "=\213\307A\213\305;\215\306A\214\306<\215\305>\213\307A\232\214\306>" \ + "\202\214\305@\11\214\306>\214\306<\214\306>\215\307\77\212\311=\333\355" \ + "\305\377\376\377\377\377\377\376\376\376\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\252\377\377\377\3\377\377\375\377" \ + "\377\377\377\376\377\203\377\377\375\7\233\314V\215\307\77\215\305>\214" \ + "\306>\215\307\77\214\305@\212\307>\232\214\306>\14\214\305@\214\306>" \ + "\214\306<\215\307=\215\307\77\214\305@\232\315V\374\377\373\376\376\377" \ + "\377\377\375\377\377\377\376\376\376\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\255\377\377\377\10\377\377\375\377\376" \ + "\377\324\353\267\214\304\77\215\305>\214\305@\212\307<\214\305@\232\214" \ + "\306>\2\215\307\77\215\306A\202\214\306>\4\215\307\77\213\304\77\215" \ + "\306E\316\346\254\202\377\377\377\3\377\377\375\376\376\377\376\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\247" \ + "\377\377\377\1\376\376\376\206\377\377\377\10\377\377\373\375\376\377" \ + "\232\315W\214\306>\215\307=\211\307>\215\306A\215\305>\232\214\306>\1" \ + "\214\305@\202\215\307\77\13\214\305@\215\306E\227\317P\377\377\377\377" \ + "\377\375\376\377\377\377\377\377\377\377\375\375\377\376\377\377\377" \ + "\377\377\375\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\254\377\377\377\20\376\377\377\377\375\377\331\356\303\215\305" \ + "@\213\310\77\215\305>\216\306\77\213\307A\215\306A\214\306<\214\306>" \ + "\216\306\77\213\304\77\212\307<\214\306>\215\305@\210\214\306>\1\214" \ + "\305@\202\215\307\77\205\214\306>\10\214\305@\212\307>\215\305>\214\305" \ + "@\215\305>\214\305@\215\305>\331\356\305\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\264\377\377\377\20\376\376\374\377" \ + "\377\375\376\376\374\261\330{\214\306>\216\306A\214\306>\213\307A\215" \ + "\305>\215\306A\215\307\77\213\304A\215\307\77\214\305@\214\306<\216\306" \ + "A\210\214\306>\4\215\307\77\213\305=\214\306>\215\307\77\202\214\306" \ + ">\12\215\307\77\214\306>\212\307>\220\305\77\212\307>\214\306>\213\310" \ + "=\214\306<\262\327z\376\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\265\377\377\377\17\374\377\377\377\377\377\370" \ + "\373\362\241\321d\211\310<\215\305>\215\305@\216\306=\214\305@\214\306" \ + ">\215\307\77\214\306>\212\307<\212\306@\212\307<\210\214\306>\3\215\307" \ + "\77\214\306>\215\306A\203\214\305@\12\215\306A\214\305@\215\305>\212" \ + "\307>\213\307A\216\305C\215\307=\242\322e\371\372\364\375\377\376\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\264\377" \ + "\377\377\1\375\377\374\203\377\377\377\4\352\364\333\223\311O\212\306" \ + "@\215\305@\202\213\310\77\202\214\306>\4\216\307F\213\305=\215\307\77" \ + "\215\305@\211\214\306>\1\215\307\77\203\214\305@\202\214\306>\1\215\307" \ + "\77\202\214\305@\6\216\305C\215\307\77\225\311K\351\363\332\377\377\377" \ + "\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\265\377\377\377\17\377\375\376\377\376\377\377\377\377\377\377" \ + "\375\352\365\327\223\313L\212\307<\215\305>\214\305@\215\307=\214\305" \ + "@\214\306<\213\310\77\213\304\77\220\305A\212\214\306>\202\214\305@\12" \ + "\214\306>\214\306<\214\306>\215\307\77\214\306>\213\310=\215\307=\225" \ + "\311K\347\365\334\377\377\375\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\267\377\377\377\1\377\377\375\202\377\377\377" \ + "\13\377\376\377\376\377\377\353\363\334\245\320d\214\305B\214\305@\215" \ + "\306A\213\305=\214\306>\213\307A\213\310=\213\214\306>\5\214\305@\214" \ + "\306>\214\306<\215\307=\215\307\77\202\214\305@\5\214\306<\242\322e\351" \ + "\363\332\377\377\375\376\376\376\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\267\377\377\377\1\376\376\374\202\377\377" \ + "\375\6\376\377\377\377\376\377\377\377\375\371\372\364\255\330|\217\304" \ + ">\202\212\306@\2\215\306A\214\303A\202\214\305@\211\214\306>\2\215\307" \ + "\77\215\306A\202\214\306>\6\215\307\77\213\304\77\215\306E\215\305>\262" \ + "\327z\371\372\364\203\377\377\377\2\376\377\377\377\377\375\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\264\377\377\377" \ + "\1\376\376\376\202\377\377\377\2\377\377\375\377\376\377\203\377\377" \ + "\377\6\377\377\375\331\356\303\233\314W\215\310<\214\305@\215\307\77" \ + "\214\214\306>\1\214\305@\202\215\307\77\7\214\305@\215\306E\227\317P" \ + "\331\356\305\376\377\377\375\377\376\376\377\377\202\377\377\377\2\377" \ + "\377\375\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\274\377\377\377\10\377\377\375\377\376\377\365\375\362" \ + "\307\342\237\234\315Z\212\306@\212\307>\214\305@\202\215\307\77\16\214" \ + "\306>\215\307\77\214\306>\215\306A\214\306>\213\310\77\214\306>\215\305" \ + "<\216\306A\213\310\77\212\307>\232\315T\307\341\242\370\373\362\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\304\377\377" \ + "\377\1\377\377\375\202\377\377\377\10\377\376\377\376\376\374\335\354" \ + "\303\270\333\207\222\311J\214\305@\215\306A\213\305=\202\214\306>\13" \ + "\215\307\77\216\306\77\215\305>\212\306@\212\307>\226\312K\270\333\211" \ + "\334\354\307\376\377\377\376\376\376\377\377\375\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\306\377\377\377\2\376\377" \ + "\375\376\377\377\204\377\377\377\16\350\366\334\332\354\302\311\341\245" \ + "\306\341\234\305\342\237\304\341\237\305\342\240\305\342\237\334\355" \ + "\303\352\364\333\377\377\375\377\375\376\377\376\377\377\377\375\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\307\377" \ + "\377\377\15\376\376\376\377\376\377\377\377\375\377\377\373\376\377\377" \ + "\376\377\375\376\377\377\377\377\375\377\377\377\376\376\376\376\377" \ + "\377\376\377\375\377\377\377\202\377\376\377\204\377\377\377\1\376\376" \ + "\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\307\377\377\377\3\376\377\377\377\377\377\376\376\376\202\377\377\377" \ + "\1\376\376\376\210\377\377\377\3\375\377\376\376\377\377\377\377\377" \ + "\203\377\376\377\4\376\377\375\376\377\377\377\377\377\377\376\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\304\377" \ + "\377\377\10\377\377\375\377\376\377\377\377\373\377\377\377\375\377\376" \ + "\376\377\377\376\376\376\377\376\377\202\376\377\377\1\377\377\377\202" \ + "\376\376\376\202\377\377\377\202\376\377\377\5\376\377\375\377\377\377" \ + "\376\376\374\377\377\377\377\377\375\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\307\377\377\377\1\376\376\377\202\377" \ + "\377\377\2\377\377\375\376\376\377\202\377\377\377\2\376\377\375\377" \ + "\377\375\204\377\377\377\202\377\377\375\1\376\377\375\202\376\377\377" \ + "\202\377\377\375\202\377\377\377\1\377\376\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\310\377\377\377\5\377\377\375" \ + "\377\376\377\377\377\375\376\376\377\377\376\377\207\377\377\377\202" \ + "\377\376\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\377\261\377\377\377" \ + "\1\376\376\376\210\377\377\377\3\376\376\376\377\377\377\376\376\376" \ + "\331\377\377\377\1\376\376\376\204\377\377\377\1\376\376\376\257\377" \ + "\377\377\1\376\376\376\212\377\377\377\1\376\376\376\211\377\377\377" \ + "\1\376\376\376\221\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \ + "\376\205\377\377\377\1\376\376\376\312\377\377\377\1\376\376\376\214" \ + "\377\377\377\1\376\376\376\202\377\377\377\6\377\376\375\377\377\377" \ + "\376\377\377\377\377\377\377\376\377\376\377\377\270\377\377\377\7\376" \ + "\377\377\377\376\377\376\377\377\377\377\375\377\377\377\377\375\377" \ + "\377\376\377\273\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \ + "\376\302\377\377\377\1\376\376\376\305\377\377\377\1\376\376\376\241" \ + "\377\377\377\1\376\376\376\214\377\377\377\1\376\376\376\235\377\377" \ + "\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376" \ + "\376\376\202\377\377\377\1\376\376\376\252\377\377\377\1\376\376\376" \ + "\212\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377" \ + "\1\376\376\376\251\377\377\377\202\376\376\376\215\377\377\377\1\376" \ + "\376\376\202\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376" \ + "\224\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\376\376\376\232\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\206\377\377\377\1\376\376" \ + "\376\243\377\377\377\1\376\376\376\204\377\377\377\1\376\376\376\202" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\2" \ + "\376\376\376\377\377\377\202\377\377\375\3\377\377\377\376\377\377\377" \ + "\377\375\202\377\376\377\1\377\377\377\270\377\376\377\14\377\377\377" \ + "\377\376\377\377\376\374\377\377\375\375\376\377\376\377\377\377\377" \ + "\375\376\376\376\377\377\377\376\376\376\377\377\377\376\376\376\203" \ + "\377\377\377\1\376\376\376\266\377\377\377\1\376\376\376\203\377\377" \ + "\377\1\376\376\376\202\377\377\377\1\376\376\376\214\377\377\377\202" \ + "\376\376\376\207\377\377\377\1\376\376\376\272\377\377\377\1\376\376" \ + "\376\252\377\377\377\202\376\376\376\247\377\377\377\5\376\376\376\377" \ + "\377\377\376\376\376\377\377\377\376\376\376\202\377\377\377\1\376\376" \ + "\376\203\377\377\377\1\376\376\376\311\377\377\377\1\376\376\376\221" \ + "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\302\377\377" \ + "\377\1\376\376\376\207\377\377\377\1\346\346\346\204\316\316\316\10\317" \ + "\317\317\315\315\315\316\316\316\363\363\365\377\377\377\376\376\376" \ + "\377\377\377\376\376\376\204\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\376\376\376\234\377\377\377\1\376\376\376\262\377\377\377\1\376\376" \ + "\376\213\377\377\377\1\377\377\375\202\376\377\377\1\376\376\377\202" \ + "\377\377\377\2\377\376\377\377\377\375\270\276\317\331\1\377\376\377" \ + "\205\377\377\377\3\376\377\375\377\377\375\376\376\376\257\377\377\377" \ + "\1\376\376\376\210\377\377\377\202\376\376\376\210\377\377\377\1\376" \ + "\376\376\220\377\377\377\1\376\376\376\207\377\377\377\1\376\376\376" \ + "\243\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\207\377\377\377\1\376\376\376\331\377\377\377\12\376" \ + "\376\376\377\377\377\235\235\235kkmllnkkmllnjjlkkm\346\346\346\202\377" \ + "\377\377\1\376\376\376\237\377\377\377\2\346\346\346\317\317\317\204" \ + "\316\316\316\2\317\317\317\346\346\346\234\377\377\377\1\376\376\376" \ + "\203\377\377\377\1\376\376\376\202\377\377\377\1\332\332\332\203\316" \ + "\316\316\1\317\317\317\202\316\316\316\213\377\377\377\5\346\346\346" \ + "\317\317\317\315\315\315\316\316\316\315\315\315\252\316\316\316\1\363" \ + "\363\363\205\377\377\377\1\376\376\376\212\377\377\377\1\376\376\376" \ + "\211\377\377\377\4\346\346\346\250\250\250\204\204\206``b\202::<\1;;" \ + "=\202::<\3;;=99;;;=\203::<\4lln\220\220\222\266\266\266\363\363\363\202" \ + "\376\376\376\240\377\377\377\1\346\346\346\202\316\316\316\10\317\317" \ + "\317\315\315\315\317\317\317\316\316\316\332\332\332\376\376\376\377" \ + "\377\377\376\376\376\203\377\377\377\1\376\376\376\241\377\377\377\6" \ + "\376\376\376\377\377\377\346\346\346\316\316\320\317\317\321\316\316" \ + "\320\203\316\316\316\2\347\347\347\376\376\376\205\377\377\377\1\376" \ + "\376\376\202\377\377\375\5\376\377\377\377\377\375\377\377\377\317\334" \ + "\344\37V\177\270\0>i\12\37U{\317\334\344\377\376\374\377\377\375\376" \ + "\377\377\377\376\374\376\377\377\376\376\376\377\377\377\363\363\363" \ + "\202\316\316\316\1\315\315\315\202\317\317\317\251\316\316\316\1\332" \ + "\332\332\202\377\377\377\1\376\376\376\203\377\377\377\202\376\376\376" \ + "\204\377\377\377\3\346\346\346\316\316\316\316\316\320\204\316\316\316" \ + "\2\346\346\346\376\376\376\212\377\377\377\1\347\347\347\206\316\316" \ + "\316\2\317\317\317\363\363\363\250\377\377\377\2\376\376\376\331\331" \ + "\331\206\316\316\316\1\332\332\332\202\377\377\377\1\376\376\376\204" \ + "\377\377\377\1\376\376\376\203\377\377\377\3\332\332\332\316\316\316" \ + "\316\316\320\250\316\316\316\1\363\363\363\205\377\377\377\1\376\376" \ + "\376\242\377\377\377\4\346\346\346::<;;=99;\204::<\1\204\204\206\237" \ + "\377\377\377\1\376\376\376\202\377\377\377\3\235\235\235::<;;=\202::" \ + "<\3;;=::<\235\235\235\202\377\377\377\1\376\376\376\232\377\377\377\1" \ + "\376\376\376\205\377\377\377\4kkm;;;99;;;=\202::<\1;;;\213\377\377\377" \ + "\4\234\234\234:::::<;;=\202::<\1;;;\250::<\1\316\316\316\202\377\377" \ + "\377\1\376\376\376\203\377\377\377\1\376\376\376\212\377\377\377\203" \ + "\376\376\376\203\377\377\377\3\346\346\346\250\250\250```\204::<\202" \ + ";;=\202::<\3;;=::<;;=\203::<\1;;=\202::<\5;;=::<```\265\265\265\362\362" \ + "\362\203\377\377\377\1\376\376\376\233\377\377\377\1\234\234\236\204" \ + "::<\5""99;;;=::<\333\333\335\376\376\376\203\377\377\377\1\376\376\376" \ + "\241\377\377\377\4\376\376\376\377\377\377\363\363\363FFH\202::<\1;;" \ + "=\203::<\1\234\234\234\210\377\377\377\6\376\377\377\377\377\375\375" \ + "\376\377\356\363\366\40Vz\0\77h\270\0=i\20\0>i\22Ip\356\363\367\376\377" \ + "\377\377\377\375\377\377\377\376\376\377\377\376\377\377\377\377\315" \ + "\315\315:::::<;;=::<99;;;;\250::<\1kkm\205\377\377\377\1\376\376\376" \ + "\203\377\377\377\4\376\376\376\377\377\377\376\376\376\234\234\234\203" \ + "::<\6;;=::<:::\234\234\234\377\377\377\376\376\376\211\377\377\377\3" \ + "\332\332\332:::;;=\202::<\202;;=\2::<\204\204\206\250\377\377\377\2\364" \ + "\364\364FFF\204::<\202:::\1\234\234\234\206\377\377\377\1\376\376\376" \ + "\204\377\377\377\2kkk;;=\251::<\1\316\316\316\202\377\377\377\1\376\376" \ + "\376\203\377\377\377\1\376\376\376\240\377\377\377\6\376\376\376\234" \ + "\234\236::<;;=::<;;=\203::<\2FFH\362\362\362\235\377\377\377\1\376\376" \ + "\376\203\377\377\377\3\234\234\236::<;;=\202::<\3;;=::<\234\234\236\203" \ + "\377\377\377\1\376\376\376\233\377\377\377\1\376\376\376\203\377\377" \ + "\377\7kkm::<;;=::<;;=::<;;=\213\377\377\377\4\235\235\235::<;;=99;\202" \ + ";;=\251::<\1\315\315\315\203\377\377\377\202\376\376\376\213\377\377" \ + "\377\1\376\376\376\202\377\377\377\6\376\376\376\377\377\377\315\315" \ + "\315\205\205\205::<;;=\213::<\4;;=::<;;=::<\203;;=\204::<\4FFF\204\204" \ + "\204\346\346\346\376\376\376\234\377\377\377\3\234\234\236::<;;=\202" \ + "::<\4;;=99;::<``b\244\377\377\377\1\376\376\376\203\377\377\377\1xxz" \ + "\202::<\10;;=99;;;=::<;;=\233\233\235\377\377\377\376\376\376\202\377" \ + "\377\377\1\376\376\376\203\377\377\377\4\375\377\376\377\376\373\377" \ + "\377\375\235\267\310\202\0>i\271\0=i\4\0\77j\237\266\306\377\376\377" \ + "\377\375\374\202\376\377\377\4\377\377\377\376\376\376\316\316\31699" \ + ";\202;;=\2::<;;=\251::<\1kkm\203\377\377\377\1\376\376\376\210\377\377" \ + "\377\4\235\235\235::<99;;;=\203::<\1\235\235\235\214\377\377\377\2ll" \ + "n99;\202;;=\1::<\203;;=\2\362\362\364\376\376\376\245\377\377\377\2\376" \ + "\376\376\250\250\250\204::<\4;;=::<:::\346\346\346\203\377\377\377\1" \ + "\376\376\376\205\377\377\377\3\376\376\376\377\377\377jjl\252::<\1\315" \ + "\315\315\203\377\377\377\202\376\376\376\242\377\377\377\3\362\362\364" \ + "GGI::<\202;;=\2""99;;;=\202::<\2""99;\235\235\235\237\377\377\377\3\376" \ + "\376\376\377\377\377\235\235\237\202::<\202;;=\202::<\3\235\235\237\377" \ + "\377\377\376\376\376\233\377\377\377\1\376\376\376\203\377\377\377\4" \ + "\376\376\376\377\377\377kkm;;=\202::<\5""99;;;=99;\377\377\377\376\376" \ + "\376\211\377\377\377\1\233\233\233\202::<\3;;=::<99;\251::<\1\317\317" \ + "\317\205\377\377\377\1\376\376\376\214\377\377\377\3\376\376\376\347" \ + "\347\347xxz\203::<\1;;=\202::<\1;;=\204::<\1;;=\203::<\1;;=\205::<\1" \ + ";;=\203::<\1;;=\203::<\2\234\234\236\362\362\362\233\377\377\377\2\233" \ + "\233\235;;=\204::<\1;;=\202::<\1\234\234\236\245\377\377\377\4\376\376" \ + "\376\302\302\304::<;;=\206::<\1\235\235\237\202\377\377\377\1\376\376" \ + "\376\203\377\377\377\7\375\376\377\377\377\377\377\377\375\376\377\377" \ + "\377\377\377\177\235\265\0\77k\271\0\77j\7\0\77k\0\77j~\236\265\377\376" \ + "\377\376\377\377\375\377\374\377\377\375\202\377\377\377\5\315\315\315" \ + ";;=::<99;;;=\252::<\3kkm\377\377\377\376\376\376\203\377\377\377\1\376" \ + "\376\376\203\377\377\377\1\376\376\376\202\377\377\377\3\233\233\233" \ + "::<;;=\202::<\3;;=::<\234\234\234\202\377\377\377\1\376\376\376\211\377" \ + "\377\377\4\264\264\264;;=::<;;=\204::<\3\247\247\251\377\377\377\376" \ + "\376\376\245\377\377\377\1SSS\203::<\1;;=\202::<\1\204\204\204\213\377" \ + "\377\377\4\376\376\376lln::<:9>\250::<\1\317\317\317\205\377\377\377" \ + "\1\376\376\376\241\377\377\377\1\265\265\267\204::<\1;;=\204::<\1FFF" \ + "\241\377\377\377\2\234\234\236;;=\204::<\2;;=\234\234\236\234\377\377" \ + "\377\3\376\376\376\377\377\377\376\376\376\204\377\377\377\1kkm\203:" \ + ":<\4;;=::<;;=\376\376\376\212\377\377\377\1\234\234\234\204::<\1;;=\251" \ + "::<\1\316\316\316\203\377\377\377\202\376\376\376\215\377\377\377\4\234" \ + "\234\234;;=::<;;=\202::<\1""99;\204::<\1;;=\203::<\1;;=\211::<\1""99" \ + ";\207::<\2FFF\301\301\301\232\377\377\377\2\234\234\23699;\210::<\1\333" \ + "\333\333\241\377\377\377\6\376\376\376\377\377\377\376\376\376\363\363" \ + "\363FFH;;=\205::<\3;;=::<\234\234\236\206\377\377\377\7\377\376\377\377" \ + "\377\377\377\377\375\375\376\377\377\376\377\201\235\263\0>g\272\0>i" \ + "\13\0>e\177\236\263\377\375\374\377\377\377\377\377\375\376\376\376\377" \ + "\376\377\377\377\377\316\316\316::<;;=\202::<\2""99;;;=\250::<\1kkm\204" \ + "\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376\376" \ + "\376\202\377\377\377\2\376\376\376\234\234\234\206::<\1\234\234\234\215" \ + "\377\377\377\2RRT;;=\205::<\1SSU\246\377\377\377\2\316\316\316999\206" \ + "::<\1\316\316\316\202\377\377\377\3\376\376\376\377\377\377\376\376\376" \ + "\207\377\377\377\3jjl::<:9>\250::<\1\316\316\316\203\377\377\377\202" \ + "\376\376\376\242\377\377\377\2SSU99;\202;;=\204::<\4;;=99;::<\264\264" \ + "\266\240\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377" \ + "\1kkm\206::<\213\377\377\377\2\234\234\236;;=\216::<\4""99;;;=::<;;=" \ + "\206::<\3;;=::<;;=\222::<\1\316\316\316\205\377\377\377\1\376\376\376" \ + "\207\377\377\377\1\376\376\376\202\377\377\377\2\346\346\350__a\202:" \ + ":<\3;;=::<;;=\204::<\1;;=\202::<\3;;=::<;;=\203::<\1;;=\202::<\2""99" \ + ";;;=\202::<\1;;=\204::<\7;;=::<;;=::<;;=\204\204\206\363\363\363\203" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\222\377\377\377\4" \ + "\234\234\236::<;;=99;\204::<\3;;=::<__a\244\377\377\377\1xxx\205::<\1" \ + ";;=\203::<\1\234\234\236\213\377\377\377\3\177\236\263\0=i\0>i\211\0" \ + "=i\2\0>j\0=i\202\1>j\2\0\77k\0>j\232\0>i\2\0>j\0\77k\202\1>j\2\0=i\0" \ + ">j\211\0=i\3\0>i\0=i\177\236\263\206\377\377\377\6\316\316\316:::::<" \ + ";;=::<;;=\217::<\1;;=\203::<\1;;=\202::<\1;;=\222::<\1kkk\205\377\377" \ + "\377\1\376\376\376\206\377\377\377\1\234\234\236\206::<\1\234\234\236" \ + "\215\377\377\377\3\234\234\234;;=::<\202;;=\203::<\3\316\316\320\377" \ + "\377\377\376\376\376\240\377\377\377\1\376\376\376\202\377\377\377\3" \ + "xxz::<;;=\202::<\3;;=::<__a\215\377\377\377\1kkm\204::<\1;;=\202::<\1" \ + ";;=\242::<\1\316\316\316\205\377\377\377\1\376\376\376\240\377\377\377" \ + "\1\265\265\265\202::<\5;;=::<;;=::<;;=\204::<\2TTV\376\376\376\237\377" \ + "\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206" \ + "::<\213\377\377\377\3\234\234\23499;;;=\214::<\1""99;\207::<\1;;=\227" \ + "::<\1\316\316\316\204\377\377\377\3\376\376\376\377\377\377\376\376\376" \ + "\203\377\377\377\1\376\376\376\204\377\377\377\2\333\333\335FFH\214:" \ + ":<\16``b\221\221\223\251\251\251\315\315\315\316\316\316\363\363\363" \ + "\377\377\377\332\332\332\316\316\316\301\301\301\235\235\237jjlFFH;;" \ + "=\207::<\1;;=\202::<\3;;=__a\363\363\363\227\377\377\377\4\234\234\236" \ + "99;::<;;=\205::<\3;;=::<\233\233\233\240\377\377\377\12\376\376\376\377" \ + "\377\377\301\301\301;;=::<;;=::<;;=::<99;\203::<\1\234\234\236\213\377" \ + "\377\377\3\177\236\263\0=i\0>i\211\0=i\7\1>j\0=i\1>j\0=i\0>g\3>h\2=g" \ + "\230\0=i\7\2=g\3>h\0>g\0=i\1>j\0=i\1>j\211\0=i\3\0>i\0=i\177\236\263" \ + "\206\377\377\377\2\317\317\317:::\221::<\202;;=\202::<\3;;=::<99;\203" \ + "::<\2;;=99;\220::<\1kkk\214\377\377\377\1\234\234\236\206::<\1\234\234" \ + "\236\213\377\377\377\3\376\376\376\377\377\377\363\363\363\204::<\4;" \ + ";=::<;;=xxz\202\377\377\377\1\376\376\376\236\377\377\377\1\376\376\376" \ + "\202\377\377\377\3\346\346\346::<;;=\202::<\4;;=99;;;=\266\266\270\215" \ + "\377\377\377\1kkm\203::<\1;;=\202::<\1;;=\243::<\1\316\316\316\204\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\232\377\377\377\1\376" \ + "\376\376\204\377\377\377\1kkm\202;;=\202::<\202;;=\2::<;;=\204::<\3\317" \ + "\317\317\377\377\377\376\376\376\235\377\377\377\1\234\234\234\206::" \ + "<\1\234\234\234\243\377\377\377\1kkm\206::<\212\377\377\377\1\376\376" \ + "\376\224\377\377\377\1lln\203::<\1;;=\202::<\1\234\234\236\234\377\377" \ + "\377\1\376\376\376\204\377\377\377\4\376\376\376\265\265\267::<;;=\202" \ + "::<\1;;=\202::<\1;;=\203::<\5__a\266\266\270\363\363\363\377\377\377" \ + "\376\376\376\204\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \ + "\376\202\377\377\377\4\301\301\303\204\204\206;;=::<\203;;=\202::<\2" \ + ";;=::<\202;;=\3GGI\332\332\334\376\376\376\203\377\377\377\1\376\376" \ + "\376\221\377\377\377\2\235\235\237::<\202;;=\202::<\1;;=\202::<\4""9" \ + "9;::<;;=\331\331\331\240\377\377\377\2\363\363\363GGI\203::<\2;;=::<" \ + "\203;;=\202::<\1\234\234\236\213\377\377\377\3\177\236\263\0=i\0>i\210" \ + "\0=i\10\0\77k\0=i\1>j\0>i\0\77j\0=i\0>i\0>j\230\0>i\10\0>j\0>i\0=i\0" \ + "\77j\0>i\1>j\0=i\0\77k\210\0=i\3\0>i\0=i\177\236\263\206\377\377\377" \ + "\1\376\376\376\217\377\377\377\1\376\376\376\203\377\377\377\1\315\315" \ + "\317\204::<\3;;=::<kkm\240\377\377\377\1\234\234\236\206::<\1\234\234" \ + "\236\214\377\377\377\3\376\376\376\377\377\377\204\204\206\202::<\1;" \ + ";=\202::<\202;;=\1\345\345\345\242\377\377\377\2\376\376\376\234\234" \ + "\234\206::<\2GGI\363\363\363\215\377\377\377\1kkm\203::<\4""99;::<;;" \ + "=\316\316\320\311\377\377\377\2\317\317\32199;\203::<\5;;=::<FFH;;=:" \ + ":<\202;;=\202::<\1kkm\237\377\377\377\1\234\234\234\206::<\1\234\234" \ + "\234\243\377\377\377\1kkm\206::<\213\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\216\377\377\377\1\376\376\376\202\377\377\377\5lln:" \ + ":<;;=::<;;=\202::<\2\234\234\234\376\376\376\227\377\377\377\1\376\376" \ + "\376\210\377\377\377\1\264\264\266\202;;=\4::<;;=::<99;\204::<\3jjl\317" \ + "\317\321\376\376\376\202\377\377\377\1\375\375\375\203\377\377\377\3" \ + "\376\376\376\377\377\377\376\376\376\204\377\377\377\1\376\376\376\203" \ + "\377\377\377\3\363\363\365\234\234\236FFH\202::<\1;;=\202::<\1;;=\203" \ + "::<\2FFH\332\332\334\225\377\377\377\1\233\233\235\202;;=\211::<\1__" \ + "a\240\377\377\377\2xxz;;=\202::<\3;;=::<;;=\205::<\1\234\234\236\213" \ + "\377\377\377\3\177\236\263\0=i\0>i\211\0=i\202\0>i\5\0<h\1>j\0=i\1>j" \ + "\0>i\230\0=i\5\0>i\1>j\0=i\1>j\0<h\202\0>i\211\0=i\3\0>i\0=i\177\236" \ + "\263\212\377\377\377\3\376\376\376\377\377\377\376\376\376\212\377\377" \ + "\377\1\376\376\376\202\377\377\377\10\316\316\320::<;;=::<;;=99;::<j" \ + "jl\225\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\207\377" \ + "\377\377\1\234\234\236\206::<\1\234\234\236\216\377\377\377\3\332\332" \ + "\332;;=99;\202::<\4;;=::<99;\234\234\236\237\377\377\377\1\376\376\376" \ + "\203\377\377\377\1SSU\202::<\1;;=\203::<\1\221\221\221\216\377\377\377" \ + "\1kkm\206::<\1\316\316\316\250\377\377\377\1\376\376\376\235\377\377" \ + "\377\1\376\376\376\202\377\377\377\5xxz::<;;=::<;;=\202::<\3\316\316" \ + "\320RRT;;=\203::<\4;;=::<\332\332\332\376\376\376\235\377\377\377\1\234" \ + "\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\214\377\377" \ + "\377\3\376\376\376\377\377\377\376\376\376\213\377\377\377\1\376\376" \ + "\376\204\377\377\377\4kkm;;=::<;;=\203::<\1\235\235\235\202\377\377\377" \ + "\1\376\376\376\221\377\377\377\1\376\376\376\213\377\377\377\4\301\301" \ + "\301;;=::<;;=\203::<\202;;=\3::<RRT\316\316\316\203\377\377\377\1\376" \ + "\376\376\202\377\377\377\1\376\376\376\204\377\377\377\3\376\376\376" \ + "\377\377\377\376\376\376\203\377\377\377\1\376\376\376\204\377\377\377" \ + "\4\346\346\346xxz;;=99;\207::<\4GGI\362\362\362\377\377\377\376\376\376" \ + "\222\377\377\377\1\234\234\236\206::<\203;;=\202::<\2;;=\233\233\235" \ + "\236\377\377\377\10\301\301\301::<;;=:9>::<99;::<99;\202;;=\203::<\1" \ + "\234\234\236\213\377\377\377\3\177\236\263\0=i\0>i\210\0=i\7\2=g\0>i" \ + "\0>j\0\77j\0=i\0\77j\0=h\232\1>j\7\0=h\0\77j\0=i\0\77j\0>j\0>i\2=g\210" \ + "\0=i\3\0>i\0=i\177\236\263\213\377\377\377\1\376\376\376\216\377\377" \ + "\377\1\317\317\321\202::<\6;;=::<;;=::<lln\376\376\376\225\377\377\377" \ + "\1\376\376\376\203\377\377\377\1\376\376\376\205\377\377\377\1\234\234" \ + "\236\206::<\1\234\234\236\213\377\377\377\1\376\376\376\203\377\377\377" \ + "\2kkm;;=\204::<\2;;=GGI\236\377\377\377\1\376\376\376\203\377\377\377" \ + "\1\265\265\267\202::<\6;;=::<;;=::<;;=\345\345\345\216\377\377\377\1" \ + "kkm\202::<\5;;=99;;;=99;\317\317\317\244\377\377\377\1\376\376\376\241" \ + "\377\377\377\3\376\376\376\377\377\377\347\347\351\206::<\3``b\377\377" \ + "\377\234\234\236\202::<\1;;=\202::<\4;;=\204\204\206\377\377\377\376" \ + "\376\376\234\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377" \ + "\377\1kkm\206::<\215\377\377\377\1\375\375\375\202\377\377\377\1\376" \ + "\376\376\213\377\377\377\5\376\376\376\377\377\377\376\376\376lln;;=" \ + "\203::<\3;;=::<\234\234\234\234\377\377\377\1\376\376\376\202\377\377" \ + "\377\4\331\331\331FFH::<;;=\202::<\11;;=::<99;;;=\203\203\203\363\363" \ + "\363\376\376\376\377\377\377\376\376\376\222\377\377\377\7\376\376\376" \ + "\377\377\377\376\376\376\377\377\377\300\300\300GGI::<\202;;=\205::<" \ + "\4``b\362\362\362\377\377\377\376\376\376\221\377\377\377\1\234\234\236" \ + "\204::<\202;;=\203::<\5;;=99;::<;;=\332\332\332\234\377\377\377\4\363" \ + "\363\363GGI;;=::<\202;;=\203::<\1;;=\202::<\3;;=::<\234\234\236\213\377" \ + "\377\377\3\177\236\263\0=i\0>i\210\0=i\10\0\77j\0>j\0\77k\0=i\3>h\2=" \ + "g\1>j\0\77k\230\0=i\10\0\77k\1>j\2=g\3>h\0=i\0\77k\0>j\0\77j\210\0=i" \ + "\3\0>i\0=i\177\236\263\232\377\377\377\12\316\316\316;;=::<;;=::<;;=" \ + "::<kkm\377\377\377\376\376\376\222\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\376\376\376\210\377\377\377\1\234\234\236\206::<\1\234\234" \ + "\236\214\377\377\377\1\376\376\376\202\377\377\377\2\266\266\26699;\202" \ + "::<\202;;=\202::<\3\266\266\270\377\377\377\376\376\376\234\377\377\377" \ + "\203\376\376\376\1lln\202;;=\204::<\3xxx\377\377\377\376\376\376\215" \ + "\377\377\377\1kkm\205::<\2;;=\316\316\316\305\377\377\377\1\376\376\376" \ + "\202\377\377\377\1\203\203\205\206::<\4\265\265\267\377\377\377\363\363" \ + "\363GGG\203::<\1;;=\202::<\1\346\346\346\235\377\377\377\1\234\234\234" \ + "\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\216\377\377\377\1\376" \ + "\376\376\220\377\377\377\1jjl\206::<\1\234\234\234\202\377\377\377\1" \ + "\376\376\376\232\377\377\377\3\376\376\376\364\364\364SSU\202::<\7;;" \ + "=::<;;=99;::<;;=\265\265\265\205\377\377\377\203\376\376\376\214\377" \ + "\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376\376\376" \ + "\203\377\377\377\7\332\332\332__a::<;;=::<;;=::<\202;;=\3::<\205\205" \ + "\207\376\376\377\222\377\377\377\3\234\234\236::<;;=\202::<\2;;=99;\202" \ + ";;=\1""99;\202::<\3;;=::<__a\234\377\377\377\1xxz\202;;=\205::<\1;;=" \ + "\202::<\1;;=\202::<\1\234\234\236\213\377\377\377\3\177\236\263\0=i\0" \ + ">i\210\0=i\10\0>i\0=i\0>i\0\77k\0>j\2=g\1\77h\0>l\230\0>i\10\0>l\1\77" \ + "h\2=g\0>j\0\77k\0>i\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\205\377\377" \ + "\377\1\376\376\376\202\377\377\377\1\376\376\376\221\377\377\377\3\316" \ + "\316\316::<;;=\204::<\1kkm\225\377\377\377\202\376\376\376\211\377\377" \ + "\377\1\234\234\236\206::<\1\234\234\236\217\377\377\377\3\376\376\376" \ + "TTV99;\202::<\4""99;;;=::<kkm\240\377\377\377\1\346\346\346\202::<\1" \ + "99;\204::<\1\316\316\316\217\377\377\377\1kkm\204::<\3;;=99;\316\316" \ + "\316\305\377\377\377\7\376\376\376\377\377\377\363\363\363::<;;=::<;" \ + ";=\202::<\1SSU\203\377\377\377\2\204\204\204;;=\203::<\4;;=99;\222\222" \ + "\222\376\376\376\234\377\377\377\1\234\234\234\206::<\1\234\234\234\243" \ + "\377\377\377\1kkm\206::<\214\377\377\377\3\376\376\376\377\377\377\376" \ + "\376\376\220\377\377\377\1kkm\206::<\1\234\234\236\236\377\377\377\1" \ + "\204\204\206\203::<\1;;=\202::<\3;;=::<\265\265\267\221\377\377\377\1" \ + "\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \ + "\376\204\377\377\377\11\376\376\376\363\363\365__a::<;;=::<;;=::<;;=" \ + "\202::<\1\301\301\303\222\377\377\377\2\234\234\236;;=\202::<\10;;=:" \ + ":<;;=FFH::<;;=::<;;=\203::<\1\235\235\237\232\377\377\377\2\301\301\303" \ + ";;=\205::<\2;;=RRT\204::<\3;;=::<\234\234\236\213\377\377\377\3\177\236" \ + "\263\0=i\0>i\210\0=i\7\0>j\2=g\0>g\0>j\40V|o\224\256\177\236\262\232" \ + "\177\236\263\7\177\236\262o\224\256\40V|\0>j\0>g\2=g\0>j\210\0=i\3\0" \ + ">i\0=i\177\236\263\232\377\377\377\3\316\316\316::<;;=\203::<\2;;=kk" \ + "m\232\377\377\377\1\376\376\376\205\377\377\377\1\234\234\236\206::<" \ + "\1\234\234\236\220\377\377\377\2\233\233\235;;=\202::<\1<<>\203::<\1" \ + "\346\346\346\237\377\377\377\1\204\204\204\206::<\2SSU\376\376\376\217" \ + "\377\377\377\1kkm\203::<\4;;=::<;;=\316\316\320\304\377\377\377\1\376" \ + "\376\376\202\377\377\377\2\234\234\236;;=\202::<\4;;=::<;;=\234\234\234" \ + "\203\377\377\377\1\346\346\346\205::<\3;;=FFH\363\363\365\203\377\377" \ + "\377\1\376\376\376\230\377\377\377\1\234\234\234\206::<\1\234\234\234" \ + "\243\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236" \ + "\235\377\377\377\2\316\316\316;;=\202::<\6;;=::<;;=::<:::\265\265\265" \ + "\237\377\377\377\7\376\376\376\363\363\363___::<;;=::<;;=\203::<\2GG" \ + "I\363\363\363\204\377\377\377\1\376\376\376\214\377\377\377\1\234\234" \ + "\234\203::<\202;;=\5::<\266\266\266GGI99;;;=\202::<\1;;=\202::<\1\332" \ + "\332\332\206\377\377\377\1\376\376\376\211\377\377\377\1\376\376\376" \ + "\207\377\377\377\2\363\363\363FFH\206::<\3FFH\301\301\30399;\202::<\202" \ + ";;=\2::<\234\234\236\206\377\377\377\7\377\377\375\377\377\377\377\377" \ + "\375\376\377\377\376\376\376\200\237\263\0\77i\211\0>i\7\0>g\1>j\0>g" \ + "_\210\236\377\377\377\376\377\377\377\376\377\231\377\377\377\10\377" \ + "\377\375\376\377\375\377\377\377\377\377\375`\210\242\3>h\0\77j\1\77" \ + "h\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<" \ + "\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\220\377\377" \ + "\377\1\363\363\363\204::<\202;;=\2""99;\205\205\207\207\377\377\377\1" \ + "\376\376\376\224\377\377\377\4\376\376\376\377\377\377\363\363\363FF" \ + "H\202::<\5;;=99;;;=::<\265\265\265\220\377\377\377\1kkm\206::<\1\316" \ + "\316\316\305\377\377\377\5\376\376\376\364\364\364FFH::<;;=\202::<\4" \ + ";;=FFH\363\363\363\377\377\377\202\376\376\376\6\377\377\377xxz::<;;" \ + "=::<;;=\202::<\1\234\234\236\206\377\377\377\202\376\376\376\224\377" \ + "\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206" \ + "::<\237\377\377\377\1kkm\206::<\1\234\234\236\225\377\377\377\1\376\376" \ + "\376\207\377\377\377\2SSS;;=\202::<\1;;=\203::<\1\234\234\234\202\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\232\377\377\377\1\376" \ + "\376\376\202\377\377\377\4\332\332\332FFH::<;;=\202::<\1;;=\202::<\1" \ + "\222\222\224\205\377\377\377\1\376\376\376\213\377\377\377\3\234\234" \ + "\234::<;;=\202::<\5""99;;;=\315\315\315\250\250\252;;=\206::<\2``b\376" \ + "\376\376\202\377\377\377\1\376\376\376\216\377\377\377\1\376\376\376" \ + "\205\377\377\377\2xxx;;=\202::<\1;;=\203::<\2\300\300\300\317\317\321" \ + "\203::<\1;;=\202::<\1\234\234\236\207\377\377\377\1\377\376\377\202\377" \ + "\377\377\4\377\376\377\201\235\263\0=j\3>j\210\0=i\5\1>j\0=j\37V\177" \ + "\377\376\377\376\376\376\202\377\377\377\1\376\377\377\230\377\377\377" \ + "\10\376\377\377\377\377\375\374\377\377\377\376\374\376\377\377#W\177" \ + "\0>g\0\77i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316" \ + "\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\220\377" \ + "\377\377\2\376\376\376\204\204\206\205::<\3;;=FFH\362\362\362\204\377" \ + "\377\377\202\376\376\376\2\377\377\377\376\376\376\224\377\377\377\3" \ + "\376\376\376\265\265\265;;=\203::<\4;;=99;FFH\363\363\363\220\377\377" \ + "\377\1kkm\206::<\1\316\316\316\306\377\377\377\4\265\265\26599;;;=::" \ + "<\202;;=\2""99;\222\222\224\204\377\377\377\12\376\376\376\316\316\320" \ + ";;=::<;;=99;;;=99;SSU\376\376\376\202\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\226\377\377\377\1\234\234\234\206::<\1\234\234\234\243" \ + "\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\234" \ + "\377\377\377\11\234\234\234::<;;=99;;;=99;::<;;=kkm\241\377\377\377\1" \ + "\376\376\376\202\377\377\377\1\301\301\303\203::<\6;;=99;::<;;=::<\346" \ + "\346\350\203\377\377\377\1\376\376\376\214\377\377\377\1\234\234\234" \ + "\203::<\202;;=\10""99;\316\316\316\377\377\377kkm::<;;=::<;;=\203::<" \ + "\1\235\235\237\203\377\377\377\1\376\376\376\214\377\377\377\1\376\376" \ + "\376\205\377\377\377\3\302\302\304::<;;=\202::<\7""99;;;=99;xxz\377\377" \ + "\377\315\315\315;;=\203::<\3:9>::<\234\234\236\206\377\377\377\3\376" \ + "\377\377\377\377\375\377\377\377\202\377\377\375\3|\237\265\0\77k\0>" \ + "g\210\0=i\10\0@h\3<i~\236\263\376\377\377\377\377\377\377\376\377\377" \ + "\376\374\377\376\377\230\377\377\377\10\377\375\377\377\377\375\377\376" \ + "\374\377\377\377\376\376\374\220\251\275\2=i\0>j\210\0=i\3\0>i\0=i\177" \ + "\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1" \ + "\234\234\236\206::<\1\234\234\236\215\377\377\377\1\376\376\376\203\377" \ + "\377\377\2\332\332\334;;=\206::<\2\266\266\266\376\376\376\202\377\377" \ + "\377\1\376\376\376\202\377\377\377\1\376\376\376\222\377\377\377\1\376" \ + "\376\376\203\377\377\377\1SSS\203::<\4""99;::<;;=\221\221\223\221\377" \ + "\377\377\1kkm\206::<\1\316\316\316\306\377\377\377\4RRT;;=::<;;=\202" \ + "::<\2;;=\345\345\345\202\377\377\377\1\376\376\376\203\377\377\377\2" \ + "__a;;=\202::<\1;;=\202::<\1\264\264\264\206\377\377\377\1\376\376\376" \ + "\224\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1" \ + "kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\226\377\377\377" \ + "\1\376\376\376\204\377\377\377\2\363\363\363FFH\203::<\1;;=\202::<\2" \ + "FFH\346\346\346\204\377\377\377\1\376\376\376\233\377\377\377\1\376\376" \ + "\376\203\377\377\377\3\376\376\376xxz99;\202::<\1""99;\202::<\4;;=\204" \ + "\204\206\377\377\377\376\376\376\202\377\377\377\1\376\376\376\213\377" \ + "\377\377\1\234\234\234\202::<\10;;=99;;;=::<\317\317\317\376\376\376" \ + "\363\363\363GGI\203::<\1;;=\203::<\3\331\331\331\377\377\377\376\376" \ + "\376\202\377\377\377\1\376\376\376\217\377\377\377\5\363\363\363GGI;" \ + ";=::<;;=\202::<\7""99;FFH\363\363\363\377\377\377\316\316\316::<;;=\202" \ + "::<\3:9>::<\234\234\236\207\377\377\377\7\376\377\377\376\376\376\377" \ + "\377\377\377\377\375\377\377\377\377\375\374\376\377\377\210\377\377" \ + "\377\10\376\376\374\376\377\377\354\364\366\377\377\375\376\377\377\377" \ + "\376\374\377\377\375\376\377\377\230\377\377\377\10\377\377\375\376\377" \ + "\377\377\376\375\375\376\377\376\377\377\301\317\330\0>g\0>j\210\0=i" \ + "\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240" \ + "\377\377\377\1\234\234\236\206::<\1\234\234\236\220\377\377\377\5\376" \ + "\376\376\377\377\377kkm::<;;=\202::<\3""99;::<^^`\204\377\377\377\1\376" \ + "\376\376\227\377\377\377\1\316\316\316\202::<\203;;=\202::<\1\347\347" \ + "\347\221\377\377\377\1kkm\206::<\1\316\316\316\303\377\377\377\12\376" \ + "\376\376\377\377\377\301\301\301;;=::<;;=::<99;::<\204\204\206\204\377" \ + "\377\377\4\376\376\376\377\377\377\376\376\376\266\266\266\202::<\5;" \ + ";=::<;;=::<``b\203\377\377\377\1\376\376\376\227\377\377\377\1\234\234" \ + "\234\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\237\377\377\377" \ + "\1kkm\206::<\1\234\234\236\233\377\377\377\1\265\265\267\204::<\4""9" \ + "9;;;=::<\234\234\234\203\377\377\377\3\376\376\376\377\377\377\376\376" \ + "\376\231\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377" \ + "\376\376\376\202\377\377\377\5\363\363\363GGI99;::<;;=\202::<\3;;=::" \ + "<\346\346\346\204\377\377\377\1\376\376\376\212\377\377\377\3\234\234" \ + "\234::<99;\202;;=\202::<\1\315\315\315\202\377\377\377\3\301\301\303" \ + ";;=99;\202;;=\5::<;;=::<``b\376\376\376\202\377\377\377\1\376\376\376" \ + "\215\377\377\377\6\376\376\376\377\377\377\376\376\376xxz::<;;=\203:" \ + ":<\202;;=\1\300\300\302\202\377\377\377\3\316\316\316;;=99;\202::<\3" \ + ";:\77::<\234\234\236\206\377\377\377\2\377\377\375\376\377\375\202\376" \ + "\377\377\4\377\377\375\377\377\377\377\376\377\377\377\375\211\377\377" \ + "\377\1\376\376\374\202\377\377\377\3\377\376\377\377\377\377\375\376" \ + "\377\231\377\377\377\202\376\377\377\5\377\376\377\376\377\377\377\377" \ + "\375\277\320\332\0\77j\211\0=i\3\0>i\0=i\177\236\263\232\377\377\377" \ + "\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234" \ + "\234\236\213\377\377\377\3\376\376\376\377\377\377\376\376\376\204\377" \ + "\377\377\1\265\265\265\202::<\1;;=\204::<\1\315\315\317\204\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\220\377\377\377\1\376\376" \ + "\376\202\377\377\377\3\204\204\204::<;;=\204::<\2yy{\376\376\376\221" \ + "\377\377\377\1kkm\206::<\1\316\316\316\305\377\377\377\4kkm;;=::<;;=" \ + "\203::<\1\316\316\316\210\377\377\377\1TTV\206::<\2\317\317\321\376\376" \ + "\376\231\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377" \ + "\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\233\377\377\377" \ + "\1TTV\202::<\7;;=::<;;=::<RRT\377\377\377\376\376\376\203\377\377\377" \ + "\1\376\376\376\233\377\377\377\1\376\376\376\206\377\377\377\2\233\233" \ + "\235;;=\203::<\4;;=::<;;=\234\234\234\217\377\377\377\4\234\234\234:" \ + ":<;;=99;\203::<\1\316\316\316\203\377\377\377\4xxz;;=::<99;\202::<\3" \ + ";;=::<\234\234\236\216\377\377\377\1\376\376\376\202\377\377\377\16\376" \ + "\376\376\302\302\304::<;;=::<;;=::<;;=::<\221\221\223\377\377\377\376" \ + "\376\376\377\377\377\316\316\316\202::<\202;;=\202::<\1\234\234\236\206" \ + "\377\377\377\2\377\376\377\377\377\377\202\377\376\377\4\376\376\376" \ + "\353\366\374\327\355\370\323\356\371\210\326\356\372\7\325\354\372\327" \ + "\355\372\365\372\376\376\376\376\377\377\377\376\377\377\377\377\373" \ + "\231\377\377\377\2\377\376\377\376\377\375\202\377\377\377\4\374\377" \ + "\377\300\316\327\0=i\1\77h\210\0=i\3\0>i\0=i\177\236\263\232\377\377" \ + "\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1" \ + "\234\234\236\221\377\377\377\4\376\376\376\377\377\377SSU;;=\202::<\4" \ + ";;=99;;;=\204\204\206\203\377\377\377\1\376\376\376\226\377\377\377\11" \ + "\363\363\36399;;;=::<;;=::<;;=::<\316\316\316\202\377\377\377\1\376\376" \ + "\376\217\377\377\377\1kkm\206::<\1\316\316\316\304\377\377\377\1\316" \ + "\316\316\206::<\1kkk\211\377\377\377\2\235\235\23599;\202;;=\6::<;;=" \ + "::<kkm\377\377\377\376\376\376\203\377\377\377\1\376\376\376\224\377" \ + "\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206" \ + "::<\237\377\377\377\1kkm\206::<\1\234\234\236\232\377\377\377\1\332\332" \ + "\332\204::<\1;;=\202::<\4\266\266\270\376\376\376\377\377\377\376\376" \ + "\376\240\377\377\377\1\376\376\376\204\377\377\377\2\363\363\363FFH\202" \ + "::<\5;;=::<;;=::<SSS\217\377\377\377\2\235\235\23599;\205::<\11\316\316" \ + "\316\377\377\377\376\376\376\377\377\377\363\363\363FFH::<;;=99;\203" \ + ";;=\2::<\331\331\333\220\377\377\377\2\363\363\363FFH\202::<\6;;=::<" \ + ";;=::<TTV\364\364\364\203\377\377\377\3\316\316\316<<>99;\202::<\3;;" \ + "=::<\234\234\236\211\377\377\377\4\377\375\376\376\377\377\254\334\363" \ + "Z\266\347\211[\267\350\6\\\266\350X\267\347\326\354\367\377\376\377\376" \ + "\377\377\377\377\375\232\377\377\377\3\377\377\373\375\377\376\376\377" \ + "\377\202\377\377\375\3\276\320\336\0>g\0>i\210\0=i\3\0>i\0=i\177\236" \ + "\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234" \ + "\234\236\206::<\1\234\234\236\223\377\377\377\1\235\235\237\204::<\4" \ + "<<>::<;;=\363\363\363\206\377\377\377\1\376\376\376\222\377\377\377\2" \ + "\234\234\234;;=\205::<\1SSU\204\377\377\377\1\376\376\376\216\377\377" \ + "\377\1kkm\206::<\1\316\316\316\304\377\377\377\1\204\204\204\203::<\1" \ + "99;\202::<\1\265\265\265\211\377\377\377\2\363\363\363FFH\205::<\2;;" \ + "=\346\346\346\231\377\377\377\1\234\234\234\206::<\1\234\234\234\243" \ + "\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\232" \ + "\377\377\377\1\222\222\222\202::<\1;;=\202::<\3;;=FFH\362\362\364\251" \ + "\377\377\377\1\235\235\235\203::<\7;;=::<;;=;;;\331\331\331\377\377\377" \ + "\376\376\376\214\377\377\377\2\234\234\234;;=\205::<\1\316\316\316\202" \ + "\377\377\377\3\376\376\376\377\377\377\301\301\301\205::<\4;;=::<__a" \ + "\376\376\376\216\377\377\377\4\376\376\376yyy::<;;=\205::<\1\316\316" \ + "\320\204\377\377\377\2\316\316\31699;\203::<\3""99;::<\234\234\236\207" \ + "\377\377\377\2\376\377\377\376\376\374\202\377\376\377\3\254\332\362" \ + "Y\267\352[\267\350\210Y\270\350\7[\267\350Y\267\352\326\356\370\376\376" \ + "\377\377\376\377\377\375\377\376\377\377\231\377\377\377\10\377\377\375" \ + "\376\377\377\377\377\377\377\376\377\377\377\375\276\317\331\1>j\0>j" \ + "\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1" \ + "kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\220\377\377\377" \ + "\1\376\376\376\202\377\377\377\4\363\363\365;;=::<;;=\204::<\1\234\234" \ + "\234\231\377\377\377\1SSS\202::<\1;;=\203::<\1\265\265\267\223\377\377" \ + "\377\1kkm\206::<\1\316\316\316\300\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\346\346\350\203::<\4;;=::<;;=SSU\213\377\377\377\1\204\204" \ + "\204\203::<\1;;=\202::<\1\204\204\206\202\377\377\377\1\376\376\376\226" \ + "\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm" \ + "\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\227\377\377\377\1\376" \ + "\376\376\202\377\377\377\3TTV::<;;=\203::<\2;;=\205\205\205\252\377\377" \ + "\377\1\347\347\347\202::<\202;;=\203::<\1\235\235\237\204\377\377\377" \ + "\1\376\376\376\211\377\377\377\1\234\234\234\206::<\1\316\316\316\205" \ + "\377\377\377\1\205\205\205\202::<\6;;=::<;;=::<;;=\234\234\236\213\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\302\302\302\202;;=\203::<\3" \ + ";;=::<\221\221\221\202\377\377\377\1\376\376\376\202\377\377\377\1\316" \ + "\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350" \ + "\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317" \ + "\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \ + "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\224" \ + "\377\377\377\4\204\204\204;;=::<;;=\203::<\1TTT\204\377\377\377\1\376" \ + "\376\376\223\377\377\377\1\300\300\300\203::<\5;;=::<;;=FFF\363\363\363" \ + "\223\377\377\377\1kkm\203::<\4;;=::<;;=\316\316\320\277\377\377\377\14" \ + "\376\376\376\377\377\377\376\376\376\377\377\377\204\204\206::<;;=::" \ + "<99;<<>99;\265\265\267\213\377\377\377\3\346\346\346::<;;=\202::<\1;" \ + ";=\202::<\2\347\347\347\376\376\376\227\377\377\377\1\234\234\234\206" \ + "::<\1\234\234\234\243\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206" \ + "::<\1\234\234\236\226\377\377\377\4\376\376\376\377\377\377\376\376\376" \ + "\346\346\350\202;;=\203::<\3""99;<<>\301\301\301\253\377\377\377\1aa" \ + "c\202::<\1;;=\202::<\2;;=jjl\205\377\377\377\1\376\376\376\210\377\377" \ + "\377\1\234\234\234\206::<\1\316\316\316\202\377\377\377\1\376\376\376" \ + "\202\377\377\377\3\362\362\362SSU;;=\205::<\2;;=\332\332\332\210\377" \ + "\377\377\1\376\376\376\203\377\377\377\2\363\363\363FFH\202::<\202;;" \ + "=\5::<;;=SSS\363\363\363\376\376\376\204\377\377\377\1\316\316\316\206" \ + "::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350" \ + "\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0" \ + ">i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::" \ + "<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\224\377\377" \ + "\377\1\332\332\332\207::<\1\301\301\301\227\377\377\377\1lll\204::<\3" \ + ";;=::<\221\221\221\202\377\377\377\3\376\376\376\377\377\377\376\376" \ + "\376\217\377\377\377\1kkm\204::<\3;;=99;\316\316\316\241\377\377\377" \ + "\1\376\376\376\234\377\377\377\10\376\376\376\377\377\377\376\376\376" \ + "\377\377\377\363\363\363FFH;;=::<\202;;=\3::<FFH\364\364\364\214\377" \ + "\377\377\1xxz\204::<\3;;=::<\233\233\233\230\377\377\377\1\234\234\234" \ + "\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\237\377\377\377\1k" \ + "km\206::<\1\234\234\236\224\377\377\377\1\376\376\376\204\377\377\377" \ + "\4\266\266\270;;=::<;;=\203::<\1""99;\254\377\377\377\3\234\234\234:" \ + ":<;;=\205::<\204\377\377\377\1\376\376\376\211\377\377\377\1\234\234" \ + "\234\206::<\1\316\316\316\203\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\316\316\320\204::<\4;;=99;::<__a\205\377\377\377\1\376\376\376\206" \ + "\377\377\377\4yy{;;=::<;;=\202::<\3;;=::<\316\316\316\206\377\377\377" \ + "\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270" \ + "\350\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276" \ + "\317\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316" \ + "\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236" \ + "\225\377\377\377\1__a\204;;=\5""99;::<yy{\377\377\377\376\376\376\216" \ + "\377\377\377\1\376\376\376\205\377\377\377\1\346\346\346\202::<\203;" \ + ";=\202::<\1\346\346\346\224\377\377\377\1kkm\205::<\2;;=\316\316\316" \ + "\235\377\377\377\1\376\376\376\244\377\377\377\1\234\234\234\202;;=\204" \ + "::<\2\235\235\235\376\376\376\212\377\377\377\4\376\376\376\377\377\377" \ + "\317\317\317::<\202;;=\202::<\3;;=GGI\362\362\362\202\377\377\377\1\376" \ + "\376\376\224\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377" \ + "\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\231\377\377" \ + "\377\1\220\220\222\205::<\3;;=kkm\376\376\376\253\377\377\377\3\316\316" \ + "\316<<>99;\202::<\4;;=::<;;=\331\331\331\215\377\377\377\1\234\234\234" \ + "\206::<\1\316\316\316\207\377\377\377\1\222\222\224\202::<\3;;=99;<<" \ + ">\202::<\4\234\234\236\376\376\376\377\377\377\376\376\376\203\377\377" \ + "\377\1\376\376\376\203\377\377\377\6\302\302\304;;=99;;;=::<;;=\202:" \ + ":<\1\234\234\234\202\377\377\377\1\376\376\376\204\377\377\377\1\316" \ + "\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350" \ + "\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317" \ + "\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \ + "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\225" \ + "\377\377\377\2\265\265\265;;=\202::<\2""99;;;=\202::<\2\347\347\347\376" \ + "\376\376\215\377\377\377\3\376\376\376\377\377\377\376\376\376\204\377" \ + "\377\377\3\221\221\223;;=99;\204::<\3xxz\377\377\377\376\376\376\202" \ + "\377\377\377\202\376\376\376\217\377\377\377\1kkm\202::<\5;;=99;;;=9" \ + "9;\317\317\317\233\377\377\377\1\376\376\376\237\377\377\377\1\376\376" \ + "\376\204\377\377\377\3\376\376\376\377\377\377GGI\202::<\5;;=::<;;=:" \ + ":<\346\346\346\213\377\377\377\1\376\376\376\202\377\377\377\2``b99;" \ + "\202;;=\203::<\3\247\247\247\377\377\377\376\376\376\225\377\377\377" \ + "\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\237\377" \ + "\377\377\1kkm\206::<\1\234\234\236\231\377\377\377\10kkm::<;;=::<;;=" \ + "99;::<\235\235\237\255\377\377\377\202::<\1;;=\204::<\1\301\301\301\215" \ + "\377\377\377\1\234\234\234\206::<\1\316\316\316\206\377\377\377\5\376" \ + "\376\376\364\364\364TTV::<99;\202;;=\203::<\4\332\332\334\376\376\376" \ + "\377\377\377\376\376\376\203\377\377\377\6\376\376\376\377\377\377\363" \ + "\363\363FFH::<;;=\204::<\1__a\210\377\377\377\1\316\316\316\206::<\1" \ + "\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270" \ + "\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0" \ + "=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240" \ + "\377\377\377\1\234\234\236\206::<\1\234\234\236\224\377\377\377\5\376" \ + "\376\376\377\377\377GGI::<;;=\203::<\4;;=\220\220\222\377\377\377\376" \ + "\376\376\214\377\377\377\1\376\376\376\203\377\377\377\10\376\376\376" \ + "\377\377\377\363\363\363FFH::<;;=99;;;=\202::<\1\316\316\320\202\377" \ + "\377\377\1\376\376\376\204\377\377\377\1\376\376\376\215\377\377\377" \ + "\1kkm\206::<\1\316\316\316\277\377\377\377\3\376\376\376\377\377\377" \ + "\265\265\267\204::<\3;;=::<\205\205\205\213\377\377\377\1\376\376\376" \ + "\202\377\377\377\2\376\376\376\265\265\265\202::<\5""99;<<>::<;;=SSU" \ + "\202\377\377\377\1\376\376\376\224\377\377\377\1\234\234\234\206::<\1" \ + "\234\234\234\243\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<" \ + "\1\234\234\236\230\377\377\377\2\376\376\376SSU\204::<\3;;=::<\266\266" \ + "\266\253\377\377\377\3\376\376\376\377\377\377^^`\206::<\1\234\234\234" \ + "\202\377\377\377\1\376\376\376\212\377\377\377\1\234\234\234\206::<\1" \ + "\316\316\316\205\377\377\377\6\376\376\376\377\377\377\376\376\376\315" \ + "\315\317::<;;=\202::<\4;;=99;::<``b\210\377\377\377\4xxz99;<<>::<\202" \ + ";;=\202::<\1\332\332\332\203\377\377\377\1\376\376\376\204\377\377\377" \ + "\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270" \ + "\350\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276" \ + "\317\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316" \ + "\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236" \ + "\226\377\377\377\1\234\234\234\206::<\2FFH\376\376\376\214\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377\3\265\265" \ + "\265;;=99;\202;;=\202::<\1SSU\202\377\377\377\1\376\376\376\223\377\377" \ + "\377\1kkm\203::<\4""99;::<;;=\316\316\320\275\377\377\377\202\376\376" \ + "\376\4\377\377\377\376\376\376SSU;;=\202::<\4;;=::<;;=\332\332\332\215" \ + "\377\377\377\5\376\376\376\377\377\377\376\376\376SSU;;=\204::<\2;;=" \ + "\264\264\264\226\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377" \ + "\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\231\377" \ + "\377\377\207::<\1\316\316\316\254\377\377\377\2\376\376\376lln\202::" \ + "<\1;;=\202::<\4;;=\233\233\233\377\377\377\376\376\376\202\377\377\377" \ + "\1\376\376\376\210\377\377\377\1\234\234\234\206::<\1\316\316\316\203" \ + "\377\377\377\202\376\376\376\204\377\377\377\1\234\234\234\207::<\1\234" \ + "\234\236\205\377\377\377\4\376\376\376\300\300\302::<;;=\205::<\2\234" \ + "\234\234\376\376\376\202\377\377\377\1\376\376\376\205\377\377\377\1" \ + "\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270" \ + "\350\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276" \ + "\317\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316" \ + "\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236" \ + "\226\377\377\377\1\347\347\347\204::<\5;;=99;;;=\265\265\265\376\376" \ + "\376\222\377\377\377\2___99;\202::<\4;;=::<;;=\265\265\265\207\377\377" \ + "\377\1\376\376\376\216\377\377\377\1kkm\203::<\1;;=\202::<\1;;=\233:" \ + ":<\5""99;;;=::<:::\234\234\234\240\377\377\377\2\316\316\316;;=\204:" \ + ":<\2;;=kkm\221\377\377\377\1\234\234\236\203::<\1;;=\202::<\3kkk\377" \ + "\377\377\376\376\376\224\377\377\377\1\234\234\234\206::<\1\234\234\234" \ + "\243\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236" \ + "\231\377\377\377\207::<\1\316\316\316\255\377\377\377\2\221\221\221;" \ + ";=\205::<\1\204\204\204\203\377\377\377\1\376\376\376\211\377\377\377" \ + "\1\234\234\234\206::<\1\316\316\316\210\377\377\377\3\376\376\376\377" \ + "\377\377``b\202::<\7;;=::<;;=::<;;=\332\332\332\376\376\376\202\377\377" \ + "\377\3\376\376\376\363\363\363GGI\203::<\4;;=::<;;=__a\206\377\377\377" \ + "\1\376\376\376\203\377\377\377\1\316\316\316\206::<\1\234\234\236\213" \ + "\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270\350[\267\350" \ + "\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0=i\3\0>i\0=i" \ + "\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377" \ + "\1\234\234\236\206::<\1\234\234\236\227\377\377\377\1\204\204\206\204" \ + "::<\3;;=::<kkk\217\377\377\377\5\376\376\376\377\377\377\376\376\376" \ + "\333\333\333:::\202::<\1;;=\202::<\2FFH\363\363\363\226\377\377\377\1" \ + "kkm\204::<\1;;=\202::<\1;;=\234::<\4;;=::<\234\234\234\376\376\376\237" \ + "\377\377\377\1kkm\206::<\1\316\316\316\221\377\377\377\2\363\363\363" \ + "GGG\204::<\3;;=::<\315\315\315\225\377\377\377\1\234\234\234\206::<\1" \ + "\234\234\234\237\377\377\377\1\376\376\376\203\377\377\377\1kkm\206:" \ + ":<\237\377\377\377\1kkm\206::<\1\234\234\236\230\377\377\377\2\376\376" \ + "\376;;=\203::<\1;;=\202::<\1\363\363\363\252\377\377\377\6\376\376\376" \ + "\377\377\377\376\376\376\234\234\23699;;;=\204::<\1kkm\215\377\377\377" \ + "\1\234\234\234\206::<\1\316\316\316\210\377\377\377\7\377\377\375\377" \ + "\377\377\332\332\332::<;;=::<;;=\203::<\2``b\376\376\376\202\377\377" \ + "\377\2\376\376\376xxz\206::<\2:::\332\332\332\212\377\377\377\1\316\316" \ + "\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211" \ + "[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331" \ + "\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316" \ + "\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\227\377" \ + "\377\377\1\315\315\315\205::<\3;;=::<\332\332\334\221\377\377\377\1\204" \ + "\204\206\205::<\2;;=\205\205\205\227\377\377\377\1kkm\203::<\3;;=::<" \ + ";;=\234::<\1:9>\203::<\1\234\234\236\237\377\377\377\1\331\331\331\202" \ + ";;=\204::<\1SSU\217\377\377\377\5\376\376\376\377\377\377\376\376\376" \ + "\377\377\377\204\204\204\204::<\3;;=99;yyy\203\377\377\377\1\376\376" \ + "\376\221\377\377\377\1\234\234\234\206::<\1\234\234\234\235\377\377\377" \ + "\1\376\376\376\205\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206:" \ + ":<\1\234\234\236\231\377\377\377\203::<\1;;=\203::<\202\377\377\377\1" \ + "\376\376\376\253\377\377\377\2\233\233\235;;=\205::<\3kkm\377\377\377" \ + "\376\376\376\202\377\377\377\1\376\376\376\210\377\377\377\1\234\234" \ + "\234\206::<\1\316\316\316\213\377\377\377\1\234\234\236\202;;=\1""99" \ + ";\203::<\5;;=\235\235\235\377\377\377\376\376\376\302\302\302\207::<" \ + "\1\251\251\251\213\377\377\377\1\316\316\316\206::<\1\234\234\236\213" \ + "\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270\350[\267\350" \ + "\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0=i\3\0>i\0=i" \ + "\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377" \ + "\1\234\234\236\206::<\1\234\234\236\223\377\377\377\1\376\376\376\204" \ + "\377\377\377\1^^`\202::<\202;;=\3::<<<>\204\204\206\213\377\377\377\1" \ + "\376\376\376\204\377\377\377\1\363\363\363\205::<\3;;=::<\346\346\346" \ + "\227\377\377\377\1kkm\204::<\3;;=::<;;=\234::<\1;;=\202::<\1\234\234" \ + "\236\237\377\377\377\4\204\204\20499;::<;;=\203::<\3\266\266\270\377" \ + "\377\377\376\376\376\221\377\377\377\5\346\346\346;;=::<;;=::<\202;;" \ + "=\4::<\346\346\350\377\377\377\376\376\376\202\377\377\377\1\376\376" \ + "\376\217\377\377\377\1\234\234\234\206::<\1\234\234\234\237\377\377\377" \ + "\202\376\376\376\202\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206" \ + "::<\1\234\234\236\224\377\377\377\6\376\376\376\377\377\377\376\376\376" \ + "\377\377\377\376\376\376;;=\206::<\1\331\331\331\255\377\377\377\1\234" \ + "\234\236\202::<\1;;=\203::<\2kkm\376\376\376\202\377\377\377\1\376\376" \ + "\376\211\377\377\377\1\234\234\234\206::<\1\316\316\316\212\377\377\377" \ + "\3\376\376\376\377\377\377___\204::<\7;;=99;::<\332\332\332\363\363\365" \ + "FFH;;=\204::<\3;;=kkm\376\376\376\213\377\377\377\1\316\316\316\206:" \ + ":<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350" \ + "\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0" \ + ">i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::" \ + "<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\224\377\377" \ + "\377\1\376\376\376\203\377\377\377\4\265\265\267::<;;=::<\202;;=\3::" \ + "<FFH\363\363\363\213\377\377\377\1\376\376\376\203\377\377\377\2\251" \ + "\251\251;;=\205::<\1lln\202\377\377\377\1\376\376\376\225\377\377\377" \ + "\1kkm\202::<\2;;=99;\204::<\1;;=\234::<\2;;=\234\234\234\235\377\377" \ + "\377\5\376\376\376\345\345\345;;=::<;;=\202::<\2;;=FFH\215\377\377\377" \ + "\3\376\376\376\377\377\377\376\376\376\205\377\377\377\10xxz;;=::<;;" \ + "=99;;;=::<\204\204\206\202\377\377\377\1\376\376\376\221\377\377\377" \ + "\1\234\234\234\206::<\1\234\234\234\234\377\377\377\1\376\376\376\204" \ + "\377\377\377\3\376\376\376\377\377\377kkm\206::<\237\377\377\377\1kk" \ + "m\206::<\1\234\234\236\231\377\377\377\202::<\1;;=\204::<\1\316\316\316" \ + "\253\377\377\377\3\376\376\376\377\377\377\220\220\222\202;;=\2::<;;" \ + "=\202::<\1\222\222\224\215\377\377\377\1\234\234\234\206::<\1\316\316" \ + "\316\213\377\377\377\3\376\376\376\332\332\332GGI\204::<\10;;=::<__a" \ + "xxz::<;;=::<;;=\202::<\2FFH\346\346\346\214\377\377\377\1\316\316\316" \ + "\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267" \ + "\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0" \ + "=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206" \ + "::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\231\377\377" \ + "\377\10FFH::<;;=99;;;=::<;;=\265\265\265\216\377\377\377\4\376\376\376" \ + "TTV99;;;=\202::<\202;;=\1\301\301\301\230\377\377\377\1kkm\202::<\1;" \ + ";=\204::<\3;;=::<;;=\232::<\5;;=::<\234\234\234\377\377\377\376\376\376" \ + "\232\377\377\377\3\376\376\376\377\377\377\221\221\221\202::<\1""99;" \ + "\203::<\5\234\234\236\377\377\377\376\376\376\377\377\377\376\376\376" \ + "\216\377\377\377\1\376\376\376\202\377\377\377\2\316\316\320::<\202;" \ + ";=\204::<\2\363\363\363\376\376\376\202\377\377\377\1\376\376\376\217" \ + "\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm" \ + "\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\224\377\377\377\1\376" \ + "\376\376\204\377\377\377\1""99;\202::<\1;;=\203::<\1\316\316\316\252" \ + "\377\377\377\10\376\376\376\377\377\377\376\376\376kkm;;=::<;;=99;\202" \ + "::<\1\234\234\236\215\377\377\377\1\234\234\234\206::<\1\316\316\316" \ + "\215\377\377\377\5\247\247\247;;=99;::<;;=\210::<\5""99;::<\250\250\252" \ + "\377\377\377\376\376\376\213\377\377\377\1\316\316\316\206::<\1\234\234" \ + "\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270\350[" \ + "\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0=i\3" \ + "\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377" \ + "\377\377\1\234\234\236\206::<\1\234\234\236\223\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\203\377\377\377\1\234\234\236\202::<\1;" \ + ";=\202::<\2""99;SSU\214\377\377\377\5\376\376\376\377\377\377\301\301" \ + "\301;;=<<>\202::<\3;;=::<SSU\202\377\377\377\1\376\376\376\226\377\377" \ + "\377\1kkm\203::<\1;;=\202::<\1\204\204\206\202\234\234\234\1\235\235" \ + "\235\232\234\234\236\202\234\234\234\1\315\315\315\233\377\377\377\6" \ + "\376\376\376\377\377\377\362\362\362HHJ99;;;=\204::<\2\364\364\364\376" \ + "\376\376\220\377\377\377\1\376\376\376\204\377\377\377\1kkm\206::<\1" \ + "\234\234\234\223\377\377\377\1\234\234\234\206::<\1\234\234\234\242\377" \ + "\377\377\2\376\376\376lln\206::<\237\377\377\377\1kkm\206::<\1\234\234" \ + "\236\231\377\377\377\2TTV99;\202::<\5;;=::<;;=\250\250\250\376\376\376" \ + "\254\377\377\377\1``b\203::<\202;;=\3::<\235\235\237\376\376\376\202" \ + "\377\377\377\1\376\376\376\211\377\377\377\1\234\234\234\206::<\1\316" \ + "\316\316\216\377\377\377\2kkm;;=\203::<\5;;=::<;;=99;;;=\202::<\2;;=" \ + "jjl\216\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377" \ + "\2\255\333\363Y\270\350\211[\267\350\3Y\270\350[\267\350\326\354\371" \ + "\242\377\377\377\3\276\317\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263" \ + "\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234" \ + "\236\206::<\1\234\234\236\224\377\377\377\1\376\376\376\204\377\377\377" \ + "\2\346\346\34699;\202::<\2;;=::<\202;;=\1\315\315\315\212\377\377\377" \ + "\1\376\376\376\202\377\377\377\1yy{\203::<\4;;=99;;;=\250\250\250\202" \ + "\377\377\377\1\376\376\376\226\377\377\377\1kkm\206::<\1\317\317\317" \ + "\240\377\377\377\1\376\376\376\234\377\377\377\1\234\234\234\202::<\2" \ + "99;;;=\202::<\1\204\204\206\203\377\377\377\1\376\376\376\220\377\377" \ + "\377\1\376\376\376\202\377\377\377\2\264\264\264::<\202;;=\203::<\3G" \ + "GI\364\364\364\376\376\376\202\377\377\377\1\376\376\376\216\377\377" \ + "\377\1\234\234\234\206::<\1\234\234\234\241\377\377\377\3\376\376\376" \ + "\377\377\377kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\225" \ + "\377\377\377\202\376\376\376\202\377\377\377\12kkm::<;;=99;::<;;=::<" \ + "\204\204\204\377\377\377\376\376\376\251\377\377\377\4\376\376\376\377" \ + "\377\377::<99;\202;;=\203::<\1\316\316\320\215\377\377\377\1\234\234" \ + "\234\206::<\1\316\316\316\216\377\377\377\5\346\346\350GGI;;=::<;;=\202" \ + "::<\2""99;;;=\202::<\3;;=GGI\346\346\350\216\377\377\377\1\316\316\316" \ + "\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267" \ + "\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0" \ + "=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206" \ + "::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\231\377\377" \ + "\377\2\376\376\376\205\205\205\202::<\5""99;;;=::<;;=\205\205\207\213" \ + "\377\377\377\12\376\376\376\346\346\346::<;;=99;::<99;;;=FFH\363\363" \ + "\363\231\377\377\377\1kkm\202::<\2;;=::<\202;;=\3\316\316\316\377\377" \ + "\377\376\376\376\234\377\377\377\1\376\376\376\236\377\377\377\1SSS\204" \ + "::<\3;;=99;\347\347\351\204\377\377\377\1\376\376\376\215\377\377\377" \ + "\1\376\376\376\205\377\377\377\1SSU\203::<\4;;=99;::<\265\265\265\202" \ + "\377\377\377\1\376\376\376\217\377\377\377\1\234\234\234\206::<\1\234" \ + "\234\234\242\377\377\377\2\376\376\376SSU\206::<\237\377\377\377\1kk" \ + "m\206::<\1\234\234\236\231\377\377\377\4\221\221\223;;=::<;;=\202::<" \ + "\3;;=___\376\376\376\253\377\377\377\1\332\332\332\204::<\1;;=\202::" \ + "<\1\346\346\350\203\377\377\377\1\376\376\376\211\377\377\377\1\234\234" \ + "\234\206::<\1\316\316\316\217\377\377\377\1\250\250\252\204::<\202;;" \ + "=\2::<;;=\202::<\1\265\265\267\217\377\377\377\1\316\316\316\206::<\1" \ + "\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270" \ + "\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0" \ + "=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240" \ + "\377\377\377\1\234\234\236\206::<\1\234\234\236\232\377\377\377\1\316" \ + "\316\316\203::<\2""99;<<>\202::<\1\346\346\350\213\377\377\377\4\221" \ + "\221\223;;=::<;;=\203::<\1\204\204\206\232\377\377\377\1kkm\203::<\1" \ + ";;=\202::<\1\316\316\316\274\377\377\377\2\265\265\267;;=\205::<\1xx" \ + "x\231\377\377\377\1\250\250\250\206::<\1TTV\222\377\377\377\1\234\234" \ + "\234\204::<\3;;=::<\235\235\235\203\377\377\377\1\376\376\376\237\377" \ + "\377\377\202;;=\203::<\3;;=::<\376\376\376\236\377\377\377\1kkm\206:" \ + ":<\1\234\234\236\225\377\377\377\1\376\376\376\203\377\377\377\1\265" \ + "\265\267\204::<\1;;=\202::<\1\363\363\363\253\377\377\377\1\250\250\250" \ + "\204::<\3;;=::<GGI\216\377\377\377\1\234\234\234\206::<\1\316\316\316" \ + "\220\377\377\377\4kkm;;=::<;;=\204::<\3;;=xxx\376\376\376\217\377\377" \ + "\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363" \ + "Y\270\350\212[\267\350\2X\266\351\326\356\370\202\377\377\377\3\377\377" \ + "\375\377\377\377\376\377\375\234\377\377\377\4\377\377\375\276\317\327" \ + "\0\77j\1>j\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316" \ + "\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\233\377" \ + "\377\377\1``b\205::<\2;;=\235\235\237\210\377\377\377\1\376\376\376\202" \ + "\377\377\377\2FFH;;=\205::<\1\346\346\346\202\377\377\377\1\376\376\376" \ + "\227\377\377\377\1kkm\206::<\1\316\316\316\266\377\377\377\1\376\376" \ + "\376\205\377\377\377\5__a::<;;=::<;;=\202::<\1SSU\202kkm\1lln\203kkm" \ + "\1lln\222kkm\4__a;;=99;;;=\204::<\3\301\301\301\377\377\377\376\376\376" \ + "\215\377\377\377\202\376\376\376\1\235\235\235\204::<\3""99;;;=\221\221" \ + "\221\243\377\377\377\203::<\1;;=\202::<\1""99;\237\377\377\377\1kkm\206" \ + "::<\1\234\234\236\231\377\377\377\1\332\332\332\202::<\3;;=::<99;\202" \ + ";;=\1\264\264\264\210\377\377\377\1\376\376\376\232\377\377\377\1\376" \ + "\376\376\206\377\377\377\2\376\376\376xxx\202::<\1;;=\203::<\1xxz\216" \ + "\377\377\377\1\234\234\234\206::<\1\316\316\316\220\377\377\377\3\363" \ + "\363\365FFH;;=\202::<\1;;=\202::<\2FFH\363\363\363\220\377\377\377\1" \ + "\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270" \ + "\350\211[\267\350\10X\267\347Y\267\352\326\354\371\377\377\377\376\376" \ + "\376\377\376\377\377\377\377\377\376\377\234\377\377\377\2\376\376\374" \ + "\277\320\330\212\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \ + "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\233" \ + "\377\377\377\1\265\265\267\203::<\4""99;;;=::<SSU\207\377\377\377\6\376" \ + "\376\376\377\377\377\376\376\376\265\265\265;;=99;\202;;=\4""99;;;=k" \ + "km\377\377\377\202\376\376\376\230\377\377\377\1kkm\206::<\1\316\316" \ + "\316\267\377\377\377\1\376\376\376\203\377\377\377\7\316\316\320<<>9" \ + "9;::<;;=::<99;\203::<\2;;=99;\202::<\1;;=\224::<\1;;=\202::<\1;;=\203" \ + "::<\1kkm\203\377\377\377\1\376\376\376\215\377\377\377\1\300\300\300" \ + "\202::<\11;;=::<99;;;=jjl\377\377\377\376\376\376\377\377\377\376\376" \ + "\376\236\377\377\377\1\346\346\350\206::<\1__a\237\377\377\377\1kkm\206" \ + "::<\1\234\234\236\231\377\377\377\2\376\376\376SSU\206::<\2yy{\376\376" \ + "\376\206\377\377\377\1\376\376\376\234\377\377\377\1\376\376\376\205" \ + "\377\377\377\4\363\363\363::<<<>99;\202::<\3;;=::<\265\265\267\203\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\210\377\377\377\1\234" \ + "\234\234\206::<\1\316\316\316\221\377\377\377\4\301\301\30199;::<;;=" \ + "\202::<\6;;=\301\301\301\377\377\377\376\376\376\377\377\377\376\376" \ + "\376\215\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377" \ + "\2\255\333\363Y\270\350\211[\267\350\6Y\270\350Y\267\352\325\353\370" \ + "\377\377\377\376\377\375\377\375\377\234\377\377\377\5\376\376\376\377" \ + "\377\377\377\377\375\276\317\327\2\77k\211\0=i\3\0>i\0=i\177\236\263" \ + "\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234" \ + "\236\206::<\1\234\234\236\234\377\377\377\1GGI\203::<\1;;=\202::<\2\301" \ + "\301\301\376\376\376\204\377\377\377\1\376\376\376\203\377\377\377\3" \ + "lln::<;;=\202::<\202;;=\4\301\301\303\376\376\376\377\377\377\376\376" \ + "\376\230\377\377\377\1kkm\206::<\1\316\316\316\265\377\377\377\1\376" \ + "\376\376\205\377\377\377\3kkm::<;;=\202::<\2""99;<<>\202::<\3;;=::<;" \ + ";=\202::<\1;;=\222::<\4""99;;;=::<;;=\203::<\1;;=\202::<\3\316\316\316" \ + "\377\377\377\376\376\376\215\377\377\377\3\376\376\376\316\316\316;;" \ + "=\203::<\3;;=::<FFH\234\377\377\377\202\376\376\376\202\377\377\377\3" \ + "\376\376\376\377\377\377\316\316\320\203::<\4;;=::<;;=kkm\237\377\377" \ + "\377\1kkm\206::<\1\234\234\236\226\377\377\377\7\376\376\376\377\377" \ + "\377\376\376\376\377\377\377\204\204\204::<;;=\204::<\2;;=\346\346\346" \ + "\241\377\377\377\1\376\376\376\202\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\202\377\377\377\1\250\250\250\202::<\1<<>\204::<\3\346" \ + "\346\346\377\377\377\376\376\376\202\377\377\377\1\376\376\376\211\377" \ + "\377\377\1\234\234\234\206::<\1\316\316\316\220\377\377\377\14\376\376" \ + "\376\377\377\377yy{::<99;;;=::<xxz\377\377\377\376\376\376\377\377\377" \ + "\376\376\376\203\377\377\377\1\376\376\376\212\377\377\377\1\316\316" \ + "\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211" \ + "[\267\350\10X\267\347Z\266\351\326\356\370\376\377\377\377\377\375\377" \ + "\377\377\377\376\377\376\377\377\234\377\377\377\4\376\376\374\277\320" \ + "\330\0=i\1>j\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \ + "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\234" \ + "\377\377\377\1\234\234\234\206::<\3jjj\377\377\377\376\376\376\204\377" \ + "\377\377\4\376\376\376\377\377\377\332\332\33299;\203::<\3;;=::<SSU\202" \ + "\377\377\377\1\376\376\376\231\377\377\377\1kkm\206::<\1\316\316\316" \ + "\267\377\377\377\5\376\376\376\377\377\377\376\376\376\346\346\350;;" \ + "=\203::<\1;;=\202::<\202;;=\202::<\3""99;::<;;=\222::<\202;;=\3""99;" \ + "::<;;=\202::<\1;;=\203::<\2\204\204\206\376\376\376\217\377\377\377\1" \ + "\363\363\363\203::<\6;;=::<;;=::<\347\347\347\376\376\376\234\377\377" \ + "\377\202\376\376\376\5\377\377\377\376\376\376\234\234\236::<;;=\202" \ + "::<\3;;=::<\234\234\236\237\377\377\377\1kkm\206::<\1\234\234\236\231" \ + "\377\377\377\5\376\376\376\316\316\316;;=99;;;=\204::<\1\222\222\224" \ + "\204\377\377\377\1\376\376\376\235\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\376\376\376\203\377\377\377\5SSU;;=::<99;;;=\202::<\3kkk\377" \ + "\377\377\376\376\376\203\377\377\377\1\376\376\376\211\377\377\377\1" \ + "\234\234\234\206::<\1\316\316\316\222\377\377\377\6\363\363\363GGI::" \ + "<;;=FFH\363\363\363\205\377\377\377\1\376\376\376\214\377\377\377\1\316" \ + "\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350" \ + "\212[\267\350\3Y\267\352\330\354\363\376\377\377\203\377\377\377\1\377" \ + "\377\375\235\377\377\377\3\276\317\331\0=i\1>j\210\0=i\3\0>i\0=i\177" \ + "\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1" \ + "\234\234\236\206::<\1\234\234\236\233\377\377\377\2\376\376\376\347\347" \ + "\347\202::<\2;;=::<\203;;=\1\346\346\346\207\377\377\377\5\204\204\204" \ + "<<>99;::<;;=\202::<\2\251\251\251\376\376\376\205\377\377\377\1\376\376" \ + "\376\225\377\377\377\1kkm\206::<\1\316\316\316\264\377\377\377\1\376" \ + "\376\376\205\377\377\377\3\204\204\206::<;;=\203::<\1;;=\205::<\1;;=" \ + "\225::<\3;;=::<;;=\202::<\1;;=\202::<\1;;=\202::<\1\347\347\347\220\377" \ + "\377\377\2SSU;;=\203::<\3;;=::<\265\265\265\237\377\377\377\7\376\376" \ + "\376\377\377\377lln99;::<;;=99;\202::<\1\265\265\267\237\377\377\377" \ + "\1kkm\206::<\1\234\234\236\225\377\377\377\1\376\376\376\204\377\377" \ + "\377\3\376\376\376SSU;;=\204::<\3;;=FFH\346\346\346\202\377\377\377\1" \ + "\376\376\376\237\377\377\377\1\376\376\376\204\377\377\377\2\265\265" \ + "\267;;=\202::<\1;;=\203::<\1\265\265\265\217\377\377\377\1\234\234\234" \ + "\206::<\1\316\316\316\223\377\377\377\4\301\301\301::<:::\302\302\302" \ + "\223\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2" \ + "\255\333\363Y\270\350\212[\267\350\2Y\270\350\332\354\370\202\377\377" \ + "\377\3\376\376\376\376\377\377\377\376\373\235\377\377\377\1\276\317" \ + "\331\202\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \ + "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\235" \ + "\377\377\377\1\204\204\204\206::<\1\221\221\223\206\377\377\377\2\363" \ + "\363\363GGI\202::<\5""99;;;=::<GGI\363\363\363\204\377\377\377\202\376" \ + "\376\376\226\377\377\377\1kkm\206::<\1\316\316\316\266\377\377\377\1" \ + "\376\376\376\202\377\377\377\3\346\346\350::<;;=\204::<\5""99;;;=:::" \ + "99;;;=\203::<\3;;=99;;;=\220::<\5;;=::<;;=::<;;=\202::<\6;;=::<99;;;" \ + "=::<\204\204\206\220\377\377\377\5yy{99;::<99;;;=\202::<\1xxz\236\377" \ + "\377\377\10\376\376\376\377\377\377\363\363\36399;::<;;=99;;;=\202::" \ + "<\2\346\346\350\376\376\376\236\377\377\377\1kkm\206::<\1\234\234\236" \ + "\231\377\377\377\3\376\376\376\377\377\377\233\233\235\202::<\7;;=::" \ + "<;;=99;;;=\204\204\204\376\376\376\245\377\377\377\2\363\363\363SSU\205" \ + "::<\2;;=FFH\205\377\377\377\3\376\376\376\377\377\377\376\376\376\210" \ + "\377\377\377\1\234\234\234\206::<\1\316\316\316\224\377\377\377\3\205" \ + "\205\205\221\221\221\376\376\376\204\377\377\377\202\376\376\376\215" \ + "\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255" \ + "\333\363Y\270\350\212[\267\350\7Y\270\350\321\356\376\377\376\377\377" \ + "\377\377\377\377\375\376\377\375\377\376\377\232\377\377\377\1\377\377" \ + "\375\202\377\377\377\3\275\317\333\0\77k\0>i\210\0=i\3\0>i\0=i\177\236" \ + "\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234" \ + "\234\236\206::<\1\234\234\236\235\377\377\377\1\316\316\316\206::<\1" \ + "FFH\203\377\377\377\1\376\376\376\202\377\377\377\1\250\250\250\203:" \ + ":<\1;;=\202::<\1\204\204\206\203\377\377\377\1\376\376\376\231\377\377" \ + "\377\1kkm\206::<\1\316\316\316\271\377\377\377\1\234\234\236\204::<\4" \ + ";;=::<kkm\234\234\236\202\234\234\234\1\233\233\233\202\234\234\234\3" \ + "\235\235\235\234\234\234\235\235\235\224\234\234\234\202\234\234\236" \ + "\1\204\204\206\206::<\2FFH\363\363\363\217\377\377\377\2\250\250\252" \ + ";;=\206::<\1\364\364\364\237\377\377\377\2\265\265\265;;=\205::<\1TT" \ + "V\240\377\377\377\1kkm\206::<\1\234\234\236\224\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\204\377\377\377\3\364\364\366FFH;;=\203" \ + "::<\4;;=::<:::\316\316\316\245\377\377\377\1\221\221\221\202::<\2;;=" \ + "::<\202;;=\2::<\234\234\236\220\377\377\377\1\234\234\234\206::<\1\316" \ + "\316\316\224\377\377\377\1\376\376\376\225\377\377\377\1\316\316\316" \ + "\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\212[\267" \ + "\350\4[\267\346\265\340\361\377\376\377\376\376\377\202\377\377\375\1" \ + "\374\377\377\230\377\377\377\3\376\376\376\377\377\377\377\377\375\202" \ + "\377\377\377\3\243\265\301\0>j\0>i\210\0=i\3\0>i\0=i\177\236\263\232" \ + "\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236" \ + "\206::<\1\234\234\236\236\377\377\377\2__a;;=\204::<\5;;=\265\265\265" \ + "\376\376\376\377\377\377\376\376\376\202\377\377\377\1SSU\204::<\3;;" \ + "=::<\346\346\350\235\377\377\377\1kkm\206::<\1\316\316\316\270\377\377" \ + "\377\2\363\363\365GGI\205::<\3;;=\333\333\333\376\376\376\237\377\377" \ + "\377\10FFH::<;;=::<;;=99;;;=\233\233\235\217\377\377\377\5\346\346\346" \ + "::<;;=::<;;=\203::<\1\234\234\234\210\377\377\377\1\376\376\376\217\377" \ + "\377\377\1\376\376\376\206\377\377\377\1TTT\205::<\3;;=\221\221\221\376" \ + "\376\376\237\377\377\377\1kkm\206::<\1\234\234\236\234\377\377\377\12" \ + "\233\233\233::<;;=::<;;=::<;;=::<SSU\363\363\363\212\377\377\377\3\376" \ + "\376\376\377\377\377\376\376\376\221\377\377\377\1\376\376\376\204\377" \ + "\377\377\1\315\315\317\203::<\1;;=\203::<\2FFH\363\363\365\220\377\377" \ + "\377\1\234\234\234\206::<\1\316\316\316\252\377\377\377\1\316\316\316" \ + "\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267" \ + "\350\6Y\270\350[\267\346\227\324\363\377\375\376\377\377\377\376\377" \ + "\375\213\377\377\377\6\376\376\376\377\377\377\373\377\376\377\377\377" \ + "\377\376\377\376\377\377\211\377\377\377\10\377\376\377\374\377\377\377" \ + "\377\375\377\377\377\377\376\377_\207\240\0>l\0\77j\210\0=i\3\0>i\0=" \ + "i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377" \ + "\1\234\234\236\206::<\1\234\234\236\236\377\377\377\1\265\265\265\204" \ + "::<\3;;=::<__a\204\377\377\377\1\317\317\321\206::<\1kkk\236\377\377" \ + "\377\1kkm\206::<\1\316\316\316\267\377\377\377\3\376\376\376\250\250" \ + "\25299;\202;;=\203::<\1kkm\233\377\377\377\1\376\376\376\205\377\377" \ + "\377\10\234\234\236;;=::<;;=::<;;=99;GGI\204\377\377\377\3\376\376\376" \ + "\377\377\377\376\376\376\210\377\377\377\5\376\376\376__a::<;;=99;\203" \ + ";;=\2FFH\363\363\363\204\377\377\377\3\376\376\376\377\377\377\376\376" \ + "\376\224\377\377\377\5\376\376\376\377\377\377\301\301\301:::;;=\202" \ + "::<\202;;=\4::<\332\332\332\377\377\377\376\376\376\236\377\377\377\1" \ + "kkm\206::<\1\234\234\236\233\377\377\377\3\376\376\376\364\364\364FF" \ + "H\205::<\4;;=99;xxx\376\376\376\203\377\377\377\1\376\376\376\203\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\224\377\377\377" \ + "\4\376\376\376\377\377\377\362\362\362GGI\202::<\6;;=::<;;=::<99;\250" \ + "\250\252\221\377\377\377\1\234\234\234\206::<\1\316\316\316\252\377\377" \ + "\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363" \ + "Y\270\350\211[\267\350\7Y\267\352X\267\347[\266\353\301\344\367\377\377" \ + "\377\376\376\376\376\377\377\211\377\377\377\6\377\376\377\377\377\377" \ + "\377\375\376\377\377\377\377\377\375\377\376\377\202\377\377\377\210" \ + "\377\376\377\10\377\377\375\376\377\377\377\377\377\376\377\375\237\266" \ + "\306\0=i\2=g\0>e\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316" \ + "\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236" \ + "\237\377\377\377\1EEG\202::<\202;;=\11""99;;;=\332\332\332\377\377\377" \ + "\376\376\376\377\377\377xxz::<;;=\204::<\1\302\302\302\236\377\377\377" \ + "\1kkm\206::<\1\316\316\316\266\377\377\377\4\376\376\376\377\377\377" \ + "SSU;;=\202::<\1;;=\202::<\1\316\316\320\235\377\377\377\15\376\376\376" \ + "\377\377\377\376\376\376\377\377\377\363\363\365::<;;=99;;;=::<;;=::" \ + "<\265\265\265\215\377\377\377\3\376\376\376\377\377\377\266\266\270\202" \ + "::<\1;;=\203::<\2;;=\204\204\206\205\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\213\377\377\377\1\376\376\376\205\377\377\377\1\376" \ + "\376\376\202\377\377\377\2\363\363\363SSU\203::<\4;;=99;;;=SSU\241\377" \ + "\377\377\1kkm\206::<\1\234\234\236\235\377\377\377\3\265\265\265;;=9" \ + "9;\202::<\1;;=\203::<\1\204\204\206\206\377\377\377\1\376\376\376\216" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\206\377\377\377\6" \ + "\376\376\376\377\377\377\362\362\364``b::<;;=\202::<\1;;=\202::<\2aa" \ + "c\376\376\376\221\377\377\377\1\234\234\234\206::<\1\316\316\316\252" \ + "\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255" \ + "\333\363Y\270\350\211[\267\350\10X\267\347[\267\346[\265\347[\267\346" \ + "\230\320\361\327\360\367\325\356\365\331\355\370\210\326\354\371\10\325" \ + "\355\367\323\355\372\366\373\377\377\376\374\376\377\375\276\320\332" \ + "\277\320\330\301\317\330\210\276\317\331\10\276\317\327\276\320\334\301" \ + "\316\327_\207\241\0>i\0=l\0\77k\0>i\210\0=i\3\0>i\0=i\177\236\263\232" \ + "\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236" \ + "\206::<\1\234\234\236\237\377\377\377\3\222\222\224::<;;=\202::<\3;;" \ + "=99;\205\205\207\202\377\377\377\2\346\346\346;;=\202::<\1;;=\202::<" \ + "\1SSU\237\377\377\377\1kkm\206::<\1\316\316\316\267\377\377\377\5\265" \ + "\265\26799;;;=::<;;=\202::<\1TTV\243\377\377\377\1\204\204\206\205::" \ + "<\2;;=SSU\206\377\377\377\1\376\376\376\210\377\377\377\3\376\376\376" \ + "GGI;;=\202::<\5;;=::<;;=::<\301\301\303\203\377\377\377\1\376\376\376" \ + "\214\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\376\376\376\204\377\377\377\3\204\204\206;;=::<\202;;=\203" \ + "::<\1\265\265\265\241\377\377\377\1kkm\206::<\1\234\234\236\236\377\377" \ + "\377\12kkk::<99;;;=::<99;;;=::<;;=\204\204\206\210\377\377\377\202\376" \ + "\376\376\213\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376" \ + "\202\377\377\377\1\376\376\376\202\377\377\377\2\364\364\366__a\206:" \ + ":<\3;;=::<\332\332\332\222\377\377\377\1\234\234\234\206::<\1\316\316" \ + "\316\252\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377" \ + "\2\255\333\363Y\270\350\211[\267\350\3\\\266\350X\270\352\\\266\352\202" \ + "[\267\350\3X\267\347Y\270\350Z\266\347\210Y\270\350\10[\267\350[\265" \ + "\351\327\355\372\376\377\377\377\377\375\0>j\0>i\1\77h\210\0>i\10\0\77" \ + "k\0>g\2=g\0=i\0\77j\0<h\0\77h\1>j\210\0=i\3\0>i\0=i\177\236\263\232\377" \ + "\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206" \ + "::<\1\234\234\236\236\377\377\377\2\376\376\376\346\346\346\202::<\10" \ + ";;=::<99;;;=::<\363\363\363\377\377\377\234\234\236\202::<\6;;=::<;;" \ + "=::<\250\250\250\376\376\376\236\377\377\377\1kkm\206::<\1\316\316\316" \ + "\267\377\377\377\10kkm;;=::<;;=99;::<;;=\264\264\266\236\377\377\377" \ + "\1\376\376\376\204\377\377\377\2\346\346\346;;=\202::<\202;;=\202::<" \ + "\2\316\316\320\376\376\376\203\377\377\377\1\376\376\376\205\377\377" \ + "\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\3\234\234" \ + "\234::<;;=\202::<\6;;=::<;;=GGI\332\332\332\376\376\376\224\377\377\377" \ + "\1\376\376\376\203\377\377\377\2\266\266\266;;=\202::<\6;;=::<;;=::<" \ + "SSU\376\376\376\241\377\377\377\1kkm\206::<\1\234\234\236\236\377\377" \ + "\377\2\363\363\363GGI\203::<\1;;=\203::<\3""99;\204\204\204\363\363\363" \ + "\225\377\377\377\1\376\376\376\204\377\377\377\4\376\376\376\346\346" \ + "\346``b::<\202;;=\3::<99;<<>\202::<\1\250\250\250\223\377\377\377\1\234" \ + "\234\234\206::<\1\316\316\316\252\377\377\377\1\316\316\316\206::<\1" \ + "\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\10Y" \ + "\270\350X\270\353Y\267\352X\266\351X\271\346[\267\350\\\266\353[\267" \ + "\350\210Y\270\350\7X\267\345]\267\351\323\355\372\377\376\377\376\377" \ + "\377\4=h\0>g\211\0=i\10\2=i\0@j\0>i\1>j\0>i\1\77h\0>g\0>j\210\0=i\3\0" \ + ">i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377" \ + "\377\377\1\234\234\236\206::<\1\234\234\236\237\377\377\377\6\376\376" \ + "\376yy{::<;;=::<;;=\202::<\4\251\251\251\376\376\376SSU;;=\203::<\3;" \ + ";=FFH\363\363\363\237\377\377\377\1kkm\206::<\1\316\316\316\264\377\377" \ + "\377\5\376\376\376\377\377\377\315\315\317::<;;=\204::<\2FFH\376\376" \ + "\376\237\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376kkm;" \ + ";=\204::<\6""99;lln\377\377\377\376\376\376\377\377\377\376\376\376\202" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\205\377\377\377\10" \ + "\376\376\376\377\377\377SSU::<99;;;=99;;;=\202::<\2FFF\332\332\332\203" \ + "\377\377\377\1\376\376\376\212\377\377\377\1\376\376\376\210\377\377" \ + "\377\1\265\265\265\206::<\3""99;::<\265\265\265\203\377\377\377\1\376" \ + "\376\376\236\377\377\377\1kkm\206::<\1\234\234\236\233\377\377\377\1" \ + "\376\376\376\203\377\377\377\1\331\331\331\204::<\3""99;;;=99;\202;;" \ + "=\2^^^\332\332\332\202\377\377\377\1\376\376\376\216\377\377\377\1\376" \ + "\376\376\206\377\377\377\5\376\376\376\316\316\316FFH::<;;=\204::<\7" \ + "99;::<\204\204\204\377\377\377\376\376\376\377\377\377\376\376\376\220" \ + "\377\377\377\1\234\234\234\206::<\1\316\316\316\252\377\377\377\1\316" \ + "\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350" \ + "\213[\267\350\6Y\270\350[\266\353[\267\350]\267\351X\266\351X\270\350" \ + "\210[\267\350\10X\266\351Z\266\351\326\354\367\377\376\377\376\377\372" \ + "\0>j\0>i\1>j\210\0=i\10\1\77h\0=h\0>i\1\77h\0>j\0=i\0>i\1>j\210\0=i\3" \ + "\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377" \ + "\377\377\1\234\234\236\206::<\1\234\234\236\237\377\377\377\2\376\376" \ + "\376\316\316\316\203::<\1;;=\202::<\4SSU\265\265\267;;=99;\202::<\5;" \ + ";=99;\204\204\204\377\377\377\376\376\376\236\377\377\377\1kkm\206::" \ + "<\1\316\316\316\263\377\377\377\1\376\376\376\202\377\377\377\1xxz\202" \ + "::<\1;;=\202::<\3""99;\234\234\236\376\376\376\236\377\377\377\1\375" \ + "\375\375\202\377\377\377\1\376\376\376\202\377\377\377\5\317\317\317" \ + "99;::<;;=::<\202;;=\2::<\332\332\332\210\377\377\377\3\376\376\376\377" \ + "\377\377\376\376\376\204\377\377\377\2\316\316\316;;=\206::<\3;;=::<" \ + "\250\250\252\217\377\377\377\1\376\376\376\204\377\377\377\2\363\363" \ + "\363\222\222\224\202::<\2;;=::<\202;;=\3""99;;;=kkm\205\377\377\377\1" \ + "\376\376\376\235\377\377\377\1kkm\206::<\1\234\234\236\235\377\377\377" \ + "\1\376\376\376\202\377\377\377\2\266\266\26699;\202::<\3;;=::<;;=\202" \ + "::<\3;;=FFH\234\234\234\202\377\377\377\1\376\376\376\223\377\377\377" \ + "\2\364\364\364\204\204\206\202::<\1;;=\202::<\1;;=\202::<\3""99;``b\376" \ + "\376\376\224\377\377\377\1\234\234\234\206::<\1\316\316\316\252\377\377" \ + "\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363" \ + "Y\270\350\211[\267\350\10Y\271\353Z\266\347\\\267\344[\267\346X\267\347" \ + "[\267\350X\270\353Z\266\347\210Y\270\350\10Y\267\352\\\267\346\325\355" \ + "\371\377\377\377\376\377\377\0>g\0\77k\0>i\210\0\77j\10\0>i\3>h\0=i\0" \ + "\77i\0=j\0>g\0=j\0=f\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1" \ + "\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234" \ + "\236\234\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377" \ + "\377\2SSU;;=\202::<\202;;=\3::<SSU::<\202;;=\203::<\1\332\332\332\240" \ + "\377\377\377\1kkm\206::<\1\316\316\316\265\377\377\377\1\346\346\346" \ + "\203::<\1;;=\202::<\2;;=\363\363\365\235\377\377\377\1\376\376\376\210" \ + "\377\377\377\1SSU\202;;=\204::<\1\204\204\204\202\377\377\377\202\376" \ + "\376\376\214\377\377\377\1\221\221\221\205::<\202;;=\4::<;;=kkm\316\316" \ + "\316\221\377\377\377\2\301\301\301SSS\210::<\2FFH\363\363\365\243\377" \ + "\377\377\1kkm\206::<\1\234\234\236\241\377\377\377\1\266\266\270\203" \ + "::<\1;;=\205::<\3:::RRR\265\265\265\222\377\377\377\3\363\363\363\234" \ + "\234\234FFF\202::<\1;;=\206::<\2``b\363\363\363\225\377\377\377\1\234" \ + "\234\234\206::<\1\316\316\316\252\377\377\377\1\316\316\316\206::<\1" \ + "\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\10Z" \ + "\266\347[\267\346Z\265\352X\266\351\\\270\351[\267\346X\267\347[\265" \ + "\347\210[\267\350\10Y\267\352[\266\345\325\355\367\376\375\377\377\377" \ + "\375\3>j\0=i\1>j\210\0>i\10\0\77j\1\77h\0>j\0>g\3>j\0\77i\0=j\0>i\210" \ + "\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm" \ + "\240\377\377\377\1\234\234\236\206::<\1\234\234\236\241\377\377\377\6" \ + "\266\266\270::<;;=::<99;::<\202;;=\205::<\2kkm\376\376\376\240\377\377" \ + "\377\1kkm\206::<\1\316\316\316\265\377\377\377\4\205\205\205;;=::<;;" \ + "=\203::<\3\204\204\206\377\377\377\376\376\376\245\377\377\377\1\265" \ + "\265\267\207::<\2\346\346\346\376\376\376\216\377\377\377\4\376\376\376" \ + "lll::<;;=\202::<\13;;=::<;;=::<;;=::<kkm\264\264\266\363\363\365\377" \ + "\377\377\376\376\376\202\377\377\377\1\376\376\376\206\377\377\377\3" \ + "\346\346\350\250\250\252TTV\204::<\3;;=::<;;=\202::<\2;;=\333\333\333" \ + "\202\377\377\377\1\376\376\376\237\377\377\377\3\376\376\376\377\377" \ + "\377kkm\203::<\1;;=\202::<\1\235\235\237\242\377\377\377\1\265\265\265" \ + "\203::<\1;;=\207::<\4GGI\220\220\222\332\332\334\376\376\376\206\377" \ + "\377\377\1\376\376\376\204\377\377\377\5\376\376\376\302\302\302\204" \ + "\204\206::<;;=\202::<\11""99;;;=::<;;=::<;;=::<```\363\363\363\226\377" \ + "\377\377\1\234\234\234\202::<\1;;=\202::<\2;;=\316\316\316\252\377\377" \ + "\377\4\316\316\316::<;;=99;\203::<\3\234\234\234\377\377\377\376\376" \ + "\376\204\377\377\377\7\373\377\376\377\376\377\377\377\377\376\377\377" \ + "\377\376\377\253\333\362[\265\351\203[\267\352\6Y\267\352[\267\350X\267" \ + "\345Y\270\346Y\270\350Y\267\352\220[\267\350\5X\267\347Y\270\350\325" \ + "\355\371\377\376\377\377\377\377\202\0>g\1\1>k\220\0=i\15\0>g\1>j\0>" \ + "i\0\77j\1>j\0=i\0\77j\0>j\0=i\1<h}\237\270\376\377\377\377\376\374\226" \ + "\377\377\377\3\376\376\376\377\377\377\316\316\316\204::<\3""99;;;=l" \ + "ln\240\377\377\377\5\234\234\234::<;;=::<;;=\202::<\1\235\235\237\241" \ + "\377\377\377\10\363\363\363FFF::<;;=::<;;=::<;;=\203::<\3;;=::<\265\265" \ + "\265\237\377\377\377\3\376\376\376\377\377\377kkm\202::<\1;;=\202::<" \ + "\4;;=\316\316\316\377\377\377\376\376\376\250\377\377\377\1\376\376\376" \ + "\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\203\377" \ + "\377\377\6\364\364\364::<99;;;=::<;;=\202::<\1\347\347\351\203\377\377" \ + "\377\1\376\376\376\244\377\377\377\4FFH;;=::<99;\203::<\1\220\220\222" \ + "\220\377\377\377\2\363\363\363``b\202::<\1;;=\203::<\1;;=\205::<\5__" \ + "_\222\222\222\234\234\234\316\316\316\317\317\317\202\316\316\316\7\301" \ + "\301\301\234\234\236\204\204\206__a;;=99;;;=\203::<\2;;=99;\203;;=\2" \ + "::<\265\265\265\204\377\377\377\1\376\376\376\235\377\377\377\5\376\376" \ + "\376\377\377\377\376\376\376kkm::<\202;;=\6::<;;=::<\234\234\236\377" \ + "\377\377\376\376\376\236\377\377\377\1\376\376\376\202\377\377\377\5" \ + "\301\301\303GGI;;=::<;;=\206::<\7;;=::<99;GGIwwy\235\235\235\300\300" \ + "\300\202\316\316\316\10\315\315\315\317\317\317\315\315\315\265\265\265" \ + "\234\234\234jjj<<>99;\203::<\1;;=\202::<\2""99;;;=\203::<\1\204\204\206" \ + "\206\377\377\377\1\376\376\376\221\377\377\377\10\234\234\234;;=::<9" \ + "9;;;=::<99;\316\316\316\252\377\377\377\4\317\317\317;;=88:;;=\202::" \ + "<\3;;=\234\234\234\376\376\376\205\377\377\377\1\377\375\377\202\377" \ + "\377\375\6\377\376\377\377\377\375\253\333\362Y\270\350X\267\347Z\266" \ + "\347\202Y\270\350\1[\267\350\202Z\266\347\2[\267\350Z\266\347\220[\267" \ + "\350\5[\267\352Z\266\351\327\355\372\377\375\376\377\376\377\202\1>j" \ + "\1\1>k\220\0>i\202\0=i\14\0\77k\0>i\0=i\1>j\0=i\0=j\0\77k\0=i\177\236" \ + "\263\377\377\377\376\377\377\375\376\377\224\377\377\377\1\376\376\376" \ + "\202\377\377\377\1\316\316\316\203::<\202;;=\3""99;kkm\376\376\376\234" \ + "\377\377\377\1\376\376\376\202\377\377\377\1\233\233\233\202::<\7;;=" \ + "::<;;=::<\234\234\236\377\377\377\376\376\376\233\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\202\377\377\377\4\221\221\221;;=99;;;=\202" \ + "::<\202;;=\203::<\1SSU\203\377\377\377\1\376\376\376\233\377\377\377" \ + "\10\376\376\376\377\377\377\376\376\376kkm::<;;=::<;;=\202::<\1;;=\202" \ + "::<\1;;=\240::<\1kkk\207\377\377\377\1\376\376\376\203\377\377\377\3" \ + "\375\375\375\377\377\377\376\376\376\202\377\377\377\2\233\233\235::" \ + "<\202;;=\203::<\1xxz\251\377\377\377\1\235\235\237\202::<\1;;=\203::" \ + "<\3GGI\363\363\363\376\376\376\217\377\377\377\2\363\363\363yyy\204:" \ + ":<\1;;=\203::<\1;;=\206::<\1""99;\203::<\1;;=\203::<\6;;=99;;;=::<;;" \ + "=99;\202;;=\3""99;GGI\301\301\301\206\377\377\377\1\376\376\376\232\377" \ + "\377\377\1\376\376\376\204\377\377\377\1lln\202::<\1;;=\202::<\2;;=\234" \ + "\234\236\241\377\377\377\1\376\376\376\202\377\377\377\2\332\332\334" \ + "__a\211::<\1;;=\205::<\1;;=\202::<\1;;=\202::<\4;;=::<99;;;=\202::<\1" \ + ";;=\202::<\1;;=\203::<\2FFH\265\265\267\206\377\377\377\3\376\376\376" \ + "\377\377\377\376\376\376\220\377\377\377\3\234\234\236::<;;=\203::<\2" \ + ";;=\316\316\316\252\377\377\377\2\315\315\31599;\203::<\5;;=::<\234\234" \ + "\234\377\377\377\376\376\376\205\377\377\377\7\377\377\375\375\377\376" \ + "\377\377\377\375\376\377\255\333\365Z\266\345[\267\350\202Y\270\350\1" \ + "X\267\347\202Y\267\352\3Z\266\351Z\266\347Y\270\350\221[\267\350\2[\267" \ + "\352\323\355\372\202\376\377\377\1\0=j\222\0=i\204\0>i\14\1\77h\0>g\0" \ + "=f\1>j\0\77i\0>i\177\237\266\377\377\375\377\376\375\377\377\377\376" \ + "\377\377\377\376\377\225\377\377\377\2\316\316\316::<\202;;=\202::<\4" \ + ";;=kkm\377\377\377\376\376\376\235\377\377\377\2\376\376\376\235\235" \ + "\235\202::<\1;;=\202::<\2;;=\234\234\236\242\377\377\377\3\346\346\346" \ + "::<;;=\210::<\2\235\235\237\376\376\376\234\377\377\377\1\376\376\376" \ + "\204\377\377\377\1lln\202::<\3;;=::<;;=\203::<\2;;=99;\240::<\1kkk\210" \ + "\377\377\377\11\376\376\376\377\377\377\376\376\376\377\377\377\376\376" \ + "\376\377\377\377\376\376\376\364\364\366GGI\205::<\6;;=\316\316\316\377" \ + "\377\377\376\376\376\377\377\377\376\376\376\245\377\377\377\11\345\345" \ + "\345;;=::<;;=::<;;=::<;;=\234\234\236\222\377\377\377\7\234\234\234;" \ + ";=::<;;=99;;;=99;\203::<\1;;=\202::<\203;;=\2::<;;=\202::<\1;;=\202:" \ + ":<\1;;=\202::<\12;;=::<;;=99;::<``b\332\332\332\376\376\376\377\377\377" \ + "\376\376\376\202\377\377\377\5\376\376\376\377\377\377\376\376\376\377" \ + "\377\377\376\376\376\232\377\377\377\5\376\376\376\377\377\377\376\376" \ + "\376kkm;;=\202::<\1;;=\202::<\1\234\234\236\236\377\377\377\1\376\376" \ + "\376\207\377\377\377\2\234\234\236;;=\202::<\1;;=\204::<\1;;=\211::<" \ + "\1;;=\202::<\1;;=\202::<\1;;=\202::<\1;;=\203::<\3;;=kkm\346\346\346" \ + "\203\377\377\377\1\376\376\376\204\377\377\377\1\376\376\376\221\377" \ + "\377\377\2\234\234\236;;=\202::<\1;;=\202::<\1\316\316\316\252\377\377" \ + "\377\4\316\316\316;;=99;;;=\203::<\1\234\234\234\210\377\377\377\7\376" \ + "\377\377\377\375\376\377\377\375\256\332\363Y\270\350Y\267\352[\267\352" \ + "\202[\267\350\5X\270\350X\270\352Y\267\352Y\270\350X\267\347\220[\267" \ + "\350\5X\267\347[\267\350\325\355\367\377\377\373\377\377\375\202\0\77" \ + "j\1\0>g\220\0>i\1\0\77j\203\0>i\202\0=i\6\1>j\0>i\0\77h\0>g\177\236\263" \ + "\377\377\375\203\377\377\377\1\377\376\377\222\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\316\316\316\203::<\1;;=\202::<\2kkm\376\376\376" \ + "\233\377\377\377\1\376\376\376\203\377\377\377\5\234\234\234::<;;=::" \ + "<;;=\202::<\1\234\234\236\235\377\377\377\202\376\376\376\202\377\377" \ + "\377\5\376\376\376\377\377\377xxz99;;;=\204::<\4;;=::<;;=\362\362\362" \ + "\237\377\377\377\5\376\376\376\377\377\377\376\376\376kkm;;=\207::<\2" \ + "99;;;=\240::<\1lll\205\377\377\377\1\376\376\376\203\377\377\377\1\376" \ + "\376\376\202\377\377\377\1\376\376\376\202\377\377\377\4\265\265\267" \ + ";;=::<;;=\202::<\2;;=__a\205\377\377\377\1\376\376\376\245\377\377\377" \ + "\3\204\204\206::<;;=\204::<\2SSU\376\376\376\215\377\377\377\1\376\376" \ + "\376\204\377\377\377\2\316\316\316__a\206::<\1;;=\214::<\5;;=::<;;=:" \ + ":<;;=\203::<\2\234\234\234\363\363\363\204\377\377\377\1\376\376\376" \ + "\243\377\377\377\1lln\206::<\2\233\233\235\376\376\376\233\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\207\377\377\377\3\345\345" \ + "\345lln;;=\204::<\5;;=99;::<99;;;=\205::<\1;;=\203::<\3""99;;;=99;\206" \ + "::<\2TTV\265\265\265\234\377\377\377\10\234\234\234;;=::<;;=::<;;=::" \ + "<\316\316\316\252\377\377\377\1\315\315\315\206::<\4\235\235\235\376" \ + "\376\376\377\377\377\376\376\376\205\377\377\377\12\377\377\373\377\377" \ + "\377\377\377\375\267\340\366[\270\344Z\266\351[\267\352Z\266\351[\265" \ + "\347[\267\350\202Y\270\350\2\\\270\351Z\266\347\220[\267\350\10X\267" \ + "\347X\266\351\325\355\371\377\376\377\377\377\377\0\77k\0=h\3>j\220\0" \ + "\77j\16\1>j\0=i\1>j\0=i\0\77j\0>i\0=h\0\77j\0\77h\1<f\177\236\263\377" \ + "\377\375\376\376\377\376\377\377\225\377\377\377\202\376\376\376\2\317" \ + "\317\317::<\202;;=\1::<\202;;=\1kkm\235\377\377\377\1\376\376\376\202" \ + "\377\377\377\2\234\234\234;;=\205::<\2\233\233\235\376\376\376\232\377" \ + "\377\377\1\376\376\376\204\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\316\316\316\203::<\1;;=\204::<\3\204\204\206\377\377\377\376\376\376" \ + "\241\377\377\377\1lln\203::<\202;;=\203::<\1;;=\241::<\1kkk\206\377\377" \ + "\377\3\376\376\376\377\377\377\376\376\376\206\377\377\377\1TTV\203:" \ + ":<\4""99;;;=99;\265\265\267\253\377\377\377\3\331\331\331;;=99;\204:" \ + ":<\2;;=\264\264\264\217\377\377\377\1\376\376\376\204\377\377\377\2\264" \ + "\264\266SSU\202::<\2""99;;;=\203::<\3;;=::<;;=\206::<\5;;=99;;;=::<;" \ + ";=\20299;\6\204\204\206\346\346\346\377\377\377\376\376\376\377\377\377" \ + "\376\376\376\203\377\377\377\202\376\376\376\202\377\377\377\1\376\376" \ + "\376\231\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377" \ + "\377\12lll::<;;=::<99;::<;;=\234\234\236\377\377\377\376\376\376\233" \ + "\377\377\377\1\375\375\375\213\377\377\377\4\316\316\316xxx;;=99;\204" \ + "::<\1;;=\202::<\1;;=\204::<\4;;=::<;;=99;\203::<\1;;=\202::<\2SSS\265" \ + "\265\265\210\377\377\377\3\376\376\376\377\377\377\376\376\376\223\377" \ + "\377\377\1\234\234\234\206::<\1\316\316\316\250\377\377\377\3\376\376" \ + "\376\377\377\377\315\315\315\202::<\7;;=::<;;=::<\234\234\234\377\377" \ + "\377\376\376\376\202\377\377\377\21\376\376\376\377\377\377\376\377\373" \ + "\377\377\377\376\377\377\376\377\375\377\376\377\353\366\374X\266\351" \ + "X\270\350W\267\347X\270\350X\267\347Z\266\347\\\270\347X\267\345Y\270" \ + "\350\221[\267\350\7Z\266\347[\267\350\327\355\372\377\375\377\377\377" \ + "\377\0>g\0\77h\221\0=i\1\0>g\202\1\77h\1\0=i\202\0>i\11\0\77j\0>g\0>" \ + "j\0\77m\336\347\354\376\377\377\377\376\377\376\377\377\377\377\375\222" \ + "\377\377\377\1\376\376\376\203\377\377\377\1\316\316\316\202::<\1;;=" \ + "\203::<\2kkm\376\376\376\233\377\377\377\1\376\376\376\202\377\377\377" \ + "\3\376\376\376\234\234\234;;=\202::<\6""99;::<;;=\234\234\236\377\377" \ + "\377\376\376\376\237\377\377\377\1\376\376\376\202\377\377\377\1SSS\202" \ + ";;=\1""99;\204;;=\3\331\331\331\377\377\377\376\376\376\234\377\377\377" \ + "\3\376\376\376\377\377\377\376\376\376\202\377\377\377\3lll::<;;=\202" \ + "::<\202;;=\203::<\1;;=\240::<\1kkk\204\377\377\377\1\376\376\376\211" \ + "\377\377\377\3\302\302\302;;;999\202::<\3;;=::<TTT\210\377\377\377\1" \ + "\376\376\376\244\377\377\377\2kkk;;=\202::<\203:::\1TTT\226\377\377\377" \ + "\3\301\301\301xxz;;=\202::<\1;;=\202::<\1;;=\202::<\5;;=::<;;=::<;;=" \ + "\202::<\5;;=99;SSU\235\235\237\347\347\351\204\377\377\377\1\376\376" \ + "\376\207\377\377\377\3\376\376\376\377\377\377\376\376\376\235\377\377" \ + "\377\10kkk:::::<999;;;:::;;;\233\233\233\236\377\377\377\1\376\376\376" \ + "\211\377\377\377\1\376\376\376\202\377\377\377\3\346\346\350\251\251" \ + "\253``b\202::<\3;;=::<;;=\202::<\1;;=\205::<\1;;=\203::<\5;;=FFH\204" \ + "\204\204\316\316\316\376\376\376\204\377\377\377\1\376\376\376\232\377" \ + "\377\377\1\234\234\234\202::<\5""99;;;=99;;;;\315\315\315\252\377\377" \ + "\377\3\316\316\316:::;;;\202:::\3;;;::<\234\234\234\206\377\377\377\1" \ + "\377\377\375\203\377\376\377\11\377\377\377\377\377\375\303\344\367W" \ + "\270\345^\266\344X\267\347Y\271\353Z\266\351\\\266\350\202Y\270\350\221" \ + "[\267\352\3[\267\350[\265\347\325\355\371\202\376\377\377\3\2=e\0>g\0" \ + "\77m\220\0=i\6\0\77j\0>i\0=h\0\77j\0=i\0\77j\202\0>g\2\1\77h\240\266" \ + "\304\204\377\377\377\2\376\376\376\377\377\375\223\377\377\377\14\376" \ + "\376\376\377\377\377\315\315\315;;=::<:::;;;:::;;;kkk\377\377\377\376" \ + "\376\376\233\377\377\377\1\376\376\376\202\377\377\377\10\235\235\235" \ + "99;::<999;;;:::;;;\233\233\233\234\377\377\377\1\376\376\376\207\377" \ + "\377\377\1\265\265\265\202::<\1;;=\203::<\1kkk\203\377\377\377\1\376" \ + "\376\376\240\377\377\377\2kkk:::\202::<\3;;=99;;;=\244::<\1kkk\205\377" \ + "\377\377\1\376\376\376\210\377\377\377\1\346\346\346\206\316\316\316" \ + "\3\332\332\332\377\377\377\377\377\375\253\377\377\377\2\346\346\346" \ + "\316\316\316\202\316\316\320\203\316\316\316\1\315\315\315\225\377\377" \ + "\377\202\376\376\376\202\377\377\377\4\316\316\320\234\234\236kkmSSU" \ + "\205::<\1;;=\203::<\5kkm\204\204\206\264\264\266\346\346\350\376\376" \ + "\376\214\377\377\377\1\376\376\376\202\377\377\377\202\376\376\376\231" \ + "\377\377\377\1\376\376\376\203\377\377\377\2\331\331\331\317\317\317" \ + "\205\316\316\316\1\347\347\347\243\377\377\377\1\376\376\376\211\377" \ + "\377\377\5\376\376\377\347\347\351\265\265\267\204\204\206lln\212::<" \ + "\4``bxxz\234\234\236\332\332\332\207\377\377\377\1\376\376\376\210\377" \ + "\377\377\1\376\376\376\222\377\377\377\1\346\346\346\203\316\316\320" \ + "\4\316\316\316\316\316\320\315\315\315\364\364\364\251\377\377\377\2" \ + "\376\376\376\364\364\364\205\316\316\316\2\316\316\320\346\346\346\210" \ + "\377\377\377\16\377\376\377\377\377\375\376\377\377\377\377\377\377\375" \ + "\377\326\354\371\241\326\366\206\310\352\200\312\357\202\312\362\204" \ + "\310\357\204\312\356\203\311\355\205\311\360\220\204\312\356\10\203\311" \ + "\355\201\311\361\342\360\371\376\377\377\377\377\375>n\222Bm\215@n\220" \ + "\220@n\217\3@l\217An\217Bo\220\202An\217\5@m\214Dm\213l\223\260\277\320" \ + "\332\376\377\377\202\377\377\377\1\377\377\375\202\377\377\377\1\376" \ + "\377\377\225\377\377\377\3\363\363\363\317\317\321\316\316\320\204\316" \ + "\316\316\1\332\332\332\240\377\377\377\1\346\346\346\202\316\316\320" \ + "\204\316\316\316\1\347\347\347\243\377\377\377\3\376\376\376\363\363" \ + "\363lln\202kkm\1lln\202kkm\1\301\301\301\240\377\377\377\1\376\376\376" \ + "\203\377\377\377\2\331\331\331\317\317\317\202\316\316\316\202\317\317" \ + "\317\245\316\316\316\2\332\332\332\376\376\376\351\377\377\377\5\332" \ + "\332\332\315\315\315\316\316\316\315\315\315\363\363\363\361\377\377" \ + "\377\202\316\316\316\1\317\317\317\202\316\316\316\2\315\315\315\363" \ + "\363\363\377\377\377\377\377\377\377\377\377\377\377\377\334\377\377" \ + "\377\1\376\376\376\375\377\377\377\1\376\376\376\377\377\377\377\377" \ + "\377\377\377\377\377\377\377\340\377\377\377\1\376\376\376\370\377\377" \ + "\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\342" \ + "\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377" \ + "\377\377\377\377\377\334\377\377\377\1\376\376\376\362\377\377\377\1" \ + "\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\346\377" \ + "\377\377\1\376\376\376\363\377\377\377\1\376\376\376\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\342\377\377\377\1\376\376\376\373\377" \ + "\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377" \ + "\340\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377" \ + "\377\377\377\377\377\377\377\377\377\377\377\377\243\377\377\377\3\376" \ + "\376\376\377\377\377\376\376\376\203\377\377\377\1\376\376\376\233\377" \ + "\377\377\1\376\376\376\205\377\377\377\1\376\376\376\214\377\377\377" \ + "\1\376\376\376\205\377\377\377\1\376\376\376\260\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\300\377\377\377\1\376\376\376\306\377\377" \ + "\377\1\376\376\376\233\377\377\377\4\376\377\377\376\376\376\377\376" \ + "\377\377\377\377\203\376\377\375\203\377\377\377\3\377\377\375\376\377" \ + "\375\376\377\377\265\377\377\377\4\377\377\375\377\376\377\376\377\377" \ + "\377\377\375\202\377\376\377\210\377\377\377\7\377\377\375\376\377\377" \ + "\377\377\377\375\377\376\376\377\377\377\376\377\376\377\377\211\377" \ + "\377\377\4\376\377\375\377\377\377\376\376\376\377\377\375\202\377\377" \ + "\377\2\377\377\375\376\376\376\220\377\377\377\1\376\377\375\202\377" \ + "\377\375\5\377\376\377\377\377\373\377\377\377\375\377\376\377\377\375" \ + "\210\377\377\377\1\377\376\377\202\377\377\375\202\377\377\377\3\376" \ + "\377\377\377\377\375\377\376\377\213\377\377\377\3\376\377\377\376\377" \ + "\375\377\377\375\203\377\377\377\203\376\377\375\4\377\377\377\377\376" \ + "\377\376\376\376\376\377\377\233\377\377\377\3\376\377\377\376\377\375" \ + "\377\377\375\203\377\377\377\203\376\377\375\4\377\377\377\377\376\377" \ + "\376\376\376\376\377\377\210\377\377\377\1\377\376\377\203\377\377\377" \ + "\4\376\377\377\377\377\375\377\376\377\376\377\373\211\377\377\377\4" \ + "\376\377\377\376\376\374\377\376\377\377\375\376\226\377\377\377\5\376" \ + "\377\377\375\377\374\377\377\375\376\375\377\377\377\375\210\377\377" \ + "\377\1\377\377\375\202\376\377\377\1\377\377\373\242\377\377\377\1\376" \ + "\376\376\212\377\377\377\1\376\376\376\207\377\377\377\1\376\376\376" \ + "\237\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\214\377" \ + "\377\377\1\376\376\376\204\377\377\377\202\376\376\376\257\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \ + "\376\246\377\377\377\1\376\376\376\224\377\377\377\1\376\376\376\250" \ + "\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\236\377\377" \ + "\377\3\376\376\376\377\377\377\376\376\376\230\377\377\377\4\377\377" \ + "\373\376\377\377\376\376\376\377\376\377\203\377\377\377\1\377\377\375" \ + "\202\377\377\377\1\377\376\377\202\377\377\375\3\377\377\377\377\377" \ + "\375\376\376\374\260\377\377\377\2\377\377\375\376\376\376\203\377\376" \ + "\377\214\377\377\377\7\376\377\377\377\376\377\377\377\375\377\377\377" \ + "\377\376\377\375\377\376\377\377\375\210\377\377\377\7\377\376\374\377" \ + "\377\375\377\376\377\377\377\375\376\376\376\377\377\377\376\376\376" \ + "\221\377\377\377\1\377\376\377\203\377\377\377\202\377\377\375\212\377" \ + "\377\377\2\377\377\375\377\377\377\202\377\377\375\214\377\377\377\3" \ + "\376\376\374\377\377\375\377\377\377\202\377\377\375\1\377\376\377\202" \ + "\377\377\377\1\377\377\375\203\377\377\377\4\377\376\377\376\376\376" \ + "\376\377\377\377\377\373\230\377\377\377\3\376\376\374\377\377\375\377" \ + "\377\377\202\377\377\375\1\377\376\377\202\377\377\377\1\377\377\375" \ + "\203\377\377\377\4\377\376\377\376\376\376\376\377\377\377\377\373\213" \ + "\377\377\377\1\377\376\374\214\377\377\377\2\377\377\375\377\376\377" \ + "\202\377\377\375\3\376\377\377\377\377\377\377\377\373\221\377\377\377" \ + "\3\376\377\375\376\377\377\377\376\377\204\377\377\377\1\377\377\375" \ + "\212\377\377\377\5\377\376\377\377\377\375\377\377\377\376\377\375\376" \ + "\377\373\243\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376" \ + "\204\377\377\377\1\376\376\376\242\377\377\377\1\376\376\376\205\377" \ + "\377\377\1\376\376\376\213\377\377\377\1\376\376\376\206\377\377\377" \ + "\1\376\376\376\263\377\377\377\3\376\376\376\377\377\377\376\376\376" \ + "\270\377\377\377\1\376\376\376\312\377\377\377\1\376\376\376\234\377" \ + "\377\377\1\377\377\375\202\376\377\377\7\377\376\377\377\377\377\376" \ + "\377\377\377\376\377\377\377\375\377\377\377\376\377\377\202\377\376" \ + "\377\2\376\377\375\376\377\377\262\377\377\377\10\377\377\375\376\377" \ + "\377\377\376\377\377\377\373\377\377\377\377\376\377\376\377\375\377" \ + "\377\375\211\377\377\377\3\376\377\377\377\376\377\377\377\375\202\377" \ + "\377\377\2\376\377\377\376\376\376\210\377\377\377\202\377\376\377\4" \ + "\374\377\377\376\377\377\377\376\377\377\377\375\222\377\377\377\4\377" \ + "\376\375\376\377\377\377\377\377\376\377\377\202\377\376\377\202\377" \ + "\377\375\210\377\377\377\4\377\377\375\377\377\377\377\377\375\377\377" \ + "\377\202\377\376\377\2\377\377\377\376\377\377\212\377\377\377\2\376" \ + "\377\377\376\377\375\202\377\376\377\7\376\377\377\377\377\377\377\377" \ + "\375\377\376\377\376\377\377\377\377\377\377\376\377\202\376\377\377" \ + "\1\377\377\375\232\377\377\377\2\376\377\377\376\377\375\202\377\376" \ + "\377\7\376\377\377\377\377\377\377\377\375\377\376\377\376\377\377\377" \ + "\377\377\377\376\377\202\376\377\377\1\377\377\375\210\377\377\377\1" \ + "\377\377\375\202\377\377\377\4\377\377\375\377\376\377\377\377\377\376" \ + "\377\377\211\377\377\377\7\375\376\377\377\377\375\377\376\377\376\376" \ + "\377\376\377\375\375\377\376\377\377\375\222\377\377\377\6\376\377\377" \ + "\377\376\377\377\377\377\377\377\375\377\376\377\376\377\377\213\377" \ + "\377\377\202\377\376\377\3\377\377\375\376\377\377\376\377\375\236\377" \ + "\377\377\1\376\376\376\203\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\376\376\376\203\377\377\377\2\376\376\376\377\377\377\202\376\376" \ + "\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\204" \ + "\377\377\377\1\376\376\376\235\377\377\377\1\376\376\376\217\377\377" \ + "\377\1\376\376\376\206\377\377\377\1\376\376\376\260\377\377\377\3\376" \ + "\376\376\377\377\377\376\376\376\241\377\377\377\202\376\376\376\204" \ + "\377\377\377\1\376\376\376\222\377\377\377\1\376\376\376\205\377\377" \ + "\377\1\376\376\376\246\377\377\377\1\376\376\376\233\377\377\377\3\376" \ + "\376\376\377\377\377\376\376\376\234\377\377\377\15\376\376\376\377\377" \ + "\377\377\376\377\377\377\375\375\377\376\377\377\377\376\377\375\377" \ + "\377\377\375\376\377\377\377\377\377\377\375\376\377\377\377\377\377" \ + "\202\377\376\377\260\377\377\377\7\377\376\377\376\377\377\377\377\377" \ + "\376\377\377\377\377\377\377\377\375\376\377\377\212\377\377\377\1\376" \ + "\376\374\203\377\377\377\3\376\376\377\377\377\375\376\377\377\210\377" \ + "\377\377\10\376\377\377\377\376\377\374\377\373\376\377\373\377\376\377" \ + "\376\376\376\377\377\377\376\377\375\220\377\377\377\2\377\376\377\377" \ + "\377\377\202\377\377\375\202\377\377\377\2\376\376\374\376\377\377\210" \ + "\377\377\377\1\376\377\377\202\377\377\377\5\376\377\377\377\377\377" \ + "\376\376\376\377\377\377\376\377\375\210\377\377\377\202\377\376\377" \ + "\15\377\377\377\376\377\377\377\377\375\377\377\377\375\376\377\377\377" \ + "\377\376\377\375\377\377\377\375\377\376\377\377\375\377\376\377\377" \ + "\377\377\376\376\376\231\377\377\377\202\377\376\377\15\377\377\377\376" \ + "\377\377\377\377\375\377\377\377\375\376\377\377\377\377\376\377\375" \ + "\377\377\377\375\377\376\377\377\375\377\376\377\377\377\377\376\376" \ + "\376\211\377\377\377\4\377\376\377\377\377\377\376\377\375\376\377\377" \ + "\202\377\377\377\2\376\377\377\376\377\375\210\377\377\377\1\376\377" \ + "\375\202\376\376\376\202\377\377\377\2\377\377\375\375\376\377\221\377" \ + "\377\377\10\377\377\375\377\377\377\376\376\374\376\377\373\376\376\376" \ + "\377\376\377\376\377\377\377\377\375\210\377\377\377\6\376\376\376\377" \ + "\377\377\377\377\375\377\377\377\374\375\377\377\377\375\242\377\377" \ + "\377\1\376\376\376\214\377\377\377\1\376\376\376\204\377\377\377\3\376" \ + "\376\376\377\377\377\376\376\376\235\377\377\377\1\376\376\376\203\377" \ + "\377\377\202\376\376\376\212\377\377\377\1\376\376\376\202\377\377\377" \ + "\202\376\376\376\264\377\377\377\5\376\376\376\377\377\377\376\376\376" \ + "\377\377\377\376\376\376\242\377\377\377\3\376\376\376\377\377\377\376" \ + "\376\376\202\377\377\377\1\376\376\376\223\377\377\377\1\376\376\376" \ + "\244\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\233\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\234\377\377\377" \ + "\1\375\377\372\202\377\377\377\3\376\376\376\377\377\375\377\377\377" \ + "\202\376\377\377\204\377\377\377\4\376\377\377\377\377\377\377\376\377" \ + "\375\377\372\260\377\377\377\202\377\377\375\2\377\377\377\376\375\377" \ + "\202\377\377\377\1\375\377\376\212\377\377\377\6\377\377\375\377\377" \ + "\377\376\377\375\377\377\375\377\376\377\377\376\375\212\377\377\377" \ + "\1\377\376\377\202\377\377\377\4\377\375\376\377\377\377\377\377\373" \ + "\376\375\377\221\377\377\377\203\376\376\376\4\377\377\375\376\376\374" \ + "\377\376\377\376\376\374\210\377\377\377\5\377\376\377\377\377\375\377" \ + "\376\377\376\376\376\376\377\375\202\377\377\377\1\376\376\376\210\377" \ + "\377\377\4\375\377\372\377\376\377\377\377\377\376\377\377\204\377\377" \ + "\377\202\376\377\377\3\377\377\377\377\377\375\376\376\376\202\377\377" \ + "\377\1\375\377\372\230\377\377\377\4\375\377\372\377\376\377\377\377" \ + "\377\376\377\377\204\377\377\377\202\376\377\377\3\377\377\377\377\377" \ + "\375\376\376\376\202\377\377\377\1\375\377\372\210\377\377\377\3\376" \ + "\377\377\377\377\377\376\376\376\202\376\377\377\202\377\377\377\1\376" \ + "\377\375\210\377\377\377\7\376\376\377\377\377\375\376\377\375\376\376" \ + "\376\377\376\377\377\377\377\376\377\377\221\377\377\377\5\376\376\376" \ + "\376\377\377\377\377\377\375\375\375\377\376\377\202\377\377\377\1\377" \ + "\377\375\211\377\377\377\7\377\376\377\376\376\374\376\377\377\377\377" \ + "\377\377\376\377\377\377\375\377\377\373\233\377\377\377\1\376\376\376" \ + "\205\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\203\377" \ + "\377\377\1\376\376\376\204\377\377\377\3\376\376\376\377\377\377\376" \ + "\376\376\204\377\377\377\1\376\376\376\237\377\377\377\1\376\376\376" \ + "\212\377\377\377\1\376\376\376\213\377\377\377\1\376\376\376\255\377" \ + "\377\377\1\376\376\376\247\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\376\376\376\224\377\377\377\1\376\376\376\247\377\377\377\1\376\376" \ + "\376\236\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\232" \ + "\377\377\377\10\377\376\377\377\377\375\377\377\377\376\377\377\376\376" \ + "\376\377\376\377\377\377\375\377\376\377\202\377\377\375\1\377\376\377" \ + "\202\377\377\377\3\377\376\377\377\375\376\377\376\377\260\377\377\377" \ + "\2\377\376\377\377\377\377\202\377\376\377\4\377\377\375\376\376\374" \ + "\377\375\377\377\376\377\210\377\377\377\3\376\376\374\377\376\377\376" \ + "\376\376\204\377\377\377\1\376\377\375\210\377\377\377\4\375\377\374" \ + "\377\377\377\377\375\376\377\376\377\203\377\377\377\1\377\377\375\220" \ + "\377\377\377\3\376\377\377\377\377\375\376\377\377\202\377\377\377\3" \ + "\377\376\377\373\377\377\376\377\377\211\377\377\377\202\376\377\375" \ + "\1\377\377\375\203\377\377\377\1\377\376\377\210\377\377\377\3\377\376" \ + "\377\377\375\376\377\376\377\202\377\377\377\1\377\376\377\202\377\377" \ + "\375\10\377\376\377\377\377\375\377\376\377\376\376\376\376\377\377\377" \ + "\377\377\377\377\375\377\376\377\230\377\377\377\3\377\376\377\377\375" \ + "\376\377\376\377\202\377\377\377\1\377\376\377\202\377\377\375\10\377" \ + "\376\377\377\377\375\377\376\377\376\376\376\376\377\377\377\377\377" \ + "\377\377\375\377\376\377\210\377\377\377\2\377\377\375\375\376\371\202" \ + "\377\376\377\3\377\377\377\377\377\375\377\376\377\212\377\377\377\1" \ + "\377\375\376\202\377\377\377\4\377\377\375\376\376\376\376\377\377\377" \ + "\376\377\220\377\377\377\2\376\377\377\376\376\377\202\377\377\377\2" \ + "\376\377\375\375\377\374\212\377\377\377\10\373\377\376\377\377\377\377" \ + "\377\375\376\376\374\377\377\375\377\376\377\377\377\377\376\377\377" \ + "\235\377\377\377\1\376\376\376\202\377\377\377\7\316\316\320\250\250" \ + "\252\221\221\223llnjjlGGI99;\204::<\7TTVkkmyy{\234\234\236\265\265\267" \ + "\332\332\332\376\376\376\237\377\377\377\3\376\376\376\377\377\377\376" \ + "\376\376\222\377\377\377\1\376\376\376\205\377\377\377\3\376\376\376" \ + "\377\377\377\376\376\376\255\377\377\377\1\376\376\376\246\377\377\377" \ + "\1\376\376\376\227\377\377\377\1\376\376\376\252\377\377\377\1\376\376" \ + "\376\233\377\377\377\1\376\376\376\236\377\377\377\17\305\344\240\303" \ + "\342\237\304\343\240\304\343\237\307\342\237\303\342\236\305\342\240" \ + "\303\342\236\305\342\237\304\343\240\304\343\237\304\341\237\304\343" \ + "\237\323\352\266\376\377\375\250\377\377\377\210\305\342\240\10\305\342" \ + "\237\303\342\234\304\343\237\306\341\236\304\343\240\322\352\270\376" \ + "\377\377\375\377\376\211\377\377\377\5\377\376\377\376\376\376\377\376" \ + "\377\360\371\350\305\342\237\202\304\341\236\210\305\342\240\5\304\341" \ + "\236\327\356\302\376\377\377\377\377\373\376\377\375\202\377\377\375" \ + "\1\377\376\377\220\377\377\377\202\377\377\375\2\376\377\377\377\377" \ + "\377\202\377\377\375\2\304\343\237\306\341\236\210\305\342\240\5\307" \ + "\342\237\303\342\236\304\341\236\341\357\314\377\377\375\213\377\377" \ + "\377\17\376\377\375\323\352\266\304\343\237\304\341\237\304\343\237\304" \ + "\343\240\305\342\237\303\342\236\305\342\240\303\342\236\307\342\237" \ + "\304\343\237\304\343\240\303\342\237\305\344\240\231\377\377\377\17\376" \ + "\377\375\323\352\266\304\343\237\304\341\237\304\343\237\304\343\240" \ + "\305\342\237\303\342\236\305\342\240\303\342\236\307\342\237\304\343" \ + "\237\304\343\240\303\342\237\305\344\240\211\377\377\377\10\360\367\347" \ + "\306\343\241\303\342\237\307\342\237\303\342\237\304\343\235\307\341" \ + "\240\304\343\240\210\305\342\240\7\315\347\252\376\377\375\377\375\376" \ + "\376\377\375\377\377\377\377\377\373\376\377\377\221\377\377\377\10\377" \ + "\377\375\376\377\375\323\352\266\307\341\240\307\342\237\305\342\240" \ + "\307\340\236\306\341\236\210\305\342\240\4\304\343\237\311\335\236\377" \ + "\377\377\377\376\377\203\377\377\377\1\376\377\377\230\377\377\377\1" \ + "\376\376\376\203\377\377\377\3\346\346\346\251\251\251jjl\202;;=\210" \ + "::<\1;;=\202::<\2;;=99;\203::<\5FFHxxx\265\265\265\363\363\363\376\376" \ + "\376\234\377\377\377\2\376\376\376\346\346\346\214\234\234\234\1\235" \ + "\235\235\203\234\234\234\3\235\235\235\234\234\234\250\250\250\203\316" \ + "\316\316\1\346\346\346\263\377\377\377\202\250\250\250\245\377\377\377" \ + "\1\316\316\316\222\234\234\234\1\302\302\302\203\316\316\316\1\363\363" \ + "\363\247\377\377\377\3\316\316\316\234\234\234\235\235\235\240\234\234" \ + "\234\1\316\316\316\231\377\377\377\6\215\305>\216\306A\215\305@\213\310" \ + "=\215\305>\212\307>\202\214\305@\6\214\306>\212\306@\214\306<\215\304" \ + "B\214\306>\252\323m\251\377\377\377\210\214\306>\10\215\305@\215\307" \ + "\77\212\307>\217\304@\214\305@\251\323m\377\377\377\377\377\375\213\377" \ + "\377\377\5\377\375\377\341\363\315\215\305>\212\307>\215\305@\210\214" \ + "\306>\6\215\306A\220\305\77\350\365\333\377\377\377\376\377\377\377\376" \ + "\377\202\376\377\377\225\377\377\377\3\377\376\377\214\306>\215\306A" \ + "\210\214\306>\6\215\305>\212\310\77\215\305@\307\341\240\376\377\377" \ + "\377\376\377\213\377\377\377\6\252\323m\214\306>\215\304B\214\306<\212" \ + "\306@\214\306>\202\214\305@\6\212\307>\215\305>\213\310=\215\305@\216" \ + "\306A\215\305>\232\377\377\377\6\252\323m\214\306>\215\304B\214\306<" \ + "\212\306@\214\306>\202\214\305@\6\212\307>\215\305>\213\310=\215\305" \ + "@\216\306A\215\305>\211\377\377\377\4\376\377\377\242\321a\213\307A\215" \ + "\305>\202\214\306>\2\215\305@\215\307\77\210\214\306>\7\215\305<\332" \ + "\354\304\377\377\377\376\377\375\376\376\376\377\376\377\376\376\376" \ + "\221\377\377\377\10\377\376\377\342\362\316\215\305>\213\310\77\212\305" \ + "D\212\307<\216\306\77\211\307>\211\214\306>\4\304\343\240\373\377\376" \ + "\377\377\377\375\377\376\202\377\377\377\1\377\377\375\225\377\377\377" \ + "\1\376\376\376\204\377\377\377\6\265\265\267__a99;;;=::<;;=\202::<\1" \ + ";;=\202::<\1;;=\202::<\1;;=\203::<\1;;=\203::<\3;;=::<99;\202::<\2xx" \ + "z\301\301\301\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \ + "\376\206\377\377\377\1\376\376\376\217\377\377\377\1\316\316\316\205" \ + "::<\202;;=\221::<\4TTVwwy\250\250\252\346\346\350\255\377\377\377\1\316" \ + "\316\320\202::<\1\316\316\316\244\377\377\377\1\234\234\236\204::<\1" \ + ";;=\205::<\3;;=::<;;=\206::<\1;;=\204::<\6SSUkkm\204\204\206\250\250" \ + "\250\316\316\316\376\376\376\206\377\377\377\1\376\376\376\231\377\377" \ + "\377\1\234\234\234\206::<\3;;=::<;;=\222::<\1;;=\204::<\3;;=::<\234\234" \ + "\236\231\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214" \ + "\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325" \ + "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306>" \ + "\15\212\306@\215\307\77\233\316W\365\374\364\377\376\375\376\377\377" \ + "\377\376\377\377\377\375\377\377\377\377\377\375\376\376\376\377\377" \ + "\377\376\376\374\202\377\377\377\1\376\376\376\216\377\377\377\213\214" \ + "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \ + "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \ + "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \ + "\305@\214\306>\214\305@\212\377\377\377\7\350\364\334\215\305>\212\307" \ + "<\214\305@\215\304B\215\305@\213\310\77\210\214\306>\10\214\305@\225" \ + "\311J\370\373\362\377\376\377\376\377\377\377\377\375\377\377\377\376" \ + "\377\377\210\377\377\377\40\376\377\377\376\377\375\377\376\377\377\377" \ + "\377\375\376\377\377\377\375\377\376\377\376\377\377\370\373\364\233" \ + "\314W\215\307\77\214\304=\212\306@\215\307\77\213\305=\215\307\77\214" \ + "\306>\217\304@\215\306A\212\307>\214\306<\215\306A\214\306>\211\307@" \ + "\242\321a\377\377\377\377\376\377\376\377\377\377\376\377\377\377\377" \ + "\376\377\377\377\376\377\223\377\377\377\7\376\376\376\377\377\377\376" \ + "\376\376\377\377\377\363\363\365\234\234\236FFH\202::<\10;;=99;;;=::" \ + "<;;=::<99;;;=\203::<\1;;=\203::<\2;;=99;\204::<\11""99;;;=::<;;=::<;" \ + ";=TTV\265\265\265\363\363\363\203\377\377\377\1\376\376\376\207\377\377" \ + "\377\1\376\376\376\215\377\377\377\1\316\316\316\205::<\3;;=::<;;=\202" \ + "::<\1;;=\214::<\3;;=99;;;=\202::<\4lln\316\316\316\376\376\376\377\377" \ + "\377\202\376\376\376\246\377\377\377\2\376\376\376xxz\202::<\2xxx\376" \ + "\376\376\243\377\377\377\1\234\234\236\204::<\202;;=\205::<\1;;=\204" \ + "::<\1;;=\202::<\1""99;\206::<\1;;=\202::<\6;;=kkk\250\250\250\346\346" \ + "\346\377\377\377\376\376\376\205\377\377\377\1\376\376\376\225\377\377" \ + "\377\1\234\234\234\204::<\1;;=\202::<\4;;=::<99;;;=\225::<\3;;=::<\234" \ + "\234\236\231\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4" \ + "\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250" \ + "\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306" \ + ">\4\215\306A\213\304\77\215\305@\262\327x\202\377\377\377\1\376\377\375" \ + "\203\377\377\375\204\377\377\377\1\376\376\376\217\377\377\377\213\214" \ + "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \ + "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \ + "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \ + "\305@\214\306>\214\305@\212\377\377\377\7\376\376\376\305\342\237\212" \ + "\307>\214\306>\212\307<\214\306>\212\307>\210\214\306>\3\214\306<\215" \ + "\306A\300\337\221\202\377\377\377\3\377\376\377\376\376\376\377\377\375" \ + "\210\377\377\377\1\377\375\377\202\377\377\377\2\376\376\377\376\377" \ + "\375\202\377\376\377\30\377\377\377\277\340\221\215\306A\213\305=\215" \ + "\305>\212\306B\214\306>\216\306\77\214\306<\212\307>\215\307=\213\305" \ + ";\215\307\77\216\305C\214\306>\214\305@\216\306\77\347\365\333\377\376" \ + "\377\377\377\375\376\377\377\377\376\374\377\377\377\377\377\375\222" \ + "\377\377\377\1\376\376\376\204\377\377\377\12\265\265\267FFH;;=::<;;" \ + "=99;::<;;=::<;;=\202::<\4<<>99;::<;;=\202::<\1;;=\203::<\1<<>\204::<" \ + "\5<<>99;;;=99;;;=\202::<\4:::SSS\266\266\266\376\376\376\203\377\377" \ + "\377\1\376\376\376\204\377\377\377\1\376\376\376\216\377\377\377\1\316" \ + "\316\316\204::<\3;;=::<;;=\204::<\1;;=\214::<\1;;=\202::<\1;;=\202::" \ + "<\2yyy\363\363\363\202\377\377\377\1\376\376\376\245\377\377\377\3\346" \ + "\346\346::<;;=\202::<\1\347\347\347\202\377\377\377\1\376\376\376\240" \ + "\377\377\377\1\234\234\236\203::<\4;;=99;::<;;=\202::<\7;;=::<;;=99;" \ + ";;=::<;;=\203::<\202;;=\210::<\1""99;\202::<\4;;=xxz\317\317\317\376" \ + "\376\376\202\377\377\377\1\376\376\376\227\377\377\377\1\234\234\234" \ + "\204::<\1""99;\203;;=\224::<\1;;=\204::<\2<<>\234\234\236\231\377\377" \ + "\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214" \ + "\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \ + "\1\342\361\320\202\214\306>\1\214\305@\210\214\306>\10\215\305>\214\306" \ + ">\213\307A\214\306>\315\345\253\377\377\375\377\376\377\376\377\377\226" \ + "\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \ + "\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214" \ + "\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@" \ + "\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377\377\7\377\377" \ + "\375\377\376\377\376\376\376\241\321a\212\307>\211\305\77\215\306A\211" \ + "\214\306>\4\213\310\77\214\305@\213\305=\342\361\320\202\377\376\377" \ + "\2\377\377\375\377\376\377\210\377\377\377\1\377\376\377\202\377\377" \ + "\377\30\377\377\375\376\377\377\377\377\375\376\377\377\351\366\334\214" \ + "\305B\211\306;\215\307\77\214\306>\212\306@\215\305>\215\305@\212\307" \ + ">\214\305@\212\306B\214\306>\213\305=\213\310\77\215\305>\215\307\77" \ + "\314\345\253\377\375\377\377\376\374\376\377\377\203\377\377\377\1\377" \ + "\376\374\225\377\377\377\2\345\345\345kkm\205::<\202;;=\203::<\1;;=\203" \ + "::<\1;;=\202::<\202;;=\202::<\1;;=\210::<\2;;=99;\205::<\2```\331\331" \ + "\331\211\377\377\377\1\376\376\376\214\377\377\377\1\316\316\316\206" \ + "::<\5""99;::<;;=::<99;\212::<\1;;=\202::<\1;;=\204::<\4;;=::<FFF\316" \ + "\316\316\247\377\377\377\3\205\205\207;;=99;\202::<\1\204\204\206\203" \ + "\377\377\377\1\376\376\376\237\377\377\377\1\234\234\236\205::<\1;;=" \ + "\204::<\1""99;\202;;=\202::<\3;;=::<;;=\203::<\1;;=\202::<\1;;=\204:" \ + ":<\1;;=\205::<\2jjl\316\316\316\203\377\377\377\1\376\376\376\225\377" \ + "\377\377\1\234\234\234\204::<\1;;=\202::<\3;;=::<;;=\222::<\7;;=::<;" \ + ";=::<;;=::<\234\234\236\231\377\377\377\3\214\305@\214\306>\214\305@" \ + "\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215" \ + "\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214" \ + "\305@\210\214\306>\10\215\305@\212\307>\214\305@\215\306A\214\305@\352" \ + "\364\334\376\376\377\377\377\373\202\377\377\377\3\376\376\376\377\377" \ + "\377\377\377\375\202\377\377\377\1\376\376\374\216\377\377\377\213\214" \ + "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \ + "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \ + "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \ + "\305@\214\306>\214\305@\211\377\377\377\1\376\377\377\202\377\377\375" \ + "\5\347\364\332\215\307\77\215\306C\214\307;\216\306\77\210\214\306>\10" \ + "\214\305@\214\305D\215\307\77\233\314V\371\374\363\376\377\377\377\377" \ + "\377\377\377\375\210\377\377\377\20\375\377\374\377\376\377\376\376\377" \ + "\376\377\377\377\376\377\376\377\375\376\377\377\244\317d\212\307>\215" \ + "\306A\215\305@\214\305@\211\306=\215\307=\215\306A\214\305@\204\214\306" \ + ">\14\211\305A\212\307>\251\324k\377\376\377\377\375\376\376\377\377\377" \ + "\377\377\377\377\375\377\377\377\377\377\375\377\377\377\377\377\375" \ + "\217\377\377\377\1\376\376\376\203\377\377\377\2\265\265\267FFH\205:" \ + ":<\1;;=\203::<\202;;=\7:::TTT\203\203\203\235\235\235\316\316\316\332" \ + "\332\332\377\377\377\202\376\376\376\202\377\377\377\5\316\316\316\317" \ + "\317\317\234\234\234yyyFFF\202::<\1;;=\202::<\3""99;;;=99;\204::<\2;" \ + ";=\233\233\233\206\377\377\377\1\376\376\376\216\377\377\377\1\316\316" \ + "\316\204::<\1;;=\205::<\1;;=\212::<\3""99;::<;;=\202::<\2;;=99;\204:" \ + ":<\2;;=\265\265\265\245\377\377\377\4\346\346\346::<99;;;=\202::<\4""9" \ + "9;\347\347\347\377\377\377\376\376\376\240\377\377\377\1\234\234\236" \ + "\205::<\1;;=\203::<\202;;=\1""99;\203;;=\2::<;;=\203::<\1;;=\202::<\2" \ + ";;=::<\202;;=\7::<;;=99;::<;;=99;;;=\202::<\3;;=xxx\362\362\362\227\377" \ + "\377\377\1\234\234\234\205::<\202;;=\4::<;;=::<;;=\223::<\2;;=99;\202" \ + ";;=\1\234\234\236\231\377\377\377\3\214\305@\214\306>\214\305@\207\214" \ + "\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306" \ + ">\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210" \ + "\214\306>\12\212\307>\215\306A\214\305@\215\307\77\213\306:\226\312N" \ + "\372\374\361\375\376\377\377\377\375\377\377\373\224\377\377\377\213" \ + "\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p" \ + "\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \ + "@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>" \ + "\3\214\305@\214\306>\214\305@\211\377\377\377\10\376\377\377\376\376" \ + "\377\376\377\377\377\375\376\307\342\237\214\306<\215\306A\214\305@\210" \ + "\214\306>\5\215\307\77\213\305=\216\306A\213\310\77\277\337\223\202\377" \ + "\377\375\1\377\376\377\210\377\377\377\14\376\377\375\376\376\376\377" \ + "\376\377\377\377\375\377\376\377\377\377\377\303\342\236\215\307\77\216" \ + "\306A\215\305>\214\306<\215\306A\203\214\306>\20\215\307\77\212\307>" \ + "\215\305@\216\306\77\214\305@\216\307<\223\312K\356\372\346\377\377\377" \ + "\376\377\377\375\377\376\377\377\377\377\376\377\377\377\375\377\377" \ + "\377\377\377\375\216\377\377\377\1\376\376\376\203\377\377\377\2\375" \ + "\375\375\205\205\207\202::<\202;;=\3::<;;=::<\202;;=\6::<:::SSS\250\250" \ + "\250\346\346\346\376\376\376\216\377\377\377\3\332\332\332\220\220\220" \ + "SSS\202::<\4;;=99;::<;;=\202::<\1""99;\202;;=\2__a\332\332\334\223\377" \ + "\377\377\1\316\316\316\204::<\6;;=RRT\235\235\237\235\235\235\233\233" \ + "\233\234\234\234\212\234\234\236\5xxzkkm__a99;;;=\204::<\202;;=\1""9" \ + "9;\202::<\1\316\316\316\244\377\377\377\4\204\204\206;;=::<;;=\202::" \ + "<\2;;=\220\220\222\203\377\377\377\1\376\376\376\236\377\377\377\1\234" \ + "\234\236\203::<\3;;=::<kkm\203\234\234\236\3\233\233\235\234\234\236" \ + "\235\235\237\204\234\234\236\2xxzlln\202kkm\1FFH\202;;=\2""99;;;=\202" \ + "::<\3""99;::<;;=\202::<\1;;=\205::<\3GGI\301\301\301\376\376\376\225" \ + "\377\377\377\1\234\234\234\205::<\5lln\234\234\236\233\233\233\235\235" \ + "\235\234\234\234\224\234\234\236\5\234\234\234\235\235\235\233\233\233" \ + "\234\234\234\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305" \ + "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \ + "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \ + "\214\305@\210\214\306>\7\212\306@\214\306<\217\307@\214\304\77\214\311" \ + ">\214\306>\251\323m\202\376\377\377\4\376\376\374\377\377\375\377\377" \ + "\377\376\376\376\202\377\377\377\1\376\376\376\216\377\377\377\213\214" \ + "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \ + "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \ + "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \ + "\305@\214\306>\214\305@\212\377\377\377\7\377\377\375\377\376\377\376" \ + "\377\377\377\376\377\251\323o\211\307>\214\305@\210\214\306>\7\212\307" \ + ">\215\305>\214\305@\214\306>\215\307\77\347\365\334\377\376\377\211\377" \ + "\377\377\2\377\376\377\375\377\374\203\377\376\377\15\352\364\333\212" \ + "\306@\215\306A\214\306>\215\307\77\213\310\77\214\306>\216\306A\215\306" \ + "A\214\306<\212\307>\213\310=\212\307>\202\214\305@\4\214\306>\314\345" \ + "\253\377\376\377\376\377\377\202\377\377\375\6\377\376\377\375\376\377" \ + "\377\377\377\377\376\377\376\377\375\377\376\377\217\377\377\377\3\376" \ + "\376\376\362\362\362lln\20299;\1;;=\204::<\202;;=\6::<\204\204\204\317" \ + "\317\317\376\376\376\377\377\377\376\376\376\206\377\377\377\1\376\376" \ + "\376\213\377\377\377\2\301\301\301kkm\211::<\6;;=FFH\301\301\301\376" \ + "\376\376\377\377\377\376\376\376\217\377\377\377\1\316\316\316\204::" \ + "<\3;;=kkm\376\376\376\221\377\377\377\3\316\316\316\204\204\204FFF\202" \ + "::<\1;;=\202::<\202;;=\2FFH\363\363\363\242\377\377\377\5\364\364\364" \ + "::<;;=99;;;=\203::<\3GGI\363\363\363\376\376\376\240\377\377\377\1\234" \ + "\234\236\205::<\1\234\234\236\210\377\377\377\1\376\376\376\204\377\377" \ + "\377\1\376\376\376\202\377\377\377\6\362\362\362\316\316\316\265\265" \ + "\265\234\234\234kkmFFH\202::<\2;;=99;\205::<\1;;=\202::<\1\221\221\221" \ + "\225\377\377\377\1\234\234\234\205::<\1\234\234\236\202\377\377\377\1" \ + "\376\376\376\225\377\377\377\1\375\375\375\235\377\377\377\3\214\305" \ + "@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324" \ + "p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320" \ + "\202\214\306>\1\214\305@\210\214\306>\4\215\307\77\214\306>\214\304\77" \ + "\214\306>\202\214\305@\6\215\307\77\307\341\240\376\377\375\376\377\377" \ + "\376\376\374\377\377\373\202\377\377\377\202\377\377\375\216\377\377" \ + "\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252" \ + "\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214" \ + "\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \ + ">\3\214\305@\214\306>\214\305@\212\377\377\377\7\377\376\377\376\376" \ + "\377\377\377\377\376\376\377\361\372\347\222\312K\215\305>\210\214\306" \ + ">\10\214\305@\215\306A\214\305@\214\306<\213\304A\243\322b\376\376\374" \ + "\376\377\375\211\377\377\377\24\377\377\373\377\377\377\376\377\377\377" \ + "\377\375\242\320c\215\307=\214\306>\213\310\77\213\304A\212\306@\215" \ + "\307\77\215\305@\214\306>\215\307\77\212\306@\215\305>\215\307\77\213" \ + "\310\77\213\306:\253\325q\202\377\377\377\11\377\377\375\377\376\377" \ + "\377\377\377\377\377\375\376\377\375\377\377\375\377\375\377\376\377" \ + "\377\377\377\375\214\377\377\377\7\376\376\376\377\377\377\376\376\376" \ + "\363\363\363__a::<;;=\203::<\202;;=\202::<\4xxz\347\347\351\377\377\377" \ + "\376\376\376\210\377\377\377\1\376\376\376\204\377\377\377\2\376\376" \ + "\376\377\377\377\203\376\376\376\205\377\377\377\2\316\316\320kkm\202" \ + "::<\3;;=::<;;=\202::<\202;;=\2:::\250\250\250\202\377\377\377\1\376\376" \ + "\376\216\377\377\377\1\316\316\316\205::<\1kkm\203\377\377\377\1\376" \ + "\376\376\215\377\377\377\1\376\376\376\202\377\377\377\3\363\363\363" \ + "xxx::<\202;;=\203::<\2;;=xxz\242\377\377\377\1\234\234\234\202::<\1;" \ + ";=\202::<\1;;=\202::<\1\234\234\234\241\377\377\377\1\234\234\236\202" \ + "::<\10;;=::<;;=\234\234\236\377\377\377\376\376\376\377\377\377\376\376" \ + "\376\216\377\377\377\1\376\376\376\203\377\377\377\3\332\332\332\221" \ + "\221\223FFH\205::<\2;;=::<\202;;=\2::<\204\204\204\224\377\377\377\1" \ + "\234\234\234\205::<\3\234\234\236\377\377\377\376\376\376\264\377\377" \ + "\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214" \ + "\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \ + "\1\342\361\320\202\214\306>\1\214\305@\210\214\306>\5\216\306\77\212" \ + "\307>\215\307=\212\306@\214\306>\202\215\305>\5\215\305@\345\356\317" \ + "\376\377\375\376\377\377\377\377\375\202\377\377\377\1\377\377\375\217" \ + "\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \ + "\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214" \ + "\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@" \ + "\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377\377\4\376\377" \ + "\377\377\377\377\377\377\375\376\377\377\202\377\377\377\2\315\347\252" \ + "\212\306@\210\214\306>\10\216\306A\212\306@\212\307>\215\305<\213\310" \ + "\77\215\305>\307\341\240\376\377\377\212\377\377\377\10\375\377\374\377" \ + "\377\377\305\342\237\215\305@\212\306@\216\306\77\215\307=\215\305>\202" \ + "\214\306>\24\213\307A\213\310=\215\304B\214\306>\212\306@\215\304B\212" \ + "\307>\225\311K\370\373\362\377\377\377\376\377\375\377\377\375\377\377" \ + "\377\374\377\375\376\376\376\377\377\377\377\377\375\377\376\377\376" \ + "\377\377\377\377\375\211\377\377\377\1\376\376\376\205\377\377\377\1" \ + "___\204::<\1;;=\203::<\2SSS\316\316\316\235\377\377\377\2\317\317\317" \ + "``b\207::<\3;;=::<\204\204\206\220\377\377\377\1\316\316\316\205::<\1" \ + "kkm\226\377\377\377\3\204\204\206::<;;=\205::<\1\316\316\316\232\377" \ + "\377\377\1\376\376\376\205\377\377\377\2\364\364\364FFF\202;;=\202::" \ + "<\6;;=99;;;=::<FFH\363\363\363\240\377\377\377\1\234\234\236\205::<\1" \ + "\234\234\234\226\377\377\377\1\376\376\376\202\377\377\377\3\265\265" \ + "\265RRR:::\202::<\1;;=\202::<\4;;=::<;;=\204\204\204\203\377\377\377" \ + "\1\376\376\376\217\377\377\377\1\234\234\234\205::<\1\234\234\236\266" \ + "\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215" \ + "\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377" \ + "\377\377\1\342\361\320\202\214\306>\1\214\305@\220\214\306>\2\222\313" \ + "J\366\373\364\202\377\376\377\4\377\377\373\376\376\374\376\377\377\377" \ + "\376\377\216\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240" \ + "\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3" \ + "\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305" \ + ">\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377\377" \ + "-\377\377\375\376\377\377\377\377\377\376\376\374\376\377\377\377\376" \ + "\377\376\377\377\252\324p\212\306@\215\305>\212\307<\215\305@\215\305" \ + "<\214\305B\215\305@\214\306<\212\307>\215\305>\214\306>\211\306=\215" \ + "\305>\212\307>\214\306<\350\364\334\374\377\377\377\376\377\376\376\376" \ + "\374\377\375\377\377\377\376\377\375\377\377\375\377\376\377\377\377" \ + "\375\377\377\377\377\376\377\357\367\350\223\312K\213\310\77\215\305" \ + ">\214\306>\215\305>\213\310\77\212\306@\214\306>\215\305@\202\214\306" \ + ">\10\214\305@\216\306=\212\307>\215\305>\333\355\303\376\376\374\377" \ + "\377\377\377\377\375\223\377\377\377\1\376\376\376\203\377\377\377\1" \ + "\203\203\203\206::<\4;;=::<\204\204\206\363\363\363\230\377\377\377\1" \ + "\376\376\376\207\377\377\377\1\235\235\237\202::<\1;;=\203::<\5;;=99" \ + ";;;=\204\204\204\376\376\376\216\377\377\377\1\316\316\316\205::<\1k" \ + "km\227\377\377\377\12\204\204\206::<;;=::<99;;;=::<\204\204\204\377\377" \ + "\377\376\376\376\232\377\377\377\1\376\376\376\203\377\377\377\2\234" \ + "\234\234;;=\203::<\1;;=\204::<\3<<>\250\250\250\376\376\376\237\377\377" \ + "\377\1\234\234\236\205::<\1\234\234\234\231\377\377\377\10\376\376\376" \ + "\377\377\377\265\265\265FFH::<;;=::<;;=\203::<\2;;=\204\204\204\222\377" \ + "\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305" \ + "@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324" \ + "p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320" \ + "\202\214\306>\1\214\305@\220\214\306>\4\216\306\77\250\322n\376\377\375" \ + "\376\377\373\222\377\377\377\213\214\306>\3\215\305>\214\306>\305\342" \ + "\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \ + ">\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215" \ + "\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377" \ + "\377\13\376\376\377\376\377\377\377\376\377\376\376\374\374\377\377\377" \ + "\377\375\377\376\377\356\372\346\225\311K\214\306>\213\310=\203\214\306" \ + ">\2\213\310\77\214\306>\202\214\305@\7\214\306<\213\307A\214\304\77\214" \ + "\305B\212\307>\244\317d\377\376\377\202\377\377\377\1\377\375\377\202" \ + "\377\377\377\25\376\377\377\377\376\377\377\377\377\374\377\375\376\376" \ + "\374\253\324n\214\306<\215\307\77\215\305>\211\307@\216\305C\214\305" \ + "@\215\307\77\214\305@\214\306<\212\307<\211\306=\214\306>\214\305@\213" \ + "\307A\263\327}\202\376\377\377\3\377\377\377\377\375\376\377\377\375" \ + "\221\377\377\377\1\376\376\376\203\377\377\377\1\250\250\250\204::<\1" \ + ";;=\202::<\2;;=\264\264\264\202\377\377\377\1\376\376\376\232\377\377" \ + "\377\1\376\376\376\205\377\377\377\2\332\332\332SSS\202::<\1;;=\204:" \ + ":<\4xxx\364\364\364\377\377\377\376\376\376\214\377\377\377\1\316\316" \ + "\316\205::<\1kkm\227\377\377\377\2\363\363\363SSU\202::<\4;;=99;::<;" \ + ";;\202\377\377\377\1\376\376\376\226\377\377\377\1\376\376\376\204\377" \ + "\377\377\11\376\376\376\363\363\363FFH99;;;=::<;;=99;;;=\203::<\4""9" \ + "9;SSU\377\377\377\376\376\376\236\377\377\377\1\234\234\236\205::<\1" \ + "\234\234\234\225\377\377\377\1\376\376\376\204\377\377\377\10\376\376" \ + "\376\377\377\377\363\363\363yyy::<;;=99;;;=\204::<\1\266\266\266\221" \ + "\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214" \ + "\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252" \ + "\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361" \ + "\320\202\214\306>\1\214\305@\220\214\306>\4\214\306<\213\307A\275\335" \ + "\222\376\377\377\203\377\377\377\1\377\377\375\216\377\377\377\213\214" \ + "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \ + "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \ + "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \ + "\305@\214\306>\214\305@\211\377\377\377\4\377\376\377\376\376\377\377" \ + "\377\377\377\377\375\202\376\377\377\5\377\375\376\377\376\377\315\346" \ + "\255\212\307>\214\305@\202\215\306A\22\214\305@\212\307<\214\305B\214" \ + "\306>\213\307A\214\306>\213\305=\214\306>\215\305>\213\307A\211\310<" \ + "\313\347\254\377\377\375\377\375\377\376\377\377\376\377\373\376\377" \ + "\377\377\376\377\202\376\377\377\10\377\377\377\315\346\254\212\307>" \ + "\212\306@\215\306A\216\306A\212\307>\214\306<\202\215\306A\10\215\306" \ + "C\214\305B\215\307\77\214\306<\214\305@\213\310<\222\310L\372\373\363" \ + "\225\377\377\377\1\376\376\376\202\377\377\377\6\376\376\376\333\333" \ + "\333::<;;=::<;;=\202::<\3;;=FFH\315\315\315\205\377\377\377\1\376\376" \ + "\376\225\377\377\377\202\376\376\376\202\377\377\377\1\376\376\376\202" \ + "\377\377\377\1\376\376\376\202\377\377\377\2\363\363\363xxx\204::<\2" \ + ";;=\203\203\203\220\377\377\377\1\316\316\316\205::<\1kkm\230\377\377" \ + "\377\3\266\266\27099;;;=\204::<\1\316\316\316\230\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\376\376\376\202\377\377\377\3\265\265\267::<;" \ + ";=\204::<\202;;=\202::<\202;;=\1\265\265\265\237\377\377\377\1\234\234" \ + "\236\205::<\1\234\234\234\236\377\377\377\5\234\234\234::<;;=::<;;=\202" \ + "::<\3;;=FFH\332\332\332\220\377\377\377\1\234\234\234\205::<\1\234\234" \ + "\236\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214" \ + "\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325" \ + "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\220\214\306>" \ + "\4\215\307\77\214\304\77\213\310\77\333\355\303\202\377\377\377\1\376" \ + "\377\375\217\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240" \ + "\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3" \ + "\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305" \ + ">\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\213\377\377\377" \ + "\5\377\377\373\377\376\377\377\377\377\375\377\374\376\377\377\202\376" \ + "\376\376\22\260\331{\212\307>\214\306>\215\305>\215\305@\215\307\77\215" \ + "\307=\214\305@\214\306>\215\306A\214\306>\213\307C\214\306>\214\304;" \ + "\213\307A\222\312K\357\370\345\377\377\375\202\377\377\377\15\377\375" \ + "\376\377\377\375\376\376\376\377\377\375\361\367\351\222\311J\213\310" \ + "\77\214\305B\215\310<\213\305=\216\306\77\212\307<\214\305B\202\214\306" \ + ">\6\216\306\77\215\305@\215\306A\214\305@\215\305<\333\356\301\202\377" \ + "\376\377\3\377\377\375\377\377\377\377\376\377\225\377\377\377\1``b\202" \ + "::<\6;;=::<;;=::<FFH\331\331\333\233\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\376\376\376\206\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\205\205\207\203::<\1\204\204\206\221\377\377\377\1\316\316\316\205" \ + "::<\1kkm\231\377\377\377\1GGI\203;;=\202::<\3\235\235\237\377\377\377" \ + "\376\376\376\233\377\377\377\2\376\376\376SSU\203::<\5;;=99;llnkkm::" \ + "<\202;;=\202::<\1SSU\237\377\377\377\1\234\234\236\205::<\1\234\234\234" \ + "\224\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\203\377" \ + "\377\377\4\376\376\376\266\266\270::<;;=\203::<\5""99;::<__a\377\377" \ + "\377\376\376\376\216\377\377\377\1\234\234\234\205::<\1\234\234\236\266" \ + "\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215" \ + "\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377" \ + "\377\377\1\342\361\320\202\214\306>\1\214\305@\220\214\306>\10\216\306" \ + "\77\215\306A\214\305@\224\310J\360\371\350\377\377\377\377\376\377\376" \ + "\377\377\216\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240" \ + "\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3" \ + "\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305" \ + ">\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\212\377\377\377" \ + "\1\377\377\375\202\377\377\377\2\377\376\377\377\377\377\202\376\377" \ + "\377\25\377\377\375\370\373\362\223\312K\212\307>\215\305>\216\306A\212" \ + "\307<\214\305B\215\307\77\214\305@\214\306>\214\305@\212\306@\215\307" \ + "=\216\306A\215\305>\214\306<\252\324n\376\377\377\376\376\376\377\376" \ + "\377\202\377\377\375\4\377\376\377\376\376\377\252\324n\215\306A\202" \ + "\214\306>\21\214\305@\215\307\77\215\305>\212\307>\214\306<\213\304A" \ + "\215\307=\214\304=\215\307\77\212\307>\214\306>\277\337\226\377\376\377" \ + "\376\377\375\377\377\375\377\377\377\376\376\376\225\377\377\377\3\234" \ + "\234\236::<;;=\204::<\4;;=\265\265\267\377\377\377\376\376\376\204\377" \ + "\377\377\202\376\376\376\202\377\377\377\1\376\376\376\225\377\377\377" \ + "\1\376\376\376\203\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \ + "\376\202\377\377\377\3\250\250\250::<\204\204\206\205\377\377\377\1\376" \ + "\376\376\214\377\377\377\1\316\316\316\205::<\1kkm\226\377\377\377\1" \ + "\376\376\376\202\377\377\377\2kkm99;\202::<\4;;=::<\204\204\206\376\376" \ + "\376\202\377\377\377\1\376\376\376\224\377\377\377\1\376\376\376\203" \ + "\377\377\377\2\376\376\376\265\265\265\202::<\1;;=\202::<\3;;=\316\316" \ + "\320\316\316\316\204::<\3;;=::<\266\266\266\236\377\377\377\1\234\234" \ + "\236\205::<\1\234\234\234\226\377\377\377\202\376\376\376\2\377\377\377" \ + "\376\376\376\205\377\377\377\4\376\376\376\251\251\253;;=99;\202::<\4" \ + "<<>99;::<\250\250\252\217\377\377\377\1\234\234\234\205::<\1\234\234" \ + "\236\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214" \ + "\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325" \ + "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\220\214\306>" \ + "\202\214\305@\6\212\306@\215\307\77\243\321d\377\377\375\377\375\377" \ + "\376\377\377\216\377\377\377\213\214\306>\3\215\305>\214\306>\305\342" \ + "\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \ + ">\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215" \ + "\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377" \ + "\377\2\376\377\377\377\377\375\202\377\377\377\1\376\376\376\202\377" \ + "\377\377\6\376\377\372\376\377\377\377\376\377\331\357\301\213\304\77" \ + "\215\307=\202\214\305@\25\214\305B\214\306<\215\305@\212\307<\214\306" \ + ">\216\306=\212\307>\212\306B\214\305@\215\306E\212\306@\313\347\255\376" \ + "\377\375\376\376\377\376\377\377\377\376\377\377\377\377\333\355\305" \ + "\212\307>\216\306\77\215\307\77\202\214\306>\1\215\307\77\202\214\306" \ + ">\13\215\305<\212\306@\212\307<\215\307\77\211\306=\213\307A\233\314" \ + "V\370\373\362\377\377\375\377\377\377\376\377\377\202\377\377\375\2\374" \ + "\377\377\377\375\376\222\377\377\377\3\363\363\363GGI::<\202;;=\202:" \ + ":<\2;;=\234\234\234\214\377\377\377\1\376\376\376\221\377\377\377\1\376" \ + "\376\376\202\377\377\377\3\376\376\376\377\377\377\376\376\376\206\377" \ + "\377\377\3\376\376\376\377\377\377\316\316\316\203\377\377\377\1\376" \ + "\376\376\203\377\377\377\1\376\376\376\213\377\377\377\1\316\316\316" \ + "\205::<\1kkm\227\377\377\377\5\376\376\376\377\377\377\235\235\237::" \ + "<;;=\203::<\2lln\376\376\376\203\377\377\377\1\376\376\376\224\377\377" \ + "\377\13\376\376\376\377\377\377\376\376\376\377\377\377RRR::<99;::<;" \ + ";=::<kkm\202\377\377\377\1__a\203;;=\202::<\1kkk\236\377\377\377\1\234" \ + "\234\236\205::<\1\234\234\234\241\377\377\377\2\204\204\204;;=\202::" \ + "<\5""99;::<;;=FFH\363\363\363\216\377\377\377\1\234\234\234\205::<\1" \ + "\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306" \ + ">\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>" \ + "\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\221" \ + "\214\306>\5\213\307A\216\306\77\212\307<\214\306>\277\337\223\220\377" \ + "\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377" \ + "\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306" \ + ">\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207" \ + "\214\306>\3\214\305@\214\306>\214\305@\211\377\377\377\4\376\377\377" \ + "\377\377\375\377\375\377\377\377\377\202\377\377\375\202\377\376\377" \ + "\202\376\377\377\22\377\376\377\262\331~\213\304\77\213\310\77\216\306" \ + "A\212\307<\215\306A\214\304=\213\310\77\214\305@\215\304B\214\305B\214" \ + "\306<\212\307>\212\307<\216\306A\221\312I\370\373\362\203\377\377\377" \ + "\13\370\373\364\226\310K\214\306>\212\307>\215\304B\214\306>\215\306" \ + "A\213\304\77\215\306A\214\306>\215\305@\202\212\306@\13\215\307\77\213" \ + "\310=\220\303@\336\362\315\377\376\377\377\377\377\374\377\377\377\376" \ + "\377\377\377\377\376\376\374\376\377\375\223\377\377\377\1\204\204\206" \ + "\203::<\4""99;;;=::<kkm\211\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\376\376\376\221\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \ + "\376\237\377\377\377\1\316\316\316\205::<\1kkm\231\377\377\377\4\234" \ + "\234\236;;=::<;;=\202::<\3jjl\377\377\377\376\376\376\232\377\377\377" \ + "\10\265\265\265:::::<;;=::<99;::<\316\316\316\202\377\377\377\1\265\265" \ + "\267\204::<\3;;=::<\316\316\316\235\377\377\377\1\234\234\236\205::<" \ + "\1\234\234\234\241\377\377\377\2\363\363\363__a\203::<\4;;=::<;;=\234" \ + "\234\236\216\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377" \ + "\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214" \ + "\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \ + "\1\342\361\320\202\214\306>\1\214\305@\220\214\306>\10\215\304B\214\306" \ + "<\214\305@\215\305@\212\306@\215\305>\323\354\265\377\376\377\216\377" \ + "\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377" \ + "\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306" \ + ">\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207" \ + "\214\306>\3\214\305@\214\306>\214\305@\212\377\377\377\3\375\377\376" \ + "\377\377\377\377\377\375\202\377\377\377\26\377\377\375\375\377\374\376" \ + "\377\377\377\376\377\377\377\375\365\375\362\225\311K\212\306@\214\306" \ + ">\214\305@\212\306@\216\306=\211\306;\215\306A\214\306>\215\307\77\217" \ + "\304@\214\306>\212\307>\215\305@\214\305@\262\327z\203\377\377\377\13" \ + "\260\331{\213\310\77\214\305B\214\305@\215\305@\215\307\77\212\307<\216" \ + "\306A\213\305;\214\305@\215\305>\202\214\306>\11\215\305@\214\306<\276" \ + "\340\224\377\376\375\377\377\375\376\377\377\377\376\375\376\377\375" \ + "\377\376\377\202\377\377\377\1\376\377\375\221\377\377\377\1\346\346" \ + "\346\206::<\2:::\346\346\346\202\377\377\377\1\376\376\376\276\377\377" \ + "\377\1\316\316\316\205::<\1kkm\216\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\376\376\376\207\377\377\377\3\234\234\236::<;;=\203::<\1k" \ + "km\226\377\377\377\1\376\376\376\204\377\377\377\2\376\376\376lln\205" \ + "::<\1``b\204\377\377\377\1SSS\205::<\1kkm\235\377\377\377\1\234\234\236" \ + "\205::<\1\234\234\234\242\377\377\377\2\316\316\316:::\202::<\5;;=::" \ + "<;;=FFH\363\363\363\206\377\377\377\1\376\376\376\206\377\377\377\1\234" \ + "\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214" \ + "\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377" \ + "\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306" \ + ">\1\214\305@\210\214\306>\27\215\306A\212\307>\215\305>\215\305@\215" \ + "\307=\217\304B\214\306<\214\305@\215\307\77\215\305@\215\307\77\214\305" \ + "@\216\306\77\211\310<\226\312L\347\364\332\377\377\377\377\376\377\377" \ + "\377\375\374\377\377\377\376\377\376\376\376\376\377\377\207\377\377" \ + "\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252" \ + "\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214" \ + "\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \ + ">\3\214\305@\214\306>\214\305@\221\377\377\377\1\377\377\375\203\377" \ + "\377\377\5\333\355\303\214\306>\212\307<\216\306A\214\305@\202\214\306" \ + ">\15\215\305@\214\306>\212\306@\213\310\77\215\305>\216\306A\211\306" \ + "=\212\306@\212\307<\334\354\305\377\377\375\335\354\303\212\307>\210" \ + "\214\306>\10\216\306A\212\307;\215\306A\216\306A\214\305@\241\321a\371" \ + "\374\361\375\376\377\223\377\377\377\1\376\376\376\204\377\377\377\2" \ + "\376\376\376\234\234\234\203::<\1""99;\202::<\1\234\234\234\302\377\377" \ + "\377\1\316\316\316\205::<\1kkm\217\377\377\377\1\376\376\376\202\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\3\376" \ + "\376\376\377\377\377xxz\202::<\5""99;::<;;=xxz\376\376\377\232\377\377" \ + "\377\3\317\317\31799;;;=\202::<\5;;=::<\265\265\265\377\377\377\376\376" \ + "\376\202\377\377\377\2\265\265\265;;=\202::<\203;;=\1\332\332\332\203" \ + "\377\377\377\1\376\376\376\230\377\377\377\1\234\234\236\205::<\1\234" \ + "\234\234\242\377\377\377\4\376\376\376\204\204\204::<;;=\202::<\3;;=" \ + "::<\266\266\266\207\377\377\377\1\376\376\376\205\377\377\377\1\234\234" \ + "\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305" \ + "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \ + "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \ + "\214\305@\211\214\306>\27\216\306A\214\306>\212\306@\214\306<\213\310" \ + "\77\215\305@\215\307\77\213\305=\216\306\77\212\307;\212\306@\215\305" \ + ">\215\306A\212\307>\245\320d\367\375\361\376\377\377\377\376\377\377" \ + "\377\377\376\376\377\377\376\377\375\377\376\377\377\375\206\377\377" \ + "\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252" \ + "\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214" \ + "\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \ + ">\3\214\305@\214\306>\214\305@\221\377\377\377\6\376\376\376\377\376" \ + "\377\377\377\377\375\377\376\376\377\377\270\333\207\203\214\306>\17" \ + "\211\306=\212\307<\214\306<\214\305@\215\307\77\214\305@\216\305C\214" \ + "\306>\212\310A\215\305@\216\306\77\223\312K\360\371\346\222\311I\214" \ + "\305@\210\214\306>\10\214\305@\212\307>\214\305@\216\306A\215\307=\350" \ + "\364\334\375\377\376\377\376\377\225\377\377\377\7\376\376\376\377\377" \ + "\377\376\376\376\377\377\377SSS::<;;=\203::<\5FFH\364\364\364\376\376" \ + "\376\377\377\377\376\376\376\277\377\377\377\1\316\316\316\205::<\1k" \ + "km\222\377\377\377\1\376\376\376\204\377\377\377\3\376\376\376\377\377" \ + "\377SSU\205::<\1\234\234\236\202\377\377\377\1\376\376\376\202\377\377" \ + "\377\1\376\376\376\220\377\377\377\1\376\376\376\204\377\377\377\2kk" \ + "m;;=\202::<\5;;=::<SSU\377\377\377\376\376\376\204\377\377\377\7SSU:" \ + ":<;;=::<;;=::<\205\205\205\234\377\377\377\1\234\234\236\205::<\1\234" \ + "\234\234\240\377\377\377\1\376\376\376\202\377\377\377\1\346\346\346" \ + "\202::<\1;;=\202::<\2;;=__a\205\377\377\377\1\376\376\376\202\377\377" \ + "\377\1\376\376\376\204\377\377\377\1\234\234\234\205::<\1\234\234\236" \ + "\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305" \ + "@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p" \ + "\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\27" \ + "\214\304=\215\305>\213\307A\212\306@\214\305B\215\305<\213\310=\215\307" \ + "\77\215\304B\214\306<\213\307A\215\305>\216\306A\212\306@\212\307>\270" \ + "\332\204\377\376\377\377\377\377\377\376\377\376\376\374\377\377\373" \ + "\377\376\377\377\377\375\206\377\377\377\213\214\306>\3\215\305>\214" \ + "\306>\305\342\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305" \ + "@\207\214\306>\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324" \ + "p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \ + "@\223\377\377\377\1\377\377\375\202\377\377\377\2\371\372\364\232\315" \ + "W\202\214\305@\4\214\306<\215\307\77\214\305B\215\306C\202\215\306A\1" \ + "\214\306<\202\212\307>\6\215\305@\212\307>\215\305>\212\306B\216\306" \ + "A\212\307>\210\214\306>\10\214\305B\215\307\77\214\306<\214\306>\304" \ + "\341\237\377\377\377\377\376\377\377\377\375\220\377\377\377\1\376\376" \ + "\376\203\377\377\377\1\376\376\376\203\377\377\377\10\301\301\301::<" \ + ";;=99;;;=::<99;\234\234\236\207\377\377\377\1\376\376\376\273\377\377" \ + "\377\1\316\316\316\205::<\1kkm\216\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\376\376\376\204\377\377\377\3\376\376\376\377\377\377\315" \ + "\315\315\202;;=\203::<\6;;=\265\265\267\377\377\377\376\376\376\377\377" \ + "\377\376\376\376\225\377\377\377\2\376\376\376\317\317\317\203::<\4;" \ + ";=::<;;=\264\264\264\206\377\377\377\10\234\234\234;;=::<;;=99;;;=::" \ + "<\346\346\346\233\377\377\377\1\234\234\236\205::<\1\234\234\234\237" \ + "\377\377\377\1\376\376\376\204\377\377\377\1\204\204\206\202::<\6;;=" \ + "99;;;=::<\346\346\346\376\376\376\204\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\204\377\377\377\1\234\234\234\205::<\1\234\234\236\266" \ + "\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215" \ + "\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377" \ + "\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306>\22\215\307" \ + "\77\212\307>\216\306A\212\304<\215\307\77\215\305@\216\306\77\213\307" \ + "A\214\306>\214\305@\215\307\77\213\310=\212\307>\214\306>\214\306<\214" \ + "\306>\216\306\77\324\353\267\202\376\376\376\3\377\377\377\376\376\377" \ + "\376\377\375\207\377\377\377\213\214\306>\3\215\305>\214\306>\305\342" \ + "\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \ + ">\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215" \ + "\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\221\377\377" \ + "\377\3\376\377\377\377\377\377\376\377\375\202\377\377\377\7\377\376" \ + "\377\341\363\315\215\305@\214\305@\215\306A\215\305@\216\306\77\202\214" \ + "\306>\12\214\305B\212\307<\213\304A\213\310=\216\306A\211\306;\213\310" \ + "=\214\305@\212\307>\215\305>\210\214\306>\10\215\307\77\214\304=\212" \ + "\307>\243\322b\377\377\377\376\377\377\377\376\377\377\377\375\226\377" \ + "\377\377\4\376\376\376\377\377\377\204\204\206;;=\203::<\3""99;;;=\364" \ + "\364\364\205\377\377\377\1\376\376\376\275\377\377\377\1\316\316\316" \ + "\205::<\1kkm\217\377\377\377\202\376\376\376\202\377\377\377\1\376\376" \ + "\376\203\377\377\377\4\376\376\376xxz;;=99;\202;;=\4::<;;=\346\346\346" \ + "\376\376\376\204\377\377\377\1\376\376\376\224\377\377\377\1xxz\203:" \ + ":<\3;;=::<SSU\203\377\377\377\1\376\376\376\203\377\377\377\2\363\363" \ + "\363FFH\202::<\4;;=99;::<\204\204\206\233\377\377\377\1\234\234\236\205" \ + "::<\1\234\234\234\244\377\377\377\1\316\316\316\202;;=\5::<;;=99;;;=" \ + "\250\250\252\203\377\377\377\1\376\376\376\210\377\377\377\1\234\234" \ + "\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305" \ + "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \ + "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \ + "\214\305@\210\214\306>\7\213\305=\214\306<\210\306\77\216\306\77\215" \ + "\307=\214\306>\215\307\77\202\214\306>\14\215\307\77\214\305B\214\306" \ + "<\212\307<\214\305@\216\306\77\215\305>\214\305@\224\313L\352\364\331" \ + "\374\377\377\377\376\377\211\377\377\377\213\214\306>\3\215\305>\214" \ + "\306>\305\342\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305" \ + "@\207\214\306>\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324" \ + "p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \ + "@\222\377\377\377\1\376\377\377\202\377\377\377\24\376\376\374\376\377" \ + "\375\377\375\377\277\337\224\214\306>\212\307>\215\307\77\214\304=\215" \ + "\307=\213\304A\214\306<\212\307>\215\307\77\214\305@\213\304\77\215\307" \ + "\77\215\305@\214\304=\215\305<\215\306A\210\214\306>\1\212\307>\202\215" \ + "\306A\4\350\365\333\377\375\376\377\376\377\375\376\377\226\377\377\377" \ + "\1\376\376\376\202\377\377\377\3TTV::<99;\202;;=\4::<\203\203\203\377" \ + "\377\377\376\376\376\302\377\377\377\1\316\316\316\205::<\1kkm\222\377" \ + "\377\377\1\376\376\376\204\377\377\377\3\300\300\302;;=::<\202;;=\202" \ + "::<\2```\376\376\376\227\377\377\377\7\376\376\376\377\377\377\346\346" \ + "\346;;=99;::<;;=\202::<\3\251\251\251\377\377\377\376\376\376\206\377" \ + "\377\377\1\234\234\234\202::<\1;;=\202::<\2;;=\346\346\346\232\377\377" \ + "\377\1\234\234\236\205::<\1\234\234\234\235\377\377\377\1\376\376\376" \ + "\207\377\377\377\11SSU::<;;=99;<<>::<xxz\377\377\377\376\376\376\212" \ + "\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214" \ + "\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252" \ + "\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361" \ + "\320\202\214\306>\1\214\305@\210\214\306>\25\213\307A\216\306A\232\315" \ + "W\215\306C\212\306@\214\305@\212\307;\216\306A\215\305>\215\307\77\214" \ + "\305@\215\307\77\214\306>\214\305@\212\306B\213\307C\214\306>\215\305" \ + "@\232\315V\372\374\367\376\376\376\202\377\377\375\1\376\376\376\206" \ + "\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \ + "\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214" \ + "\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@" \ + "\207\214\306>\3\214\305@\214\306>\214\305@\221\377\377\377\5\377\376" \ + "\377\376\377\377\377\375\376\377\376\377\376\377\377\202\377\377\377" \ + "\10\370\373\362\233\314V\213\307A\211\306=\215\307\77\212\307<\212\306" \ + "@\215\305<\202\214\306>\7\215\307=\215\306A\214\305@\212\307>\216\306" \ + "A\212\306@\215\307=\210\214\306>\10\212\307>\212\307<\313\347\254\376" \ + "\377\377\377\377\377\377\376\377\376\377\377\377\377\375\223\377\377" \ + "\377\1\376\376\376\203\377\377\377\1\332\332\332\202::<\1;;=\203::<\1" \ + "\302\302\302\203\377\377\377\5\376\376\376\377\377\377\376\376\376\377" \ + "\377\377\376\376\376\274\377\377\377\1\316\316\316\205::<\1kkm\217\377" \ + "\377\377\1\376\376\376\206\377\377\377\3\332\332\334FFH;;=\205::<\1\265" \ + "\265\265\202\377\377\377\1\376\376\376\224\377\377\377\1\376\376\376" \ + "\202\377\377\377\1\205\205\207\202::<\1;;=\202::<\2GGI\363\363\363\202" \ + "\377\377\377\1\376\376\376\205\377\377\377\1\363\363\363\202::<\1;;=" \ + "\202::<\2""99;\234\234\234\203\377\377\377\1\376\376\376\226\377\377" \ + "\377\1\234\234\236\205::<\1\234\234\234\234\377\377\377\1\376\376\376" \ + "\210\377\377\377\3\222\222\222::<99;\202;;=\5""99;GGI\376\376\376\377" \ + "\377\377\376\376\376\211\377\377\377\1\234\234\234\205::<\1\234\234\236" \ + "\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305" \ + "@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p" \ + "\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306>\10" \ + "\213\307A\214\306>\331\356\303\232\315W\215\305>\215\306A\214\305B\214" \ + "\306>\202\214\305@\7\213\310=\214\306>\215\304B\215\306A\211\306;\213" \ + "\310\77\214\305@\202\215\307\77\2\257\326{\376\377\373\202\377\377\377" \ + "\1\377\377\375\206\377\377\377\213\214\306>\3\215\305>\214\306>\305\342" \ + "\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \ + ">\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215" \ + "\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\221\377\377" \ + "\377\6\377\377\373\377\377\375\377\377\377\376\376\377\377\376\377\373" \ + "\377\374\202\377\376\377\4\336\362\315\220\303@\213\310=\215\307\77\202" \ + "\212\306@\1\215\305@\202\214\306>\7\213\305=\214\306>\213\305=\214\305" \ + "@\213\310\77\212\306@\213\307A\210\214\306>\10\215\307\77\252\324p\377" \ + "\377\375\376\377\377\377\377\375\377\377\377\377\376\377\377\377\375" \ + "\220\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\265\265\265\204::<\5;;=::<\363\363\363\377\377\377\376\376" \ + "\376\302\377\377\377\1\316\316\316\205::<\1kkm\225\377\377\377\2\317" \ + "\317\317FFH\206::<\1SSU\204\377\377\377\1\376\376\376\225\377\377\377" \ + "\2\346\346\346;;=\203::<\3;;=::<\234\234\236\202\377\377\377\1\376\376" \ + "\376\207\377\377\377\2\204\204\206;;=\204::<\2FFF\362\362\362\231\377" \ + "\377\377\1\234\234\236\205::<\1\234\234\234\245\377\377\377\1\301\301" \ + "\301\202::<\6;;=::<;;=::<\347\347\347\376\376\376\212\377\377\377\1\234" \ + "\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214" \ + "\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377" \ + "\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306" \ + ">\1\214\305@\210\214\306>\27\214\305@\215\305<\342\362\315\353\365\334" \ + "\223\312K\215\305<\212\306@\215\305<\212\307>\215\306A\214\306>\212\307" \ + ">\215\307\77\215\304B\215\307\77\215\305@\214\306>\215\305>\214\305@" \ + "\215\305<\315\345\253\377\377\375\376\377\377\207\377\377\377\213\214" \ + "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \ + "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \ + "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \ + "\305@\214\306>\214\305@\221\377\377\377\14\376\377\377\376\376\377\377" \ + "\377\377\377\377\373\376\377\375\377\376\377\376\377\377\377\377\377" \ + "\377\376\375\276\340\224\214\306<\215\305@\202\214\306>\12\215\305>\214" \ + "\305@\215\305@\214\305@\213\310\77\214\306>\216\306\77\211\305\77\215" \ + "\307=\214\305@\210\214\306>\4\223\312K\360\367\347\377\377\377\377\377" \ + "\375\232\377\377\377\2\376\376\376\234\234\236\204::<\2;;=___\234\377" \ + "\377\377\1\376\376\376\203\377\377\377\1\376\376\376\244\377\377\377" \ + "\1\316\316\316\205::<\1kkm\202\377\377\377\1\376\376\376\216\377\377" \ + "\377\4\376\376\376\377\377\377\347\347\347\204\204\204\203::<\6;;=::" \ + "<;;=::<;;=\301\301\303\226\377\377\377\1\376\376\376\203\377\377\377" \ + "\1\203\203\205\202;;=\5::<;;=::<GGG\363\363\363\206\377\377\377\1\376" \ + "\376\376\203\377\377\377\3\347\347\34799;;;=\202::<\202;;=\1\234\234" \ + "\236\231\377\377\377\1\234\234\236\205::<\1\234\234\234\245\377\377\377" \ + "\1\363\363\363\202::<\1""99;\203::<\1\316\316\316\213\377\377\377\1\234" \ + "\234\234\204::<\2;;=kkm\203\234\234\236\2\235\235\237\234\234\234\220" \ + "\234\234\236\204\234\234\234\4\235\235\235\234\234\234\234\234\236\346" \ + "\346\350\231\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4" \ + "\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250" \ + "\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306" \ + ">\40\213\307A\215\305>\341\360\317\377\375\376\324\353\267\215\304B\214" \ + "\306>\215\307=\214\305@\212\307>\212\307<\215\305<\215\306A\214\306>" \ + "\214\306<\212\306@\214\305@\215\307\77\216\306=\212\306B\214\306>\352" \ + "\364\333\377\376\377\377\377\377\377\376\377\377\377\377\377\377\375" \ + "\376\377\373\375\376\377\377\376\377\214\306>\215\307\77\211\214\306" \ + ">\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214\306" \ + ">\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232\377" \ + "\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305" \ + "@\214\306>\214\305@\232\377\377\377\7\374\377\375\242\321a\216\306A\212" \ + "\307>\214\306>\215\307\77\212\307<\210\214\306>\16\215\307\77\214\307" \ + ";\213\304\77\216\306A\214\305B\215\307\77\215\305>\212\307>\320\345\254" \ + "\374\377\377\377\376\377\377\377\375\377\376\377\375\377\372\223\377" \ + "\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377\377\377kkm\203" \ + "::<\3<<>::<\221\221\221\305\377\377\377\1\316\316\316\204::<\2;;=jjl" \ + "\217\377\377\377\16\316\316\316\300\300\300\234\234\234__a::<;;=::<;" \ + ";=::<99;;;=::<;;=\204\204\206\232\377\377\377\1\362\362\362\202;;=\202" \ + "::<\3""99;::<\235\235\235\212\377\377\377\12\376\376\376\377\377\377" \ + "\205\205\20799;;;=::<;;=::<GGI\376\376\376\230\377\377\377\1\234\234" \ + "\236\205::<\1\234\234\234\246\377\377\377\10EEG::<;;=::<99;;;=\234\234" \ + "\234\377\377\377\202\376\376\376\202\377\377\377\1\376\376\376\205\377" \ + "\377\377\1\234\234\234\205::<\2;;=99;\202;;=\2""99;;;=\221::<\1""99;" \ + "\203::<\3;;=::<\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305" \ + "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \ + "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \ + "\214\305@\210\214\306>\202\214\306<\32\342\361\322\377\377\377\377\377" \ + "\375\266\334\205\212\306B\215\307\77\212\306@\220\306=\214\306>\215\307" \ + "\77\214\305B\213\305=\216\306\77\215\307\77\215\305<\212\306B\215\306" \ + "A\215\305@\216\306=\232\315V\371\373\360\377\377\375\377\377\377\375" \ + "\376\377\377\375\377\376\376\377\202\377\377\377\2\214\305@\212\307>" \ + "\211\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324" \ + "p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \ + "@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>" \ + "\3\214\305@\214\306>\214\305@\233\377\377\377\5\347\365\334\211\306=" \ + "\215\305>\216\306=\214\305@\211\214\306>\2\215\304B\212\307>\202\214" \ + "\306>\14\215\306A\214\306<\215\305@\252\324p\374\377\377\377\377\377" \ + "\377\375\376\377\376\377\376\376\377\377\377\375\377\377\377\377\375" \ + "\377\222\377\377\377\1\376\376\376\203\377\377\377\4\376\376\376lln:" \ + ":<;;=\203::<\2\235\235\235\376\376\376\304\377\377\377\1\316\316\316" \ + "\205::<\202;;=\2::<;;=\202::<\1;;=\211::<\202;;=\204::<\1""99;\202::" \ + "<\5;;=::<;;=__a\376\376\376\224\377\377\377\1\376\376\376\205\377\377" \ + "\377\1\235\235\235\206::<\3\346\346\346\377\377\377\376\376\376\207\377" \ + "\377\377\5\376\376\376\377\377\377\376\376\376\346\346\350;;=\203::<" \ + "\3;;=::<\265\265\265\230\377\377\377\1\234\234\236\205::<\1\234\234\234" \ + "\246\377\377\377\1lln\202::<\4""99;;;=99;\234\234\234\213\377\377\377" \ + "\1\234\234\234\203::<\7;;=::<;;=::<;;=::<;;=\222::<\7;;=99;;;=::<;;=" \ + "::<\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305@\207\214" \ + "\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306" \ + ">\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210" \ + "\214\306>\13\216\306A\213\310\77\343\361\320\377\377\375\375\377\376" \ + "\371\374\361\242\320c\213\310\77\216\306\77\214\306>\215\306A\202\214" \ + "\305@\2\216\306A\213\305=\204\214\306>\11\213\307A\216\306A\212\307>" \ + "\260\331y\377\376\377\376\377\375\377\377\373\376\377\377\377\377\377" \ + "\202\377\376\377\2\212\311=\215\306A\211\214\306>\3\215\305>\214\306" \ + ">\305\342\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207" \ + "\214\306>\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214" \ + "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\231" \ + "\377\377\377\6\377\376\377\377\377\373\377\376\377\305\342\240\212\310" \ + "\77\214\304=\202\215\305@\210\214\306>\4\215\305>\213\305=\212\306@\215" \ + "\306A\202\214\306>\10\222\312M\370\373\362\377\376\377\377\375\376\377" \ + "\376\377\377\377\377\376\377\375\377\377\377\202\377\376\377\221\377" \ + "\377\377\1\376\376\376\205\377\377\377\2::<;;=\202::<\202;;=\3\300\300" \ + "\300\377\377\377\376\376\376\235\377\377\377\1\376\376\376\245\377\377" \ + "\377\1\316\316\316\207::<\5;;=::<;;=::<;;=\210::<\202;;=\2""99;;;=\202" \ + "::<\3;;=::<;;=\202::<\3;;=xxz\363\363\363\225\377\377\377\3\376\376\376" \ + "\377\377\377\376\376\376\202\377\377\377\3\363\363\363FFH::<\202;;=\202" \ + "::<\1\204\204\206\205\377\377\377\1\376\376\376\205\377\377\377\1\376" \ + "\376\376\202\377\377\377\1kkm\202::<\1;;=\202::<\1SSU\230\377\377\377" \ + "\1\234\234\236\205::<\1\234\234\234\244\377\377\377\3\376\376\376\377" \ + "\377\377xxz\202::<\1;;=\202::<\3xxx\377\377\377\376\376\376\211\377\377" \ + "\377\1\234\234\234\203::<\1;;=\202::<\1;;=\224::<\5;;=99;;;=::<;;=\202" \ + "::<\1\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305@\207\214" \ + "\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306" \ + ">\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210" \ + "\214\306>\3\214\305@\214\306<\343\361\316\202\377\377\377\26\377\376" \ + "\374\353\365\335\223\312K\211\305\77\215\307=\215\306C\211\306;\214\306" \ + ">\215\305@\215\307\77\214\305@\213\307A\214\306>\212\307<\216\306\77" \ + "\212\306B\215\305>\212\306@\304\341\236\377\376\377\375\377\376\377\377" \ + "\375\203\377\377\377\2\212\306@\214\306<\211\214\306>\3\215\305>\214" \ + "\306>\305\342\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305" \ + "@\207\214\306>\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324" \ + "p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \ + "@\231\377\377\377\2\377\377\373\376\377\377\202\377\377\377\4\241\321" \ + "c\215\306A\215\305>\213\310\77\210\214\306>\20\215\305@\215\307=\213" \ + "\310\77\214\304;\216\306\77\213\310\77\333\355\303\377\375\376\377\377" \ + "\375\377\376\377\377\377\377\375\377\374\376\377\377\377\377\377\377" \ + "\377\375\376\376\376\222\377\377\377\1\376\376\376\204\377\377\377\206" \ + "::<\2\316\316\316\376\376\376\234\377\377\377\1\376\376\376\247\377\377" \ + "\377\1\316\316\316\204::<\1;;=\205::<\1;;=\212::<\4""99;;;=::<;;=\203" \ + "::<\1;;=\202::<\1\233\233\233\234\377\377\377\3\235\235\23799;;;=\203" \ + "::<\2;;=\346\346\346\203\377\377\377\1\376\376\376\204\377\377\377\3" \ + "\376\376\376\377\377\377\376\376\376\203\377\377\377\4\316\316\320;;" \ + "=::<;;=\202::<\2;;=\264\264\264\227\377\377\377\1\234\234\236\205::<" \ + "\1\234\234\234\246\377\377\377\2\234\234\236;;=\203::<\2;;=kkk\213\377" \ + "\377\377\1\234\234\234\204::<\3;;=::<;;=\225::<\2;;=99;\202::<\3;;=:" \ + "::\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305@\207\214\306" \ + ">\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>" \ + "\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210" \ + "\214\306>\14\215\307\77\215\305@\340\361\315\376\376\376\377\376\377" \ + "\377\377\375\377\377\377\323\353\267\212\307>\215\305@\214\305@\214\311" \ + "@\202\214\306>\22\212\307>\215\305@\214\306>\212\306@\214\305@\215\305" \ + ">\215\307=\214\306>\214\304=\215\307\77\341\362\316\377\376\377\377\377" \ + "\377\376\376\376\377\377\375\375\376\377\217\307@\212\306@\211\214\306" \ + ">\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214\306" \ + ">\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232\377" \ + "\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305" \ + "@\214\306>\214\305@\232\377\377\377\7\377\376\377\376\377\377\377\377" \ + "\377\352\364\331\212\307<\215\307=\212\307>\211\214\306>\13\212\306@" \ + "\214\306<\216\306A\214\305@\252\322q\376\376\377\376\377\373\377\376" \ + "\377\376\376\377\377\377\375\376\377\377\203\377\377\377\1\376\377\375" \ + "\227\377\377\377\202::<\202;;=\3::<;;=\316\316\316\233\377\377\377\1" \ + "\375\375\375\251\377\377\377\1\316\316\316\211::<\1;;=\213::<\3;;=::" \ + "<;;=\204::<\3""99;\205\205\207\346\346\346\233\377\377\377\4\376\376" \ + "\376\364\364\364FFH;;=\202::<\202;;=\1\204\204\204\215\377\377\377\1" \ + "\376\376\376\202\377\377\377\7kkm::<99;::<;;=99;TTV\227\377\377\377\1" \ + "\234\234\236\205::<\1\234\234\234\246\377\377\377\1\234\234\236\202:" \ + ":<\202;;=\2::<kkk\202\377\377\377\3\376\376\376\377\377\377\376\376\376" \ + "\206\377\377\377\1\234\234\234\203::<\1;;=\202::<\2;;=::<\202;;=\223" \ + "::<\2""99;;;=\202::<\2;;;\316\316\316\231\377\377\377\3\214\305@\214" \ + "\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251" \ + "\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202" \ + "\214\306>\1\214\305@\210\214\306>\202\214\305@\15\341\362\316\377\377" \ + "\375\376\377\375\377\377\377\373\377\374\377\376\377\271\332\211\212" \ + "\307>\212\307<\214\305B\214\305@\216\306\77\212\307>\202\215\307\77\11" \ + "\214\305B\215\306A\212\311=\214\303A\214\306>\215\306A\212\307>\225\311" \ + "K\371\372\362\202\377\377\375\202\377\377\377\2\214\305@\215\306A\211" \ + "\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p" \ + "\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \ + "@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>" \ + "\3\214\305@\214\306>\214\305@\231\377\377\377\10\376\377\377\377\376" \ + "\377\377\377\375\377\375\376\331\356\303\214\306>\214\305B\215\307\77" \ + "\210\214\306>\12\215\305>\212\306B\215\304B\214\306>\215\307=\224\310" \ + "J\364\370\351\376\376\374\375\377\372\377\377\375\203\377\377\377\3\377" \ + "\376\377\377\377\377\376\377\375\221\377\377\377\3\376\376\376\377\377" \ + "\377\376\376\376\203\377\377\377\7::<;;=99;::<;;=::<\315\315\315\232" \ + "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\246\377\377" \ + "\377\1\316\316\316\204::<\1;;=\202::<\1;;=\203::<\1;;=\210::<\1;;=\202" \ + "::<\1;;=\202::<\4``b\233\233\235\347\347\351\376\376\376\235\377\377" \ + "\377\2\265\265\265;;=\202::<\1;;=\202::<\1\332\332\332\216\377\377\377" \ + "\3\376\376\376\377\377\377\302\302\302\206::<\1\315\315\315\226\377\377" \ + "\377\1\234\234\236\205::<\1\234\234\234\245\377\377\377\2\376\376\376" \ + "\235\235\237\205::<\1jjj\203\377\377\377\3\376\376\376\377\377\377\376" \ + "\376\376\205\377\377\377\1\234\234\234\204::<\2;;=kkm\202\234\234\236" \ + "\1\233\233\235\223\234\234\234\202\235\235\235\1\233\233\233\203\234" \ + "\234\234\1\346\346\346\231\377\377\377\3\214\305@\214\306>\214\305@\207" \ + "\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214" \ + "\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305" \ + "@\210\214\306>\17\212\307>\216\306A\342\360\315\376\377\377\376\376\374" \ + "\375\377\376\377\376\377\377\376\374\377\377\375\242\320d\215\307=\214" \ + "\306>\214\305@\215\305@\212\306@\202\214\305@\17\215\305@\212\307>\215" \ + "\307\77\214\306<\215\306A\213\304\77\215\306A\215\307\77\252\324n\377" \ + "\377\377\375\377\376\377\376\377\377\377\375\212\307<\215\305@\211\214" \ + "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \ + "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \ + "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \ + "\305@\214\306>\214\305@\232\377\377\377\6\376\377\375\377\375\377\367" \ + "\375\363\223\312H\216\306\77\215\305>\212\214\306>\2\215\305@\214\306" \ + ">\202\212\307>\3\214\305@\247\324o\377\376\377\202\377\377\377\2\377" \ + "\376\377\377\377\375\233\377\377\377\2::<;;=\204::<\2\316\316\316\376" \ + "\376\376\236\377\377\377\3\316\316\316;;;:::\230::<\213\377\377\377\1" \ + "\316\316\316\224::<\6kkmlln\205\205\207\234\234\236\301\301\303\363\363" \ + "\363\202\377\377\377\1\376\376\376\202\377\377\377\3\376\376\376\377" \ + "\377\377\376\376\376\231\377\377\377\1SSS\204::<\2;;=lln\213\377\377" \ + "\377\1\376\376\376\205\377\377\377\2\376\376\376TTV\205::<\1lll\226\377" \ + "\377\377\1\234\234\236\205::<\1\234\234\234\246\377\377\377\2\233\233" \ + "\235;;=\204::<\2kkk\376\376\376\203\377\377\377\1\376\376\376\206\377" \ + "\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305" \ + "@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324" \ + "p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320" \ + "\202\214\306>\1\214\305@\210\214\306>\3\212\307>\215\305>\342\362\315" \ + "\202\377\377\377\22\377\376\377\376\377\377\377\377\375\376\377\377\363" \ + "\367\346\225\311K\211\307@\216\306\77\212\307>\215\305@\214\306<\212" \ + "\307>\214\305@\214\306>\212\306@\215\306C\214\304\77\215\307\77\202\214" \ + "\306>\7\212\306@\307\341\240\377\376\377\376\377\372\377\377\377\212" \ + "\307>\215\305>\211\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \ + "\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214" \ + "\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@" \ + "\207\214\306>\3\214\305@\214\306>\214\305@\231\377\377\377\4\377\376" \ + "\377\376\377\375\376\377\377\257\330z\202\214\305@\1\215\307\77\211\214" \ + "\306>\14\212\307>\215\307\77\214\305@\215\305@\212\307>\215\307=\214" \ + "\305B\313\347\252\377\377\377\377\375\377\377\376\377\376\376\376\202" \ + "\376\377\375\231\377\377\377\4GGI;;=::<;;=\202::<\1\233\233\235\237\377" \ + "\377\377\3\316\316\316::<;;=\230::<\213\377\377\377\1\316\316\316\205" \ + "::<\1kkm\202\377\377\377\2\376\376\376\250\250\250\206::<\2FFH\346\346" \ + "\346\210\377\377\377\1\376\376\376\237\377\377\377\1\264\264\266\203" \ + ";;=\4::<;;=;;;\316\316\316\222\377\377\377\1\265\265\265\204::<\3;;=" \ + "::<\316\316\316\203\377\377\377\1\376\376\376\221\377\377\377\1\234\234" \ + "\236\205::<\1\234\234\234\245\377\377\377\2\376\376\376\235\235\237\205" \ + "::<\1lll\213\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377" \ + "\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214" \ + "\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \ + "\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361" \ + "\316\205\377\377\377\10\376\377\375\377\377\377\333\355\303\215\305@" \ + "\214\306>\214\306<\214\305@\215\305>\202\214\305@\207\214\306>\6\212" \ + "\306@\214\307;\330\355\304\377\376\377\377\377\377\215\305>\212\214\306" \ + ">\3\215\305>\214\306>\305\342\240\215\377\377\377\17\251\323q\214\306" \ + ">\215\307\77\214\305B\215\307\77\213\305=\215\307\77\214\305@\212\307" \ + ">\215\305@\213\310\77\214\305@\215\305<\214\306>\376\377\377\230\377" \ + "\377\377\6\376\377\377\253\323p\215\305@\213\307A\214\306<\212\306B\202" \ + "\214\306>\4\214\305@\214\306>\212\307>\214\305@\202\214\306>\2\214\305" \ + "@\376\377\375\220\377\377\377\1\377\377\375\202\377\377\377\16\376\377" \ + "\375\377\376\377\377\375\376\374\377\377\377\377\375\376\377\375\377" \ + "\377\377\336\355\304\214\306>\215\306A\214\306>\215\306A\212\306@\216" \ + "\306A\202\214\305@\4\215\307\77\214\306>\215\307\77\214\306>\202\214" \ + "\305@\16\214\306>\215\307\77\214\306>\215\307\77\214\305@\214\305B\222" \ + "\313H\361\370\346\376\377\377\377\377\377\377\376\377\377\377\377\374" \ + "\377\377\377\376\377\230\377\377\377\1kkm\202::<\1""99;\202::<\1\235" \ + "\235\237\233\377\377\377\1\376\376\376\203\377\377\377\1\316\316\316" \ + "\224::<\1;;=\205::<\213\377\377\377\1\316\316\316\205::<\1kkm\204\377" \ + "\377\377\3wwy::<;;=\202::<\4""99;;;=``b\363\363\363\206\377\377\377\1" \ + "\376\376\376\235\377\377\377\4\376\376\376\377\377\377\376\376\376TT" \ + "V\205::<\1lln\223\377\377\377\10\376\376\376SSU;;=::<;;=99;::<lll\205" \ + "\377\377\377\1\376\376\376\217\377\377\377\1\234\234\236\205::<\1\234" \ + "\234\234\246\377\377\377\1\204\204\206\202::<\1;;=\202::<\3xxx\377\377" \ + "\377\376\376\376\211\377\377\377\1\234\234\234\205::<\1\234\234\236\266" \ + "\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215" \ + "\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377" \ + "\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305" \ + "@\343\361\316\205\377\377\377\7\377\375\377\377\377\375\376\377\377\276" \ + "\337\220\213\310\77\213\304A\216\306=\207\214\306>\3\215\307\77\214\306" \ + ">\212\307>\202\215\305>\5\223\312J\361\371\344\377\375\377\212\307<\214" \ + "\305@\211\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\14" \ + "\376\376\374\252\324n\214\306>\213\305=\215\307\77\214\305@\215\306A" \ + "\214\306>\215\307\77\213\310\77\215\305@\212\307>\202\214\306>\1\214" \ + "\305@\232\377\377\377\3\247\324m\215\305>\214\305@\202\214\306>\1\215" \ + "\307=\202\214\305@\6\214\306<\215\307=\214\305B\215\307\77\214\306>\214" \ + "\305@\224\377\377\377\15\377\377\375\376\376\376\377\377\377\377\376" \ + "\377\376\377\375\377\377\375\372\373\366\222\312M\216\306A\215\305<\214" \ + "\306>\212\307>\215\305<\202\214\306>\2\215\307\77\213\305=\204\214\306" \ + ">\1\214\305@\203\214\306>\14\215\307\77\214\305@\213\304\77\214\305B" \ + "\253\324n\376\376\377\376\377\377\377\376\377\377\377\377\376\377\375" \ + "\377\377\375\376\377\375\227\377\377\377\3lln::<;;=\203::<\2kkm\376\376" \ + "\376\236\377\377\377\2\316\316\316;;=\226::<\3;;=::<kkm\213\377\377\377" \ + "\1\316\316\316\204::<\2;;=kkm\204\377\377\377\3\363\363\363__a;;=\203" \ + "::<\4;;=99;\205\205\207\376\376\376\202\377\377\377\1\376\376\376\203" \ + "\377\377\377\1\376\376\376\236\377\377\377\1\301\301\301\204::<\4;;=" \ + "::<wwy\235\235\237\223\234\234\236\1kkm\204::<\5;;=99;\345\345\345\377" \ + "\377\377\376\376\376\222\377\377\377\1\234\234\236\205::<\1\234\234\234" \ + "\246\377\377\377\1kkm\204::<\2;;=\234\234\234\213\377\377\377\1\234\234" \ + "\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305" \ + "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \ + "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \ + "\214\305@\211\214\306>\2\214\305@\343\361\316\205\377\377\377\2\377\377" \ + "\375\377\375\377\202\377\377\377\1\242\322b\202\214\305@\2\214\305B\215" \ + "\307\77\205\214\306>\12\215\307\77\214\306>\215\306A\214\306>\212\306" \ + "@\215\307=\241\321c\377\377\377\215\304B\212\307>\211\214\306>\3\215" \ + "\305>\214\306>\305\342\240\214\377\377\377\5\376\377\375\251\323o\215" \ + "\307\77\214\306>\215\307\77\202\214\305@\2\214\306>\215\307\77\202\214" \ + "\306>\5\213\310\77\215\305>\214\305@\214\306>\377\376\377\230\377\377" \ + "\377\12\377\376\377\247\326p\213\304\77\215\307\77\214\305B\214\306<" \ + "\214\306>\215\307\77\214\305@\214\306>\202\215\307\77\3\214\306>\215" \ + "\306A\216\306\77\223\377\377\377\5\376\377\372\377\377\375\376\376\376" \ + "\377\377\377\377\377\375\202\377\376\377\4\250\325p\212\307<\214\305" \ + "@\215\307\77\202\214\305@\3\214\307;\215\307=\214\306>\202\214\305@\202" \ + "\214\306>\1\215\307\77\207\214\306>\202\214\305@\5\212\307>\307\341\240" \ + "\376\376\374\377\377\377\377\376\377\202\377\377\377\1\376\376\374\227" \ + "\377\377\377\7\234\234\236;;=99;<<>99;::<;;=\237\377\377\377\1\316\316" \ + "\316\223::<\7;;=99;;;=99;::<;;=kkm\213\377\377\377\1\316\316\316\205" \ + "::<\2mmo\376\376\377\204\377\377\377\12\332\332\332FFH;;=::<;;=99;<<" \ + ">::<\266\266\270\376\376\376\203\377\377\377\1\376\376\376\202\377\377" \ + "\377\1\376\376\376\230\377\377\377\3\376\376\376\377\377\377\376\376" \ + "\376\202\377\377\377\1kkm\205::<\202;;=\224::<\10;;=::<;;=::<;;=88:;" \ + ";=\205\205\205\224\377\377\377\1\234\234\236\205::<\1\234\234\234\246" \ + "\377\377\377\3SSU;;=::<\203;;=\1\234\234\234\206\377\377\377\1\376\376" \ + "\376\204\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377" \ + "\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306" \ + ">\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1" \ + "\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361" \ + "\316\205\377\377\377\10\376\376\374\376\377\375\377\375\377\377\377\377" \ + "\367\372\357\224\313L\214\305B\215\305<\203\214\306>\202\215\307\77\204" \ + "\214\306>\6\215\306A\213\307A\214\306>\212\306@\277\337\223\215\305>" \ + "\212\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\2\376\377" \ + "\377\251\322r\202\215\307\77\1\214\305B\202\214\306>\202\215\307\77\7" \ + "\214\306>\215\307\77\214\306>\214\304\77\212\306@\215\307\77\377\376" \ + "\377\230\377\377\377\7\377\377\375\215\305@\214\306>\214\305@\214\306" \ + ">\216\306\77\214\306<\203\214\305@\6\215\306C\215\307=\214\305@\215\306" \ + "A\233\314V\377\377\375\220\377\377\377\5\376\376\376\377\377\377\377" \ + "\376\377\377\375\377\377\377\375\202\376\377\377\21\377\376\377\314\346" \ + "\251\212\306B\215\307=\212\307>\216\306\77\215\306C\212\307>\215\306" \ + "C\214\305@\215\307\77\213\304\77\215\306A\214\306>\214\305@\215\307\77" \ + "\215\306A\203\214\306>\1\215\307\77\202\214\306>\202\215\307\77\10\214" \ + "\306>\214\305@\350\364\334\377\377\375\377\376\377\377\377\377\376\376" \ + "\376\377\376\377\222\377\377\377\1\376\376\376\204\377\377\377\1\301" \ + "\301\301\202::<\2""99;;;=\202::<\1\316\316\316\233\377\377\377\1\376" \ + "\376\376\202\377\377\377\2\316\316\316;;;\222::<\7""99;;;=::<;;=::<9" \ + "9;\204\204\206\213\377\377\377\1\316\316\316\205::<\1jjl\202\377\377" \ + "\377\202\376\376\376\202\377\377\377\1\265\265\267\202::<\202;;=\202" \ + "::<\2FFH\332\332\332\205\377\377\377\1\376\376\376\234\377\377\377\2" \ + "\376\376\376\317\317\317\202::<\1;;=\204::<\3;;=::<;;=\222::<\2""99;" \ + ";;=\202::<\1;;=\203::<\3\346\346\346\377\377\377\376\376\376\221\377" \ + "\377\377\1\234\234\236\205::<\1\234\234\234\246\377\377\377\1;;=\203" \ + "::<\4;;=::<\316\316\316\376\376\376\203\377\377\377\1\376\376\376\206" \ + "\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214" \ + "\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252" \ + "\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361" \ + "\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316\205" \ + "\377\377\377\203\376\377\377\202\377\376\377\2\341\361\315\214\305@\203" \ + "\215\307\77\202\214\306>\1\215\307\77\203\214\306>\10\214\305@\215\307" \ + "\77\214\306>\212\307>\216\306A\213\305;\214\305@\215\305<\211\214\306" \ + ">\3\215\305>\214\306>\305\342\240\214\377\377\377\2\376\377\377\252\324" \ + "p\202\214\306>\3\214\305B\214\306<\215\307\77\203\214\306>\6\214\306" \ + "<\214\307;\217\307@\212\307>\214\305@\376\377\377\231\377\377\377\10" \ + "\215\307=\214\305B\213\304A\216\310@\214\304\77\215\307=\214\305@\215" \ + "\307\77\203\214\306>\3\215\307\77\214\306>\247\324o\222\377\377\377\3" \ + "\377\377\375\377\377\377\377\375\376\203\377\377\377\20\360\371\346\223" \ + "\312K\216\306\77\213\304A\215\306A\213\305=\215\305@\212\307>\215\305" \ + "<\214\305B\214\305@\214\306>\214\306<\214\306>\215\307\77\213\305=\204" \ + "\214\306>\202\215\307\77\203\214\306>\10\215\306A\212\307<\243\321d\377" \ + "\377\373\375\377\376\377\376\377\377\377\377\376\376\374\223\377\377" \ + "\377\5\375\375\375\377\377\377\376\376\376\377\377\377\346\346\346\202" \ + "::<\1;;=\203::<\1\221\221\221\235\377\377\377\3\376\376\376\377\377\377" \ + "\376\376\376\222\377\377\377\1__a\204::<\2;;=\234\234\234\213\377\377" \ + "\377\1\316\316\316\205::<\3jjl\377\377\377\376\376\376\205\377\377\377" \ + "\2\204\204\206;;=\204::<\3;;=RRT\363\363\363\237\377\377\377\1\376\376" \ + "\376\202\377\377\377\2jjl;;=\206::<\4;;=::<99;;;=\223::<\1;;=\205::<" \ + "\1\204\204\206\203\377\377\377\1\376\376\376\217\377\377\377\1\234\234" \ + "\236\205::<\1\234\234\234\245\377\377\377\3\315\315\315;;=99;\202::<" \ + "\5""99;;;=\346\346\346\377\377\377\376\376\376\211\377\377\377\1\234" \ + "\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214" \ + "\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377" \ + "\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306" \ + ">\1\214\305@\211\214\306>\2\214\305@\343\361\316\207\377\377\377\202" \ + "\377\377\375\4\376\377\377\377\377\375\303\342\237\212\306@\202\214\305" \ + "@\206\214\306>\7\216\306\77\213\305;\214\305@\216\306A\214\306>\215\307" \ + "\77\213\307A\212\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \ + "\377\17\252\323k\215\306A\214\306>\215\307\77\214\306>\215\307\77\214" \ + "\305@\214\306>\213\304A\215\306C\214\305@\213\304A\213\310=\214\306<" \ + "\342\357\321\230\377\377\377\6\360\371\346\214\305B\212\307<\215\307" \ + "=\213\305=\215\307\77\202\214\305@\7\215\306A\214\306>\214\306<\214\305" \ + "@\214\306>\214\305@\252\324p\222\377\377\377\11\377\376\377\376\377\377" \ + "\377\377\377\377\377\375\376\376\374\377\377\377\253\323p\215\307\77" \ + "\211\306;\202\215\306A\6\214\306>\214\306<\215\305>\216\305C\215\307" \ + "\77\213\304\77\202\215\307\77\2\215\307=\213\305;\202\215\307\77\2\214" \ + "\306>\215\307\77\205\214\306>\5\215\307\77\212\306@\214\306>\215\307" \ + "\77\304\341\236\202\377\377\377\2\376\376\377\374\377\377\230\377\377" \ + "\377\7SSU;;=99;::<;;=::<FFH\232\377\377\377\1\376\376\376\205\377\377" \ + "\377\1\376\376\376\220\377\377\377\2\376\376\376;;=\202::<\1;;=\202:" \ + ":<\1\316\316\316\213\377\377\377\1\316\316\316\205::<\1kkm\210\377\377" \ + "\377\2__a;;=\204::<\2;;=xxz\202\377\377\377\1\376\376\376\233\377\377" \ + "\377\1\376\376\376\202\377\377\377\2\315\315\315;;=\206::<\2;;=99;\203" \ + ";;=\223::<\1;;=\205::<\6FFH\363\363\363\377\377\377\376\376\376\377\377" \ + "\377\376\376\376\216\377\377\377\1\234\234\236\205::<\1\234\234\234\244" \ + "\377\377\377\4\376\376\376\223\223\22399;;;=\202::<\4;;=EEG\377\377\377" \ + "\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \ + "\376\204\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377" \ + "\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306" \ + ">\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1" \ + "\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361" \ + "\316\206\377\377\377\13\377\376\377\377\377\377\376\377\375\377\377\377" \ + "\377\376\377\376\377\377\253\324l\214\305B\213\304\77\214\305@\215\307" \ + "\77\203\214\306>\11\214\305@\214\306<\216\306=\214\306>\212\306@\215" \ + "\306C\214\304;\212\307>\214\305@\211\214\306>\3\215\305>\214\306>\305" \ + "\342\240\215\377\377\377\1\261\330\177\202\214\306>\2\214\306<\215\306" \ + "A\203\214\306>\7\215\307\77\214\306>\214\306<\215\307=\214\306>\215\306" \ + "C\323\353\267\230\377\377\377\4\340\361\315\215\305@\215\306A\214\305" \ + "@\202\214\306>\2\213\305=\215\306A\202\214\305@\5\214\306>\215\307\77" \ + "\214\306>\214\305@\260\330x\221\377\377\377\3\376\376\376\377\377\373" \ + "\375\377\376\202\377\377\377\25\376\377\377\314\345\253\214\305@\213" \ + "\304\77\216\306\77\212\307>\215\305@\214\306>\214\305@\215\305>\214\305" \ + "@\214\306>\214\306<\214\305@\215\306A\214\305@\215\306C\214\306>\214" \ + "\305@\214\306>\215\307\77\207\214\306>\7\212\306@\220\306=\215\306C\350" \ + "\364\336\376\377\373\377\377\375\376\377\377\230\377\377\377\1\221\221" \ + "\223\203::<\1;;=\202::<\1\265\265\265\230\377\377\377\1\376\376\376\227" \ + "\377\377\377\1\316\316\316\202::<\1;;=\203::<\1\363\363\363\213\377\377" \ + "\377\1\316\316\316\205::<\1kkm\204\377\377\377\1\376\376\376\203\377" \ + "\377\377\2\346\346\346FFH\206::<\2\234\234\236\376\376\376\237\377\377" \ + "\377\1\205\205\205\206::<\3;;=::<;;=\223::<\1;;=\203::<\202;;=\204::" \ + "<\2\234\234\234\376\376\376\221\377\377\377\1\234\234\236\205::<\1\234" \ + "\234\234\245\377\377\377\1RRR\204::<\2""99;yy{\203\377\377\377\1\376" \ + "\376\376\202\377\377\377\202\376\376\376\204\377\377\377\1\234\234\234" \ + "\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305@\207" \ + "\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214" \ + "\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305" \ + "@\211\214\306>\2\214\305@\343\361\316\205\377\377\377\30\377\377\375" \ + "\377\377\377\375\377\376\377\377\377\377\376\377\377\377\377\376\377" \ + "\377\371\372\365\222\313H\214\305B\214\305@\215\307\77\214\306>\215\307" \ + "\77\214\306>\214\305@\212\306B\214\305@\212\307>\216\306\77\212\307>" \ + "\215\307\77\214\306<\214\305@\211\214\306>\3\215\305>\214\306>\305\342" \ + "\240\214\377\377\377\20\377\376\377\301\345\237\215\305>\215\306A\213" \ + "\304\77\215\306C\214\306>\214\306<\216\306\77\214\306>\214\305B\215\307" \ + "\77\214\306>\215\307\77\214\305@\271\332\211\230\377\377\377\10\307\341" \ + "\240\215\305>\214\305@\214\306>\215\305<\212\307>\214\305B\214\306<\202" \ + "\214\306>\5\215\305<\214\305B\215\307\77\214\306>\303\344\235\222\377" \ + "\377\377\6\376\376\377\377\377\375\376\377\377\377\376\377\352\364\333" \ + "\215\305@\202\215\307\77\16\214\306>\215\307\77\214\306>\215\307\77\214" \ + "\306<\216\306A\213\310\77\214\305D\215\3108\214\305@\215\305>\223\312" \ + "K\236\323a\215\307\77\207\214\306>\202\214\305@\10\214\306>\215\307\77" \ + "\212\307>\212\307<\241\321c\377\376\377\377\375\376\377\375\377\230\377" \ + "\377\377\3\332\332\332:::;;=\204::<\1SSU\203\377\377\377\1\376\376\376" \ + "\247\377\377\377\1\376\376\376\204\377\377\377\1\221\221\221\202::<\1" \ + ";:\77\202::<\1RRT\214\377\377\377\1\316\316\316\205::<\1kkm\211\377\377" \ + "\377\2\316\316\316;;=\202::<\5;;=::<;;=::<\316\316\316\210\377\377\377" \ + "\1\376\376\376\215\377\377\377\1\376\376\376\207\377\377\377\2\346\346" \ + "\350::<\202;;=\202::<\2:::xxx\230\234\234\234\3\235\235\235\234\234\234" \ + "kkm\203::<\4;;=::<FFH\364\364\364\203\377\377\377\1\376\376\376\215\377" \ + "\377\377\1\234\234\236\205::<\1\234\234\234\241\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\332\332\334\206::<\1\250\250\252\214\377\377\377" \ + "\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306" \ + ">\214\305@\204\214\306>\2\213\307A\213\310\77\204\214\306>\1\252\324" \ + "p\232\377\377\377\1\377\377\375\216\377\377\377\215\214\306>\1\250\325" \ + "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>" \ + "\2\214\305@\343\361\316\215\377\377\377\10\352\363\336\214\306>\212\306" \ + "B\215\307\77\212\307<\215\305>\214\305@\215\307\77\221\214\306>\3\215" \ + "\305>\214\306>\305\342\240\214\377\377\377\30\377\376\377\313\347\254" \ + "\215\307\77\214\304=\215\307\77\212\306@\215\307\77\215\306A\214\305" \ + "@\214\306>\215\307\77\214\306>\215\307\77\214\305@\214\305B\222\313H" \ + "\377\376\377\377\375\376\377\376\377\377\377\377\377\376\377\377\377" \ + "\373\376\377\377\377\376\377\211\377\377\377\26\377\377\375\377\376\377" \ + "\377\377\377\376\377\377\377\377\375\376\377\375\377\377\377\241\323" \ + "b\215\304D\214\307;\215\307\77\214\305B\215\307\77\214\306<\215\306A" \ + "\212\307>\215\305@\214\306>\213\310=\215\305@\215\306A\323\352\264\221" \ + "\377\377\377\11\376\377\377\376\376\374\376\377\377\377\376\374\377\376" \ + "\377\242\320c\215\307\77\215\306A\214\306>\202\214\305@\203\214\306>" \ + "\25\214\305@\215\306A\214\305@\215\307\77\214\306>\215\307=\315\345\253" \ + "\361\370\346\215\307\77\214\306>\212\306@\216\306A\214\306>\215\305>" \ + "\215\305@\214\305@\212\307>\215\305@\212\306@\215\305<\215\305@\202\214" \ + "\306>\12\277\337\223\377\377\377\376\377\375\377\376\377\377\377\375" \ + "\376\377\377\377\377\377\376\376\376\377\377\377\377\377\375\222\377" \ + "\377\377\1___\202::<\202;;=\202::<\1\266\266\266\250\377\377\377\1\376" \ + "\376\376\202\377\377\377\1\376\376\376\203\377\377\377\1SSU\203::<\3" \ + ";;=::<\221\221\223\214\377\377\377\1\316\316\316\205::<\1kkm\210\377" \ + "\377\377\3\376\376\376\377\377\377\233\233\233\203::<\5;;=::<;;=FFH\364" \ + "\364\364\210\377\377\377\1\376\376\376\213\377\377\377\2\376\376\376" \ + "\377\377\377\202\376\376\376\205\377\377\377\1\204\204\206\202::<\1;" \ + ";=\202::<\3FFF\363\363\363\376\376\376\231\377\377\377\3\346\346\346" \ + "::<;;=\204::<\3\234\234\234\377\377\377\376\376\376\217\377\377\377\1" \ + "\234\234\236\205::<\1\234\234\234\234\377\377\377\1\376\376\376\207\377" \ + "\377\377\3\205\205\207::<;;=\204::<\1\346\346\350\214\377\377\377\1\234" \ + "\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214" \ + "\305@\205\214\306>\7\214\306<\214\306>\215\307\77\214\305@\214\306>\252" \ + "\324p\376\377\375\230\377\377\377\203\377\376\377\203\377\377\377\1\376" \ + "\376\377\211\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342" \ + "\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316" \ + "\215\377\377\377\2\376\377\375\313\347\254\203\214\306>\3\214\305@\216" \ + "\306\77\211\306=\221\214\306>\3\215\305>\214\306>\305\342\240\214\377" \ + "\377\377\11\375\376\377\343\361\316\215\305>\215\307\77\213\304A\215" \ + "\307\77\215\305>\214\306<\214\305@\203\214\306>\14\215\307\77\214\305" \ + "@\213\304\77\214\305B\322\353\264\377\377\377\377\377\375\377\377\377" \ + "\377\376\377\376\377\377\377\377\377\376\377\377\210\377\377\377\13\377" \ + "\377\375\377\377\377\376\377\375\377\376\377\376\376\374\377\377\375" \ + "\377\377\377\350\364\334\215\304D\215\305>\215\307\77\202\214\305@\202" \ + "\214\306>\10\214\305@\215\306A\214\306<\215\306C\214\304=\215\307=\212" \ + "\307<\351\366\332\222\377\377\377\14\377\377\375\377\377\377\377\377" \ + "\375\304\343\237\214\306>\212\307>\217\307@\214\305@\215\307\77\214\306" \ + ">\214\305@\215\306A\202\214\306>\5\214\306<\215\305>\211\307>\216\306" \ + "=\251\323o\202\376\377\377\31\304\341\241\212\306@\215\306A\212\307>" \ + "\215\307\77\214\306<\216\305C\212\307<\216\306A\214\306<\215\307\77\215" \ + "\305>\212\307>\216\306A\214\305@\216\306A\341\361\315\377\376\377\377" \ + "\377\375\376\377\377\377\376\377\376\376\376\377\377\377\377\376\377" \ + "\376\377\375\222\377\377\377\1\265\265\265\202;;=\204::<\2SSU\364\364" \ + "\364\203\377\377\377\1\376\376\376\245\377\377\377\1\376\376\376\203" \ + "\377\377\377\1\316\316\316\203::<\1;;=\202::<\1\302\302\302\214\377\377" \ + "\377\1\316\316\316\205::<\1kkm\213\377\377\377\1lln\204::<\3;;=::<__" \ + "a\202\377\377\377\1\376\376\376\206\377\377\377\1\376\376\376\213\377" \ + "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377" \ + "\3\346\346\346::<;;=\204::<\1\234\234\234\234\377\377\377\1\204\204\206" \ + "\202;;=\202::<\2;;=SSU\221\377\377\377\1\234\234\236\205::<\1\234\234" \ + "\234\235\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202" \ + "\377\377\377\2\346\346\346::<\202;;=\4""99;;;=::<kkm\215\377\377\377" \ + "\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306" \ + ">\214\305@\204\214\306>\10\214\305@\215\306A\215\305@\213\305=\214\306" \ + ">\215\307\77\252\324p\376\377\377\230\377\377\377\1\376\376\376\205\377" \ + "\377\377\2\376\377\377\376\377\375\210\377\377\377\215\214\306>\1\250" \ + "\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306" \ + ">\2\214\305@\343\361\316\215\377\377\377\10\377\377\375\377\375\376\262" \ + "\331|\214\305@\215\306A\214\306>\214\305B\215\307\77\221\214\306>\3\215" \ + "\305>\214\306>\305\342\240\214\377\377\377\10\376\377\375\377\377\377" \ + "\214\304\77\212\307>\216\306A\214\306>\215\305@\215\307\77\206\214\306" \ + ">\202\214\305@\3\233\316X\376\376\377\376\377\373\202\377\377\377\3\377" \ + "\375\376\377\377\375\377\376\377\210\377\377\377\12\377\376\377\376\377" \ + "\375\377\375\376\376\376\374\377\377\377\377\377\375\377\377\377\257" \ + "\330x\214\307;\215\307\77\202\214\305@\2\215\307\77\213\305=\202\214" \ + "\306>\1\215\305>\202\214\306>\5\216\306\77\215\306A\215\305@\376\377" \ + "\375\377\376\377\220\377\377\377\11\377\377\375\377\377\377\376\377\377" \ + "\350\364\334\212\307>\213\310\77\216\306\77\212\307>\214\305@\202\214" \ + "\306>%\215\306A\214\306>\213\305=\214\306>\215\307\77\215\305@\211\307" \ + ">\223\311M\363\367\350\376\377\375\377\377\377\377\377\375\242\320d\212" \ + "\307<\215\306A\214\305@\212\306@\215\306A\214\306>\212\307>\215\307\77" \ + "\217\304@\211\310<\215\305>\213\310\77\212\307>\214\306>\234\315W\367" \ + "\372\363\376\377\377\377\376\377\377\377\375\377\377\377\376\376\376" \ + "\377\377\375\377\377\377\376\377\375\222\377\377\377\1RRR\202::<\203" \ + ";;=\2::<\234\234\236\204\377\377\377\1\376\376\376\246\377\377\377\3" \ + "\376\376\376\377\377\377kkk\202::<\4;;=99;;;=FFH\215\377\377\377\1\316" \ + "\316\316\205::<\1kkm\211\377\377\377\5\376\376\376\377\377\377\363\363" \ + "\363SSU;;=\202::<\202;;=\2""99;\222\222\222\207\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\214\377\377\377\1\376\376\376\204\377\377" \ + "\377\3\204\204\204;;=99;\202;;=\3::<FFH\363\363\363\230\377\377\377\1" \ + "\376\376\376\202\377\377\377\2\376\376\376\317\317\317\203::<\4;;=::" \ + "<;;=\266\266\266\220\377\377\377\1\234\234\236\205::<\1\234\234\234\243" \ + "\377\377\377\2\204\204\204;;=\204::<\2""99;\264\264\264\215\377\377\377" \ + "\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306" \ + ">\214\305@\204\214\306>\2\214\305@\214\306>\203\215\306A\2\215\307\77" \ + "\251\323q\231\377\377\377\203\377\377\375\202\377\377\377\1\377\375\376" \ + "\202\377\376\377\210\377\377\377\215\214\306>\1\250\325p\216\377\377" \ + "\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343" \ + "\361\316\215\377\377\377\7\376\376\376\377\377\375\366\373\364\233\316" \ + "X\215\305@\215\307=\215\305>\222\214\306>\3\215\305>\214\306>\305\342" \ + "\240\216\377\377\377\6\243\322b\214\306>\215\305@\215\307\77\215\305" \ + "@\215\306A\203\214\306>\1\215\307\77\202\214\306>\202\215\307\77\2\214" \ + "\306>\315\346\254\202\377\377\377\4\377\376\375\376\377\375\376\376\377" \ + "\377\376\377\212\377\377\377\7\377\377\375\377\376\377\377\377\373\377" \ + "\377\375\327\356\304\214\306>\215\307\77\202\214\305@\203\214\306>\12" \ + "\215\307\77\214\306>\214\305@\216\306\77\214\306<\214\304\77\212\307" \ + ">\260\331{\376\377\375\377\376\377\220\377\377\377\13\376\377\377\377" \ + "\377\375\370\373\362\233\315Z\216\306A\214\305@\212\307>\215\306A\214" \ + "\306>\214\305@\215\306A\202\214\306>\6\215\307\77\214\305@\214\305B\214" \ + "\306>\215\307=\313\347\254\202\377\377\377\23\377\376\377\377\377\375" \ + "\350\364\334\212\307>\220\306=\214\305@\216\306=\214\306>\214\305@\214" \ + "\306>\212\306@\215\305>\212\306@\215\307\77\212\307>\215\307\77\214\305" \ + "@\212\306@\277\340\221\202\377\377\377\1\377\377\375\203\377\377\377" \ + "\2\377\376\377\377\377\375\220\377\377\377\4\376\376\376\377\377\377" \ + "\265\265\265::<\202;;=\5""99;::<;;=99;\317\317\317\250\377\377\377\1" \ + "\376\376\376\202\377\377\377\2\316\316\31699;\202::<\202;;=\2::<\221" \ + "\221\223\215\377\377\377\1\316\316\316\205::<\1kkm\207\377\377\377\1" \ + "\376\376\376\204\377\377\377\1\332\332\334\203::<\5;;=::<;;=99;\302\302" \ + "\302\202\377\377\377\1\376\376\376\216\377\377\377\1\376\376\376\202" \ + "\377\377\377\1\376\376\376\204\377\377\377\4\362\362\362FFH::<;;=\202" \ + "::<\2;;=\221\221\223\204\377\377\377\202\376\376\376\224\377\377\377" \ + "\1\376\376\376\203\377\377\377\1kkm\202;;=\203::<\1SSU\220\377\377\377" \ + "\1\234\234\236\205::<\1\234\234\234\240\377\377\377\3\376\376\376\377" \ + "\377\377\315\315\315\203::<\1;;=\202::<\1SSU\216\377\377\377\1\234\234" \ + "\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305" \ + "@\204\214\306>\3\215\306A\214\306<\215\307=\202\214\305@\3\214\306>\253" \ + "\324n\377\377\375\230\377\377\377\2\375\376\377\376\376\376\203\377\377" \ + "\377\1\377\377\375\212\377\377\377\215\214\306>\1\250\325p\216\377\377" \ + "\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343" \ + "\361\316\220\377\377\377\5\350\365\333\214\306>\214\305@\214\306>\215" \ + "\306A\221\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\7" \ + "\377\377\375\277\337\224\212\306@\215\305@\212\307>\215\306A\215\307" \ + "\77\203\214\306>\202\215\307\77\203\214\306>\3\214\306<\214\306>\351" \ + "\363\330\202\377\377\377\3\376\376\376\374\377\377\376\377\377\211\377" \ + "\377\377\1\376\377\377\202\377\377\377\7\375\376\377\351\365\337\223" \ + "\311M\215\307=\214\305B\214\305@\215\307\77\202\214\306>\12\215\306A" \ + "\214\305@\214\306>\212\307>\215\306A\214\306>\215\307=\213\310\77\316" \ + "\345\255\376\377\377\221\377\377\377\7\376\377\377\377\377\375\300\337" \ + "\223\216\306A\213\305=\215\307=\215\305>\202\214\306>\1\215\307\77\203" \ + "\214\306>\202\214\305@\5\215\307\77\213\307A\251\322r\377\377\377\377" \ + "\377\375\202\377\377\377\14\377\376\377\377\377\377\305\342\237\212\307" \ + "<\220\305\77\214\306>\212\306@\215\306A\214\306<\214\305@\214\306<\216" \ + "\305C\202\214\306>\7\215\305<\214\306>\215\305>\214\305@\342\362\316" \ + "\377\377\377\377\377\375\202\377\377\377\3\376\377\377\377\376\377\376" \ + "\376\376\221\377\377\377\3\376\376\376\377\377\377___\205::<\4;;=FFH" \ + "\363\363\363\377\377\377\202\376\376\376\246\377\377\377\3\363\363\363" \ + "SSU;;=\204::<\4;;=\345\345\345\377\377\377\376\376\376\213\377\377\377" \ + "\1\316\316\316\205::<\1kkm\211\377\377\377\1\376\376\376\203\377\377" \ + "\377\4\264\264\266;;=99;::<\202;;=\3::<GGI\332\332\332\206\377\377\377" \ + "\1\376\376\376\215\377\377\377\1\376\376\376\203\377\377\377\3\234\234" \ + "\236::<;;=\204::<\2\346\346\346\376\376\376\202\377\377\377\1\376\376" \ + "\376\202\377\377\377\202\376\376\376\220\377\377\377\1\376\376\376\204" \ + "\377\377\377\2\376\376\376\317\317\317\204::<\3;;=::<\265\265\265\217" \ + "\377\377\377\1\234\234\236\205::<\1\234\234\234\235\377\377\377\1\376" \ + "\376\376\203\377\377\377\2\363\363\363TTV\203::<\5;;=99;::<\235\235\235" \ + "\376\376\376\215\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377" \ + "\377\377\3\214\305@\214\306>\214\305@\204\214\306>\2\212\306@\213\310" \ + "\77\202\214\305@\3\215\307\77\214\306<\251\323o\231\377\377\377\4\377" \ + "\376\377\377\377\375\377\377\377\376\376\377\214\377\377\377\215\214" \ + "\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305" \ + "@\211\214\306>\2\214\305@\343\361\316\215\377\377\377\1\377\377\375\203" \ + "\377\377\377\4\323\353\267\212\307<\214\306<\212\306B\221\214\306>\3" \ + "\215\305>\214\306>\305\342\240\214\377\377\377\7\376\377\377\377\376" \ + "\377\350\365\331\215\307\77\215\305>\214\306>\212\307>\202\214\306>\1" \ + "\215\307\77\205\214\306>\11\215\307\77\213\304A\212\307>\222\312M\343" \ + "\361\316\376\376\377\377\376\377\377\377\377\377\375\377\210\377\377" \ + "\377\1\377\376\377\202\377\377\375\12\377\376\377\350\364\334\220\313" \ + "K\216\306=\215\305<\215\307\77\214\306>\213\305=\214\306>\215\306A\202" \ + "\214\306>\1\214\305@\202\212\307>\6\214\305@\215\306C\215\305>\360\370" \ + "\351\377\377\373\376\377\377\221\377\377\377\7\345\360\322\215\305@\214" \ + "\305@\215\307=\214\304=\213\310=\215\305>\202\214\306>\2\213\305=\215" \ + "\307\77\202\214\305@\7\215\307\77\214\307;\214\305@\363\367\346\376\377" \ + "\377\377\377\373\377\376\377\202\377\377\377\30\376\377\375\377\376\377" \ + "\241\321a\216\306\77\212\306@\213\310=\215\305@\213\307A\217\304>\215" \ + "\305@\214\306<\216\306A\215\306A\212\307>\214\306<\214\306>\212\307<" \ + "\233\314W\366\373\365\377\377\375\377\377\377\377\376\377\373\377\377" \ + "\377\376\377\224\377\377\377\1\317\317\317\205::<\4;;=::<``b\362\362" \ + "\362\247\377\377\377\2\376\376\376\221\221\221\206::<\3\204\204\206\377" \ + "\377\377\376\376\376\214\377\377\377\1\316\316\316\205::<\1kkm\212\377" \ + "\377\377\6\376\376\376\377\377\377\376\376\376\377\377\377\203\203\203" \ + ";;=\205::<\3``b\363\363\363\376\376\376\216\377\377\377\1\376\376\376" \ + "\206\377\377\377\3\363\363\363FFH;;=\203::<\2;;=\203\203\203\203\377" \ + "\377\377\3\376\376\376\377\377\377\376\376\376\225\377\377\377\1\376" \ + "\376\376\204\377\377\377\3kkk::<<<>\202::<\2;;=kkm\217\377\377\377\1" \ + "\234\234\236\205::<\1\234\234\234\236\377\377\377\4\376\376\376\377\377" \ + "\377\376\376\376kkk\202::<\5;;=::<99;;;=TTV\202\377\377\377\1\376\376" \ + "\376\214\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377" \ + "\3\214\305@\214\306>\214\305@\204\214\306>\10\214\306<\214\306>\214\305" \ + "@\214\306>\215\307\77\214\306>\252\324r\376\377\377\230\377\377\377\1" \ + "\377\377\375\202\377\377\377\2\377\377\375\376\376\374\203\377\376\377" \ + "\210\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320" \ + "\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316\215\377" \ + "\377\377\10\375\377\374\377\376\377\375\377\376\376\376\377\377\377\377" \ + "\270\333\207\214\305@\215\307\77\221\214\306>\3\215\305>\214\306>\305" \ + "\342\240\214\377\377\377\12\375\376\377\377\376\377\376\377\377\234\313" \ + "Y\215\306A\214\305@\212\307>\214\305@\214\306>\215\307\77\206\214\306" \ + ">\7\215\307\77\214\306>\215\305@\213\310\77\304\343\240\371\372\364\376" \ + "\377\377\212\377\377\377\10\376\377\377\377\376\377\315\345\251\223\311" \ + "M\214\306>\216\306\77\214\305B\214\306<\202\214\306>\15\215\306A\214" \ + "\305@\214\306>\215\307\77\214\305@\214\306<\214\305@\215\307\77\213\304" \ + "A\263\330{\377\377\377\376\376\376\377\377\375\220\377\377\377\7\370" \ + "\373\364\232\315V\216\306=\212\311=\214\306>\216\306A\213\307A\202\214" \ + "\305@\202\214\306>\202\214\305@\10\215\307\77\215\305>\215\304D\304\341" \ + "\237\376\377\377\377\376\377\376\376\377\377\377\375\202\377\376\377" \ + "\24\376\377\377\377\377\373\350\365\333\215\305>\214\306<\214\306>\212" \ + "\306@\215\307\77\213\305=\215\305@\215\307\77\214\306>\215\305>\215\306" \ + "A\211\305A\215\305@\214\305B\213\310=\262\327z\374\377\377\202\377\377" \ + "\377\2\377\377\375\373\377\376\225\377\377\377\1\221\221\223\203::<\6" \ + ";;=99;;;=::<``b\362\362\362\246\377\377\377\2\265\265\265:::\202::<\1" \ + ";;=\203::<\1\346\346\350\216\377\377\377\1\316\316\316\205::<\1kkm\216" \ + "\377\377\377\6\363\363\363__a::<;;=::<;;=\202::<\1\204\204\204\204\377" \ + "\377\377\1\376\376\376\221\377\377\377\1\234\234\234\204::<\3;;=::<\347" \ + "\347\347\202\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376" \ + "\225\377\377\377\3\376\376\376\377\377\377\265\265\265\202::<\202;;=" \ + "\3::<;;=\316\316\316\216\377\377\377\1\234\234\236\205::<\1\234\234\234" \ + "\240\377\377\377\2\204\204\204:::\206::<\1\301\301\303\217\377\377\377" \ + "\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306" \ + ">\214\305@\205\214\306>\7\214\305@\216\306A\215\307=\213\304\77\213\307" \ + "A\242\321a\345\356\317\230\342\362\316\7\341\361\315\342\361\322\342" \ + "\361\320\343\361\315\345\360\322\365\373\357\376\377\377\211\377\377" \ + "\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306" \ + ">\1\214\305@\211\214\306>\2\214\305@\343\361\316\216\377\377\377\7\376" \ + "\377\375\377\377\375\377\377\377\377\376\377\371\374\365\242\322d\215" \ + "\306A\221\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\10" \ + "\377\377\375\377\377\377\377\377\373\312\346\253\215\307=\212\307>\214" \ + "\305B\216\306=\206\214\306>\202\214\305@\10\214\306>\212\307>\216\306" \ + "\77\214\306>\212\307>\233\316W\306\340\237\361\370\346\210\377\377\377" \ + "\12\361\370\350\314\345\253\233\314W\214\306>\213\310\77\215\305<\214" \ + "\305@\212\307<\215\306A\214\305@\203\214\306>\202\214\305@\202\214\306" \ + ">\4\216\306A\212\306@\213\310\77\333\356\301\202\377\377\377\1\377\377" \ + "\375\220\377\377\377\26\270\332\204\215\306A\212\306B\214\306>\213\307" \ + "A\215\305@\214\306<\214\306>\215\306A\214\306<\215\307\77\214\305B\215" \ + "\307\77\214\307;\215\304D\241\323b\377\377\375\376\377\377\377\377\377" \ + "\377\377\373\377\377\377\376\377\377\202\377\377\375\16\377\377\377\376" \ + "\377\377\277\337\224\214\305@\215\306A\214\306>\215\305>\212\310\77\214" \ + "\305@\215\307\77\212\307>\214\305B\216\306=\215\306A\202\214\306<\6\214" \ + "\306>\213\307C\331\356\305\377\376\377\377\377\373\376\376\376\227\377" \ + "\377\377\3__a::<;:\77\205::<\2__a\363\363\363\203\377\377\377\1\376\376" \ + "\376\213\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377" \ + "\377\377\376\376\376\213\377\377\377\1\376\376\376\202\377\377\377\1" \ + "\265\265\267\205::<\3;;=:::\234\234\234\217\377\377\377\1\316\316\316" \ + "\205::<\1kkm\217\377\377\377\4\332\332\332GGI::<;;=\204::<\1\250\250" \ + "\252\225\377\377\377\1FFH\205::<\1\204\204\204\242\377\377\377\1TTV\205" \ + "::<\4lln\376\376\376\377\377\377\376\376\376\203\377\377\377\1\376\376" \ + "\376\207\377\377\377\1\234\234\236\205::<\1\235\235\237\221\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\202\376" \ + "\376\376\205\377\377\377\3\363\363\365\204\204\206;;=\204::<\3;;=:::" \ + "xxx\220\377\377\377\1\234\234\234\203::<\3;;=::<\234\234\234\204\377" \ + "\377\377\1\376\376\376\261\377\377\377\3\214\305@\214\306>\214\305@\250" \ + "\214\306>\2\215\307\77\342\362\316\212\377\377\377\215\214\306>\1\250" \ + "\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306" \ + ">\2\214\305@\343\361\316\216\377\377\377\11\375\376\377\377\376\377\377" \ + "\377\375\376\377\377\377\376\377\351\365\335\223\311M\212\307<\214\306" \ + ">\202\216\306A\4\212\307<\215\306A\215\305>\215\307\77\211\214\306>\3" \ + "\215\305>\214\306>\305\342\240\214\377\377\377\20\377\376\377\377\377" \ + "\375\377\376\377\365\374\364\223\312J\217\304>\215\307\77\212\307;\215" \ + "\306A\214\305B\214\305@\215\307\77\214\306<\213\310\77\214\305@\215\305" \ + ">\210\214\306>\10\234\315Z\257\327~\304\343\235\306\340\237\307\341\240" \ + "\304\343\237\257\327\177\241\321a\210\214\306>\20\217\304>\215\306A\212" \ + "\306@\212\307>\213\305;\216\306A\213\305=\215\306C\211\310<\216\306A" \ + "\214\306>\234\314V\377\377\377\375\377\374\376\377\377\377\376\377\211" \ + "\377\377\377\7\377\376\377\376\377\375\376\377\377\376\377\375\377\376" \ + "\377\377\377\377\333\355\303\210\214\306>\10\215\306A\214\305@\216\306" \ + "=\214\306>\215\307\77\214\305@\215\307\77\352\364\334\211\377\377\377" \ + "\6\377\376\377\367\375\363\232\315V\215\307\77\214\306>\214\305@\212" \ + "\214\306>\6\212\307>\223\311M\366\373\364\377\376\377\377\377\377\376" \ + "\377\373\221\377\377\377\1\376\376\376\204\377\377\377\2\346\346\346" \ + "FFH\203::<\1""99;\203::<\2__a\332\332\332\211\377\377\377\1\376\376\376" \ + "\203\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\206\377" \ + "\377\377\1\376\376\376\207\377\377\377\1\265\265\267\202::<\1;;=\204" \ + "::<\2```\376\376\376\217\377\377\377\1\316\316\316\205::<\1kkm\216\377" \ + "\377\377\4\376\376\376\377\377\377\301\301\301;;=\205::<\2;;=\331\331" \ + "\331\202\377\377\377\3\376\376\376\377\377\377\376\376\376\216\377\377" \ + "\377\1\265\265\267\205::<\3;;=\332\332\332\376\376\376\241\377\377\377" \ + "\1\266\266\270\205::<\2""99;\316\316\320\215\377\377\377\1\234\234\236" \ + "\203::<\5;;=::<\234\234\234\377\377\377\376\376\376\220\377\377\377\1" \ + "\376\376\376\206\377\377\377\1\376\376\376\203\377\377\377\2\346\346" \ + "\346``b\202::<\2""99;;;=\203::<\4FFF\363\363\363\377\377\377\376\376" \ + "\376\216\377\377\377\1\234\234\234\204::<\3;;=\234\234\234\376\376\376" \ + "\265\377\377\377\3\214\305@\214\306>\214\305@\250\214\306>\2\215\307" \ + "\77\342\362\316\212\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \ + "\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361" \ + "\316\215\377\377\377\16\377\376\377\376\377\377\377\376\377\377\377\377" \ + "\376\377\377\377\376\377\375\377\374\323\353\267\215\305<\215\306C\215" \ + "\305<\213\306:\213\310\77\212\306@\202\214\305@\211\214\306>\3\215\305" \ + ">\214\306>\305\342\240\215\377\377\377\4\376\377\377\377\377\375\377" \ + "\376\377\305\342\242\202\214\305@\5\216\306A\214\306>\215\307=\215\307" \ + "\77\213\304A\202\214\305@\2\214\306>\212\306@\210\214\306>\7\214\306" \ + "<\215\307=\215\307\77\213\305=\214\306>\215\307\77\213\305=\211\214\306" \ + ">\11\215\306A\215\305>\212\307;\213\304\77\215\306A\211\306=\215\306" \ + "A\212\307<\216\306A\202\215\307\77\4\343\361\320\376\377\375\377\377" \ + "\375\376\376\377\212\377\377\377\1\377\376\377\202\377\377\377\4\377" \ + "\376\377\376\377\377\367\375\363\225\311J\210\214\306>\10\215\307=\213" \ + "\310\77\214\305@\216\306\77\214\305@\212\307>\307\341\240\376\377\375" \ + "\210\377\377\377\5\377\376\377\374\377\375\377\376\377\343\361\320\212" \ + "\306@\202\214\306>\1\213\310\77\210\214\306>\10\215\306A\215\305>\214" \ + "\305@\260\327z\377\376\374\374\377\377\377\377\377\377\376\377\226\377" \ + "\377\377\1\332\332\332\210::<\2GGI\250\250\250\223\377\377\377\3\376" \ + "\376\376\377\377\377\376\376\376\202\377\377\377\1\376\376\376\202\377" \ + "\377\377\1\376\376\376\204\377\377\377\2\250\250\252;;=\204::<\202;;" \ + "=\2EEG\331\331\331\220\377\377\377\1\316\316\316\205::<\1kkm\221\377" \ + "\377\377\5\222\222\224::<;;=::<;;=\202::<\5SSU\364\364\364\376\376\376" \ + "\377\377\377\376\376\376\216\377\377\377\2\376\376\376TTV\203::<\4;;" \ + "=99;lln\376\376\376\243\377\377\377\1TTV\204::<\5;;=\204\204\206\376" \ + "\376\376\377\377\377\376\376\376\212\377\377\377\1\234\234\236\202::" \ + "<\1;;=\202::<\1\234\234\234\215\377\377\377\1\376\376\376\202\377\377" \ + "\377\1\376\376\376\212\377\377\377\6\376\376\376\250\250\252FFH99;::" \ + "<;;=\205::<\1\316\316\316\221\377\377\377\1\234\234\234\203::<\3;;=:" \ + ":<\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305@\250\214\306" \ + ">\2\215\307\77\342\362\316\212\377\377\377\215\214\306>\1\250\325p\216" \ + "\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214" \ + "\305@\343\361\316\215\377\377\377\3\377\376\377\376\377\375\376\377\377" \ + "\202\377\377\377\13\377\377\375\377\376\377\376\376\374\271\332\211\215" \ + "\306A\211\306;\216\306A\212\307>\213\307A\215\306A\212\307>\211\214\306" \ + ">\3\215\305>\214\306>\305\342\240\214\377\377\377\20\376\377\375\377" \ + "\377\377\377\377\375\377\377\377\371\370\364\233\316U\214\306>\214\305" \ + "@\215\306A\214\306>\214\305@\215\307=\214\306>\215\305@\215\304B\213" \ + "\310=\210\214\306>\3\215\305@\214\306>\213\305=\202\213\310\77\3\214" \ + "\306>\215\307\77\215\305@\210\214\306>\20\212\306@\212\307;\216\306\77" \ + "\215\307\77\212\306@\214\306<\215\305>\215\307\77\220\305\77\211\307" \ + ">\263\330{\377\376\377\377\377\375\376\377\377\377\377\377\376\376\376" \ + "\211\377\377\377\7\377\377\373\377\377\377\377\375\376\377\377\377\377" \ + "\377\375\257\330|\213\310\77\211\214\306>\6\215\306C\211\306=\214\305" \ + "@\214\306>\242\322e\377\377\375\212\377\377\377\7\376\377\377\377\377" \ + "\375\377\375\376\277\337\224\216\307B\212\307>\214\305@\210\214\306>" \ + "\2\214\305@\216\306\77\202\212\307>\4\332\360\302\376\376\374\376\376" \ + "\376\377\376\377\227\377\377\377\1\266\266\266\202::<\1;;=\202::<\2;" \ + ";=::<\202;;=\2kkm\346\346\350\202\377\377\377\1\376\376\376\207\377\377" \ + "\377\1\376\376\376\203\377\377\377\5\376\376\376\377\377\377\376\376" \ + "\376\377\377\377\376\376\376\202\377\377\377\3\376\376\376\377\377\377" \ + "\376\376\376\204\377\377\377\2\364\364\364yy{\203::<\2;;=99;\203::<\3" \ + "\265\265\267\377\377\377\376\376\376\217\377\377\377\1\316\316\316\205" \ + "::<\1kkm\222\377\377\377\1kkm\203::<\1;;=\202::<\5kkm\377\377\377\376" \ + "\376\376\377\377\377\376\376\376\212\377\377\377\5\376\376\376\377\377" \ + "\377\376\376\376\265\265\267;;=\204::<\2;;=\315\315\315\244\377\377\377" \ + "\11\234\234\234::<99;;;=::<;;=::<\347\347\347\376\376\376\213\377\377" \ + "\377\1\234\234\236\204::<\2;;=\233\233\233\217\377\377\377\1\376\376" \ + "\376\206\377\377\377\6\376\376\376\377\377\377\376\376\376\377\377\377" \ + "\265\265\265TTT\202::<\202;;=\203::<\3;;=::<\266\266\270\202\377\377" \ + "\377\1\376\376\376\217\377\377\377\1\234\234\234\204::<\4;;=\235\235" \ + "\237\377\377\377\376\376\376\224\377\377\377\1\376\376\376\203\377\377" \ + "\377\1\376\376\376\233\377\377\377\3\214\305@\214\306>\214\305@\250\214" \ + "\306>\2\215\307\77\342\362\316\212\377\377\377\215\214\306>\1\250\325" \ + "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>" \ + "\2\214\305@\343\361\316\215\377\377\377\202\377\377\375\16\377\377\377" \ + "\377\377\375\377\377\377\376\377\375\376\376\374\377\376\377\375\377" \ + "\376\241\322_\215\306A\212\306B\215\305>\215\307\77\214\306<\214\305" \ + "B\211\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\1\377" \ + "\376\377\202\377\377\375\15\376\377\377\377\375\376\340\361\317\214\306" \ + ">\212\307>\214\306>\215\307\77\214\306>\212\307<\215\307\77\215\305>" \ + "\216\306=\213\305=\210\214\306>\1\212\307>\202\214\305@\202\214\306>" \ + "\3\214\305@\215\306A\212\307>\210\214\306>\20\212\307>\213\304\77\214" \ + "\306>\211\310<\214\306>\216\306A\212\306@\215\305@\214\306>\223\313N" \ + "\367\372\363\376\377\377\377\377\377\377\376\377\376\377\373\377\376" \ + "\377\212\377\377\377\202\376\377\377\3\377\375\376\324\353\265\215\306" \ + "A\211\214\306>\7\215\305>\213\305=\215\307\77\215\306A\212\307>\351\363" \ + "\333\377\377\375\211\377\377\377\10\377\376\377\375\377\376\376\377\377" \ + "\377\376\377\370\373\362\233\314W\215\307\77\215\305<\210\214\306>\1" \ + "\215\307\77\202\214\306>\4\214\306<\225\310O\360\366\350\377\376\377" \ + "\221\377\377\377\3\376\376\376\377\377\377\376\376\376\205\377\377\377" \ + "\1\266\266\266\202::<\4;;=99;::<;;=\202::<\4;;=::<\204\204\206\346\346" \ + "\350\207\377\377\377\1\376\376\376\206\377\377\377\202\376\376\376\202" \ + "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\202\377\377" \ + "\377\3\251\251\251FFF99;\202::<\1""99;\202::<\5;;=::<\234\234\236\377" \ + "\377\377\376\376\376\220\377\377\377\1\316\316\316\205::<\1kkm\222\377" \ + "\377\377\11\363\363\363GGI99;::<99;;;=::<;;=\234\234\234\214\377\377" \ + "\377\1\376\376\376\203\377\377\377\1SSU\202::<\1;;=\202::<\1kkm\245\377" \ + "\377\377\5\362\362\362GGI;;=::<;;=\202::<\1\204\204\206\206\377\377\377" \ + "\1\376\376\376\205\377\377\377\1\234\234\236\203::<\3""99;::<\234\234" \ + "\234\223\377\377\377\1\376\376\376\203\377\377\377\3\331\331\331\222" \ + "\222\222SSU\203::<\2;;=::<\202;;=\4::<;;=::<\265\265\267\202\377\377" \ + "\377\1\376\376\376\203\377\377\377\1\376\376\376\214\377\377\377\1\234" \ + "\234\234\205::<\1\234\234\236\203\377\377\377\1\376\376\376\223\377\377" \ + "\377\1\376\376\376\236\377\377\377\3\214\305@\214\306>\214\305@\250\214" \ + "\306>\2\215\307\77\342\362\316\212\377\377\377\215\214\306>\1\250\325" \ + "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>" \ + "\2\214\305@\343\361\316\216\377\377\377\17\377\376\377\377\377\377\376" \ + "\376\376\377\376\377\377\377\375\376\377\377\375\377\376\377\377\377" \ + "\363\367\350\222\312K\214\305@\213\310\77\214\304\77\215\307\77\216\306" \ + "A\211\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\14\377" \ + "\376\377\376\377\375\376\377\377\377\376\377\376\377\377\376\377\375" \ + "\307\342\237\214\305@\214\306<\215\304D\214\306>\214\305D\202\212\307" \ + "<\2\212\307>\213\307A\210\214\306>\3\215\307\77\214\306>\215\307\77\202" \ + "\214\305@\213\214\306>\12\213\305;\215\306A\212\306@\214\306>\213\307" \ + "C\212\307>\215\305>\212\307>\215\305>\333\356\301\202\377\377\377\3\377" \ + "\377\375\377\377\377\377\376\377\211\377\377\377\10\376\377\375\377\377" \ + "\375\376\377\375\374\377\375\362\371\347\225\311M\215\307\77\215\305" \ + "<\210\214\306>\2\214\305@\216\306=\202\212\306@\2\305\342\237\377\375" \ + "\376\212\377\377\377\1\376\376\374\203\377\377\377\4\376\376\376\337" \ + "\363\316\215\306C\215\305<\211\214\306>\1\215\307\77\202\214\305@\4\214" \ + "\306<\253\324n\375\377\374\377\377\375\224\377\377\377\1\376\376\376" \ + "\204\377\377\377\2\301\301\301FFH\202::<\2;;=99;\202;;=\2::<;;=\202:" \ + ":<\2\204\204\206\316\316\320\207\377\377\377\1\376\376\376\203\377\377" \ + "\377\1\376\376\376\206\377\377\377\6\376\376\376\377\377\377\364\364" \ + "\364\265\265\267SSU::<\202;;=\202::<\5;;=::<;;=::<\204\204\204\223\377" \ + "\377\377\1\316\316\316\205::<\1kkm\223\377\377\377\11\315\315\315;;=" \ + "::<;;=::<;;=::<99;\302\302\302\216\377\377\377\5\301\301\303::<;;=::" \ + "<;;=\202::<\2\316\316\316\377\377\377\202\376\376\376\241\377\377\377" \ + "\14\376\376\376\377\377\377\234\234\234;;=::<;;=::<;;=::<\347\347\351" \ + "\377\377\377\376\376\376\211\377\377\377\1\234\234\236\203::<\3;;=::" \ + "<\234\234\236\216\377\377\377\202\376\376\376\1\377\377\377\202\316\316" \ + "\316\6\250\250\250\234\234\234jjjFFF;;=99;\202;;=\2::<;;=\202::<\5<<" \ + ">99;;;=::<\265\265\267\204\377\377\377\1\376\376\376\217\377\377\377" \ + "\1\234\234\234\204::<\2;;=\234\234\236\202\377\377\377\1\376\376\376" \ + "\223\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\234\377" \ + "\377\377\3\214\305@\214\306>\214\305@\250\214\306>\2\215\307\77\342\362" \ + "\316\212\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361" \ + "\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316\215" \ + "\377\377\377\202\377\376\377\16\377\377\375\376\377\377\377\377\377\377" \ + "\377\375\377\376\377\376\376\376\377\376\377\377\377\377\333\354\302" \ + "\212\307>\213\310\77\214\306<\213\310=\215\305@\211\214\306>\3\215\305" \ + ">\214\306>\305\342\240\214\377\377\377\1\377\376\377\202\376\377\377" \ + "\202\377\377\375\13\376\377\377\377\375\376\271\333\205\215\305>\214" \ + "\306>\212\307>\214\306>\215\306A\214\306>\212\306@\214\305@\210\214\306" \ + ">\3\214\305@\215\307\77\214\306>\202\212\307>\3\214\306>\215\307\77\215" \ + "\306A\210\214\306>\4\216\306A\211\306=\214\306<\216\306A\202\212\307" \ + ">\202\215\306A\10\322\352\270\377\377\375\376\376\374\377\377\377\376" \ + "\377\377\377\376\377\377\377\375\376\377\377\210\377\377\377\10\377\377" \ + "\375\377\377\377\377\376\377\374\376\373\250\325n\216\306\77\212\307" \ + ">\214\305B\210\214\306>\202\212\307>\6\214\305@\242\322d\376\376\374" \ + "\377\377\375\375\377\376\377\376\377\210\377\377\377\10\376\377\377\377" \ + "\377\375\377\375\376\377\377\375\375\376\377\376\377\375\270\333\207" \ + "\211\310<\210\214\306>\10\214\304=\216\307B\214\306>\212\307>\216\306" \ + "A\215\307\77\313\350\250\376\376\377\221\377\377\377\1\376\376\376\203" \ + "\377\377\377\1\376\376\376\204\377\377\377\7\332\332\332RRT;;=::<;;=" \ + "::<;;=\202::<\1;;=\203::<\3RRT\221\221\223\317\317\321\214\377\377\377" \ + "\11\376\376\376\377\377\377\364\364\364\301\301\301\204\204\206EEG;;" \ + "=99;;;=\204::<\1""99;\202::<\1\251\251\251\207\377\377\377\1\376\376" \ + "\376\214\377\377\377\1\316\316\316\205::<\1kkm\224\377\377\377\1\247" \ + "\247\247\203::<\5;;=::<;;=FFH\345\345\345\214\377\377\377\2\376\376\376" \ + "kkm\205::<\1SSU\202\377\377\377\1\376\376\376\244\377\377\377\2\363\363" \ + "\363FFH\204::<\2;;=\221\221\223\213\377\377\377\1\234\234\236\204::<" \ + "\4;;=SSUkkmlln\213kkm\5;;=::<;;=::<;;=\204::<\2;;=99;\202;;=\2::<;;=" \ + "\202::<\7;;=99;::<FFH\301\301\301\377\377\377\376\376\376\223\377\377" \ + "\377\1\234\234\234\205::<\1SSU\202kkm\1lln\223kkm\1lln\205kkm\1\332\332" \ + "\334\231\377\377\377\3\214\305@\214\306>\214\305@\250\214\306>\2\215" \ + "\307\77\342\362\316\212\377\377\377\215\214\306>\1\250\325p\216\377\377" \ + "\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343" \ + "\361\316\215\377\377\377\1\377\376\377\202\377\377\375\202\377\377\377" \ + "\202\377\376\377\11\377\377\375\377\377\377\376\377\377\377\376\377\276" \ + "\336\223\214\306<\213\310\77\214\304=\215\306A\211\214\306>\3\215\305" \ + ">\214\306>\305\342\240\214\377\377\377\20\377\377\375\376\377\375\376" \ + "\376\376\377\376\377\375\377\376\377\375\377\376\377\377\376\377\375" \ + "\270\333\207\217\305<\212\307>\214\305@\216\306\77\213\305=\214\305@" \ + "\216\306=\211\214\306>\2\215\306A\215\305@\202\216\306\77\3\215\305@" \ + "\214\305@\215\307\77\210\214\306>\13\213\305=\215\306A\215\305>\212\306" \ + "@\215\305>\215\306A\220\305A\323\352\266\376\377\375\377\376\377\377" \ + "\377\375\202\377\377\377\3\376\377\377\377\375\377\376\377\375\213\377" \ + "\377\377\5\316\347\256\212\307>\213\305;\216\306A\212\307<\210\214\306" \ + ">\10\212\307>\216\306\77\215\305>\350\364\336\377\376\377\376\376\374" \ + "\377\377\377\377\376\377\210\377\377\377\1\377\376\377\202\377\377\377" \ + "\5\377\376\377\376\377\375\377\376\377\370\373\360\225\311K\210\214\306" \ + ">\10\216\306=\214\305@\215\310<\212\307>\214\306>\214\305@\223\312J\356" \ + "\371\350\231\377\377\377\4\376\376\376\377\377\377\363\363\363xxz\202" \ + "::<\1""99;\202::<\1;;=\203::<\202;;=\203::<\4__a\205\205\205\234\234" \ + "\234\250\250\250\205\316\316\316\4\250\250\250\234\234\234xxx___\202" \ + "::<\3""99;;;=99;\203::<\1;;=\203::<\2FFH\265\265\265\205\377\377\377" \ + "\1\376\376\376\217\377\377\377\1\316\316\316\205::<\1kkm\225\377\377" \ + "\377\3xxx::<;;=\204::<\1```\213\377\377\377\4\376\376\376\317\317\317" \ + "::<;;=\204::<\1\266\266\270\203\377\377\377\1\376\376\376\241\377\377" \ + "\377\1\377\377\375\202\377\377\377\1\204\204\206\202::<\1;;=\202::<\2" \ + "GGI\363\363\363\212\377\377\377\1\234\234\236\203::<\1;;=\202::<\1;;" \ + "=\221::<\1;;=\207::<\1;;=\202::<\1;;=\202::<\2``b\346\346\350\210\377" \ + "\377\377\1\376\376\376\215\377\377\377\1\234\234\234\207::<\3;;=::<;" \ + ";=\221::<\1;;=\203::<\1;;=\202::<\1\316\316\320\231\377\377\377\3\214" \ + "\305@\214\306>\214\305@\250\214\306>\2\215\307\77\342\362\316\212\377" \ + "\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214" \ + "\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316\215\377\377\377" \ + "\7\377\377\375\376\377\375\377\377\377\377\376\377\376\376\374\376\377" \ + "\377\377\377\377\202\376\377\377\202\377\377\375\4\377\377\377\242\320" \ + "d\211\306=\215\305@\212\214\306>\3\215\305>\214\306>\305\342\240\214" \ + "\377\377\377\6\377\376\377\377\377\377\377\377\375\377\375\377\376\377" \ + "\372\375\376\377\202\377\377\377\10\376\377\377\304\343\240\215\305@" \ + "\214\306>\216\306A\215\307\77\212\307>\215\307\77\212\214\306>\3\215" \ + "\307\77\214\306>\214\305@\202\215\307\77\211\214\306>\12\215\306C\212" \ + "\307<\215\307\77\215\305@\213\310\77\215\306A\323\352\266\377\376\377" \ + "\377\377\377\376\377\377\204\377\377\377\2\377\377\375\377\376\377\210" \ + "\377\377\377\10\376\377\377\377\376\377\361\370\346\225\311K\212\307" \ + ">\215\306A\214\305@\215\305>\210\214\306>\3\214\305@\214\306>\307\341" \ + "\240\203\376\377\377\2\377\377\375\376\377\377\210\377\377\377\5\376" \ + "\377\377\377\376\372\376\377\375\376\376\376\377\377\377\202\377\376" \ + "\377\1\334\355\301\210\214\306>\10\215\306A\213\310\77\215\305@\214\306" \ + ">\214\306<\215\306A\214\306>\254\322o\232\377\377\377\6\376\376\376\377" \ + "\377\377\376\376\376\302\302\302FFH;;=\206::<\1;;=\202::<\202;;=\203" \ + "::<\1;;=\204::<\3;;=::<;;=\202::<\1;;=\202::<\1;;=\203::<\2;;=::<\202" \ + ";;=\2__a\332\332\332\226\377\377\377\3\316\316\316::<;;=\203::<\1kkm" \ + "\222\377\377\377\7\376\376\376\377\377\377\376\376\376\363\363\363__" \ + "a::<;;=\204::<\1\203\203\203\202\377\377\377\2\376\376\376\377\377\377" \ + "\202\376\376\376\205\377\377\377\1kkm\202::<\1;;=\202::<\5TTV\377\377" \ + "\377\376\376\376\377\377\377\376\376\376\245\377\377\377\2\347\347\347" \ + "99;\202::<\1;;=\202::<\1\235\235\237\206\377\377\377\1\376\376\376\202" \ + "\377\377\377\2\376\376\376\234\234\234\224::<\1;;=\202::<\3""99;::<;" \ + ";=\204::<\1;;=\204::<\3;;=GGI\250\250\252\230\377\377\377\2\234\234\236" \ + ";;=\232::<\10;;=99;;;=::<;;=::<:::\316\316\316\230\377\377\377\10\377" \ + "\376\377\212\306@\214\305@\213\310=\214\306<\215\306A\214\307;\215\306" \ + "A\240\214\306>\10\214\305@\212\307<\214\306<\214\305@\212\306@\342\360" \ + "\315\376\377\377\377\376\377\210\377\377\377\212\214\306>\4\216\306\77" \ + "\212\306B\214\306>\250\325n\202\377\376\377\210\377\377\377\1\377\376" \ + "\377\202\377\377\377\5\376\377\375\342\362\316\214\305B\215\305@\214" \ + "\306<\210\214\306>\202\212\307>\5\343\361\320\377\377\377\377\377\375" \ + "\376\377\377\377\376\377\223\377\377\377\6\377\376\377\377\377\375\371" \ + "\372\364\223\312J\212\306@\215\305@\210\214\306>\10\214\305@\215\305" \ + ">\212\307>\304\343\240\377\377\375\377\377\377\377\377\375\377\376\377" \ + "\220\377\377\377\11\376\377\377\377\377\377\333\355\303\226\310K\213" \ + "\310\77\214\306>\215\305@\215\306A\214\305@\203\214\306>\7\215\305>\215" \ + "\305@\214\305@\212\307>\215\305>\215\307\77\215\306A\202\214\306<\5\215" \ + "\306A\213\305=\215\305@\215\307\77\213\305;\202\215\305@\13\215\307\77" \ + "\213\310\77\214\305@\215\307\77\212\307>\215\305>\214\306>\212\306@\235" \ + "\315U\347\365\334\377\376\377\220\377\377\377\15\376\376\376\377\377" \ + "\375\377\377\377\244\317c\213\307A\214\306<\213\307A\215\305>\215\305" \ + "<\215\307\77\214\306<\215\307\77\214\305@\202\215\307\77\12\214\305@" \ + "\215\306A\215\305@\234\315W\367\375\363\377\376\377\376\377\377\377\377" \ + "\375\376\377\377\377\376\377\220\377\377\377\10\260\331{\215\307=\212" \ + "\307>\213\307A\214\306>\215\305@\215\307\77\215\305>\210\214\306>\3\314" \ + "\345\253\377\377\377\376\377\375\202\377\376\377\2\377\377\377\376\377" \ + "\377\222\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377" \ + "\377\3\364\364\364\220\220\220;;=\211::<\2;;=::<\202;;=\2::<;;=\202:" \ + ":<\4;;=::<;;=99;\203::<\2;;=99;\206::<\2GGI\247\247\251\203\377\377\377" \ + "\1\376\376\376\222\377\377\377\6\376\376\376\377\377\377\316\316\316" \ + ";;=99;;;=\202::<\2lln\376\376\376\202\377\377\377\1\376\376\376\221\377" \ + "\377\377\4\376\376\376\333\333\333FFH;;=\202::<\1;;=\202::<\1\265\265" \ + "\265\202\377\377\377\1\376\376\376\202\377\377\377\5\376\376\376\377" \ + "\377\377\376\376\376\377\377\377\316\316\320\202::<\2;;=99;\202;;=\1" \ + "\264\264\266\202\377\377\377\1\376\376\376\244\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\205\205\207\204::<\3;;=FFH\363\363\363\206\377" \ + "\377\377\1\376\376\376\202\377\377\377\3\233\233\233::<;;=\220::<\3""9" \ + "9;;;=99;\202::<\1;;=\203::<\1;;=\204::<\7;;=::<SSU\250\250\252\362\362" \ + "\364\377\377\377\376\376\376\225\377\377\377\3\376\376\376\377\377\377" \ + "\235\235\237\202::<\1;;=\231::<\2;;=99;\204::<\1\316\316\316\230\377" \ + "\377\377\10\377\377\373\212\311=\212\306@\216\306A\215\305>\215\307\77" \ + "\214\306>\215\306A\240\214\306>\7\214\306<\214\306>\216\306\77\214\306" \ + ">\214\305@\343\361\320\377\377\375\211\377\377\377\210\214\306>\10\213" \ + "\307A\212\306@\215\305@\212\307<\215\307\77\247\324o\375\377\376\376" \ + "\377\377\211\377\377\377\7\376\377\375\377\377\377\377\377\375\342\360" \ + "\315\214\305@\213\305=\215\307\77\210\214\306>\10\215\305>\215\307\77" \ + "\343\361\316\376\376\376\377\376\377\376\377\377\377\377\375\376\377" \ + "\372\220\377\377\377\10\376\377\377\377\376\377\377\377\375\377\376\374" \ + "\376\377\375\343\362\321\212\307>\214\307;\210\214\306>\4\215\307=\215" \ + "\304B\213\307A\305\342\240\203\377\377\377\1\376\377\377\222\377\377" \ + "\377\21\377\376\377\367\374\365\267\332\206\215\306A\212\306@\214\306" \ + "<\214\306>\215\306A\215\307\77\214\306>\214\305@\212\306B\212\306@\212" \ + "\307<\215\307\77\214\306>\214\305@\202\215\305@\5\214\305@\214\306>\214" \ + "\305@\212\307>\215\306A\202\214\305@\11\214\307;\214\306>\215\306A\214" \ + "\305@\215\305>\212\306@\222\311I\306\343\240\366\373\364\224\377\377" \ + "\377\6\303\342\237\217\304@\214\306<\214\306>\215\306C\212\306B\204\214" \ + "\305@\1\215\306A\202\214\305@\11\215\306A\214\306<\214\306>\341\361\314" \ + "\377\377\377\376\377\375\377\377\377\377\375\377\377\377\375\221\377" \ + "\377\377\10\370\373\364\224\307N\215\305@\215\305>\212\307<\215\306A" \ + "\212\307<\215\306A\210\214\306>\10\215\307=\346\364\332\376\377\375\376" \ + "\377\373\377\377\377\376\376\377\377\376\377\377\377\375\230\377\377" \ + "\377\5\346\346\350\204\204\206GGI::<;;=\202::<\5;;=::<;;=::<;;=\202:" \ + ":<\3;;=::<;;=\202::<\5;;=99;;;=::<;;=\207::<\3FFH\234\234\234\363\363" \ + "\363\203\377\377\377\1\376\376\376\222\377\377\377\1\376\376\376\202" \ + "\377\377\377\4\316\316\316::<;;=99;\202;;=\1kkm\202\377\377\377\1\376" \ + "\376\376\220\377\377\377\1\376\376\376\202\377\377\377\5\376\376\376" \ + "\266\266\26699;;;=::<\202;;=\3::<GGG\332\332\332\207\377\377\377\2\376" \ + "\376\376\204\204\206\202;;=\4::<;;=::<SSU\252\377\377\377\2\376\376\376" \ + "\346\346\350\202::<\5;;=::<99;;;;\266\266\266\203\377\377\377\1\376\376" \ + "\376\205\377\377\377\3\235\235\235::<99;\220::<\1;;=\205::<\203;;=\1" \ + "99;\203::<\3SSS\221\221\221\316\316\316\205\377\377\377\1\376\376\376" \ + "\222\377\377\377\1\376\376\376\203\377\377\377\3\234\234\236::<;;=\232" \ + "::<\7""99;::<;:\77::<;;=99;\317\317\321\230\377\377\377\7\377\375\377" \ + "\214\306<\213\307A\215\305>\215\307\77\212\307>\216\306\77\241\214\306" \ + ">\1\215\306C\202\215\305@\5\212\306@\215\307=\343\361\320\377\377\377" \ + "\377\376\377\210\377\377\377\210\214\306>\10\215\305<\215\307\77\216" \ + "\306\77\214\306>\216\305C\252\324r\377\377\377\377\377\373\211\377\377" \ + "\377\7\375\377\376\377\377\377\377\375\376\343\361\316\215\307=\212\307" \ + ">\215\305>\210\214\306>\10\214\305@\215\305<\342\362\316\377\377\375" \ + "\377\376\377\375\377\374\376\376\377\376\377\377\222\377\377\377\1\375" \ + "\377\372\202\377\377\377\3\377\376\377\304\341\237\215\307\77\210\214" \ + "\306>\10\212\307;\215\307\77\213\305=\305\342\240\377\377\377\377\376" \ + "\374\377\377\375\376\377\377\221\377\377\377\22\377\376\377\377\377\375" \ + "\376\377\377\377\375\376\361\367\351\270\334\204\214\306>\215\307\77" \ + "\214\305@\212\306@\213\307A\212\306@\213\310\77\214\306>\215\304B\214" \ + "\306>\212\307<\214\306>\202\216\306A\6\214\306>\213\310\77\214\305@\215" \ + "\305<\215\305>\215\307=\202\213\310\77\10\215\306A\214\306>\215\306A" \ + "\222\311I\300\336\226\361\370\346\376\376\376\377\377\377\202\377\376" \ + "\377\1\376\377\373\217\377\377\377\10\377\377\375\347\365\333\214\307" \ + ";\211\305A\213\304\77\215\307\77\215\305<\213\310\77\202\214\306>\1\215" \ + "\307\77\203\214\306>\4\215\307\77\214\306>\215\306A\275\337\223\202\377" \ + "\377\377\5\377\376\377\377\377\377\376\377\375\377\376\377\376\377\377" \ + "\220\377\377\377\10\375\377\376\331\357\301\215\307\77\215\305>\216\305" \ + "C\211\306=\220\305A\211\307@\210\214\306>\10\214\305@\246\321e\377\377" \ + "\377\377\376\377\376\377\377\377\377\375\376\377\377\377\376\377\227" \ + "\377\377\377\1\376\376\376\202\377\377\377\3\363\363\363\266\266\270" \ + "__a\207::<\202;;=\203::<\2;;=99;\202;;=\2""99;::<\202;;=\1::<\203;;=" \ + "\3^^^\250\250\250\363\363\363\203\377\377\377\1\376\376\376\202\377\377" \ + "\377\1\376\376\376\224\377\377\377\4\316\316\316999::<;;=\202::<\1ll" \ + "l\205\377\377\377\1\376\376\376\217\377\377\377\6\376\376\376\377\377" \ + "\377\376\376\376\204\204\204::<;;=\203::<\3:::TTT\363\363\363\206\377" \ + "\377\377\10\347\347\347;;;99;::<;;=::<:::\234\234\236\253\377\377\377" \ + "\3\376\376\376lln;;=\202::<\3;;=999SSS\202\377\377\377\1\376\376\376" \ + "\203\377\377\377\4\376\376\376\377\377\377\376\376\376\234\234\234\223" \ + "::<\1""99;\202::<\1;;=\203::<\5kkmxxz\235\235\237\301\301\301\346\346" \ + "\346\207\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\221" \ + "\377\377\377\1\376\376\376\202\377\377\377\3\235\235\235::<;;=\232::" \ + "<\2;;=99;\202::<\3;;=::<\316\316\316\230\377\377\377\10\373\377\376\216" \ + "\306A\214\306<\213\304A\212\306@\214\305@\214\304\77\215\307\77\240\214" \ + "\306>\6\214\306<\215\306A\215\305@\216\310@\217\304@\341\361\314\212" \ + "\377\377\377\210\214\306>\7\215\307\77\213\310\77\213\305=\215\307\77" \ + "\214\304\77\253\323r\374\377\373\211\377\377\377\1\377\376\377\203\377" \ + "\377\377\3\342\362\315\215\305@\215\307=\211\214\306>\10\214\306<\215" \ + "\304B\341\363\313\374\377\375\376\376\377\377\377\377\377\375\376\377" \ + "\377\375\221\377\377\377\7\376\377\375\376\376\377\377\377\377\375\377" \ + "\374\377\377\377\377\377\375\253\323p\210\214\306>\5\215\307\77\215\305" \ + ">\217\304@\305\342\237\376\377\375\202\377\377\377\1\377\377\375\220" \ + "\377\377\377\1\376\377\377\202\377\376\377\202\376\377\375\202\377\377" \ + "\377\5\360\370\351\311\347\247\245\320e\215\305>\212\307>\202\214\306" \ + ">\5\215\306A\212\307>\215\305@\214\306>\214\306<\202\214\306>\2\214\306" \ + "<\214\306>\202\216\306A\14\214\306>\215\306A\215\305<\214\306>\213\305" \ + "=\255\331x\323\353\267\366\374\362\377\377\377\377\377\375\377\377\377" \ + "\376\377\377\217\377\377\377\2\376\376\376\377\377\377\202\377\377\375" \ + "\11\244\317d\214\306>\213\307A\214\306>\214\305@\214\306>\215\306A\214" \ + "\306<\215\307\77\202\214\306>\202\214\305@\13\215\305<\215\305@\230\316" \ + "V\370\373\360\376\377\375\377\377\377\377\376\377\376\376\376\377\377" \ + "\375\377\376\377\376\377\377\220\377\377\377\10\376\376\376\377\376\377" \ + "\262\327x\214\306>\216\306A\215\307=\215\305<\215\306A\211\214\306>\6" \ + "\215\306C\307\341\240\376\377\373\376\377\377\376\377\375\376\376\374" \ + "\236\377\377\377\4\346\346\350\266\266\270\204\204\206SSU\202::<\1;;" \ + "=\202::<\1;;=\202::<\202;;=\3""99;::<;;=\203::<\4GGIxxz\247\247\247\347" \ + "\347\347\212\377\377\377\1\376\376\376\223\377\377\377\1\364\364\364" \ + "\205\316\316\316\1\332\332\332\203\377\377\377\202\376\376\376\221\377" \ + "\377\377\1\376\376\376\202\377\377\377\202\316\316\316\203\316\316\320" \ + "\3\316\316\316\317\317\317\346\346\346\206\377\377\377\5\346\346\346" \ + "\316\316\316\317\317\317\316\316\316\315\315\315\202\316\316\316\1\363" \ + "\363\363\250\377\377\377\1\376\376\376\203\377\377\377\3\346\346\346" \ + "\315\315\315\317\317\317\202\316\316\320\3\317\317\317\315\315\315\363" \ + "\363\363\202\377\377\377\202\376\376\376\204\377\377\377\3\346\346\346" \ + "\316\316\316\316\316\320\224\316\316\316\1\315\315\315\203\377\377\377" \ + "\1\376\376\376\215\377\377\377\1\376\376\376\225\377\377\377\2\346\346" \ + "\346\317\317\317\232\316\316\316\1\317\317\317\203\316\316\316\4\317" \ + "\317\317\315\315\315\316\316\316\363\363\363\231\377\377\377\3\340\361" \ + "\317\342\360\317\342\362\316\202\343\361\316\2\342\360\315\343\361\316" \ + "\240\342\361\320\10\342\362\316\342\361\320\343\363\317\341\360\317\342" \ + "\361\320\370\373\364\376\377\375\376\377\377\210\377\377\377\210\342" \ + "\361\320\7\341\360\317\342\362\316\343\361\316\342\360\314\342\361\320" \ + "\350\364\336\377\376\374\211\377\377\377\10\377\376\377\377\377\375\377" \ + "\377\377\377\377\375\370\373\362\341\360\321\340\357\316\342\362\316" \ + "\210\342\361\320\3\342\362\316\342\361\320\371\373\360\203\377\377\377" \ + "\202\377\376\377\220\377\377\377\4\377\377\375\376\376\376\377\376\377" \ + "\376\377\375\203\377\377\377\1\365\375\362\210\342\361\320\4\341\360" \ + "\321\342\361\322\343\363\317\360\367\345\224\377\377\377\7\376\377\377" \ + "\376\377\375\377\377\375\377\376\377\377\377\375\377\375\376\377\376" \ + "\377\202\377\377\377\30\376\376\377\364\370\351\333\354\277\277\337\224" \ + "\247\324k\224\313K\214\305@\214\306>\212\306@\214\306>\214\305B\215\306" \ + "C\215\307\77\212\306@\214\306>\215\307\77\241\321c\257\330|\304\342\242" \ + "\341\361\315\377\377\377\377\376\377\376\377\373\377\377\377\202\377" \ + "\377\375\1\377\376\377\203\377\377\377\1\376\377\377\212\377\377\377" \ + "\1\376\376\376\203\377\377\377\13\376\376\374\372\372\370\342\361\320" \ + "\343\361\316\342\362\316\341\360\317\342\361\320\341\360\317\342\362" \ + "\316\342\361\322\342\361\320\202\341\361\315\6\342\361\320\341\360\317" \ + "\343\361\315\343\361\320\356\371\350\377\376\377\203\377\377\377\1\376" \ + "\377\375\202\377\377\377\1\376\377\375\222\377\377\377\6\366\373\364" \ + "\342\361\320\342\362\316\342\360\317\341\362\316\343\361\320\210\342" \ + "\361\320\10\341\362\316\341\361\315\352\364\334\377\377\377\377\376\377" \ + "\377\377\377\376\377\377\376\377\375\222\377\377\377\202\376\376\376" \ + "\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377" \ + "\377\377\3\376\376\376\377\377\377\375\375\375\202\377\377\377\5\363" \ + "\363\363\316\316\316\264\264\264\235\235\235\233\233\233\202kkk\202k" \ + "km\3llnkkmyy{\202\234\234\236\6\316\316\320\346\346\346\377\377\377\376" \ + "\376\376\377\377\377\376\376\376\204\377\377\377\1\376\376\376\204\377" \ + "\377\377\1\376\376\376\240\377\377\377\1\376\376\376\231\377\377\377" \ + "\1\375\375\375\203\377\377\377\1\376\376\376\214\377\377\377\1\376\376" \ + "\376\202\377\377\377\1\376\376\376\242\377\377\377\1\376\376\376\206" \ + "\377\377\377\3\376\376\376\377\377\377\376\376\376\204\377\377\377\1" \ + "\376\376\376\202\377\377\377\202\376\376\376\225\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\202\377\377\377\3\376\376\376\377\377\377" \ + "\376\376\376\214\377\377\377\3\376\376\376\377\377\377\376\376\376\265" \ + "\377\377\377\1\375\375\375\234\377\377\377\7\376\377\377\377\376\377" \ + "\376\377\377\376\376\374\377\376\377\377\377\377\377\377\375\240\377" \ + "\377\377\1\377\377\375\202\377\377\377\5\377\376\377\376\376\376\377" \ + "\376\377\376\376\377\377\377\375\221\377\377\377\7\375\376\377\377\377" \ + "\377\377\376\377\377\377\375\376\377\377\377\377\373\377\376\377\210" \ + "\377\377\377\5\377\376\377\377\377\377\376\376\374\376\377\377\377\377" \ + "\377\202\377\377\375\1\376\377\377\210\377\377\377\6\376\377\377\375" \ + "\376\377\377\376\377\377\377\377\376\377\377\377\377\377\202\377\377" \ + "\375\224\377\377\377\202\377\376\377\2\374\377\377\377\376\377\210\377" \ + "\377\377\3\376\377\377\376\376\376\376\377\377\202\377\377\377\3\375" \ + "\377\376\377\377\377\377\376\377\220\377\377\377\202\377\376\377\2\376" \ + "\377\377\375\376\377\202\377\377\377\4\377\377\375\377\376\377\377\377" \ + "\377\377\377\375\202\376\377\377\7\377\377\377\377\376\377\377\377\377" \ + "\376\377\375\370\373\364\344\357\315\342\361\320\202\342\362\315\14\340" \ + "\357\316\345\360\316\376\377\373\376\376\376\377\377\377\377\375\376" \ + "\377\377\375\377\377\377\375\377\376\377\377\377\377\376\377\377\377" \ + "\375\202\376\377\375\5\376\377\377\377\377\377\377\377\375\376\376\376" \ + "\377\376\377\214\377\377\377\1\376\376\376\202\377\377\377\5\377\377" \ + "\375\376\375\377\377\377\377\376\376\377\377\377\375\204\377\377\377" \ + "\1\377\377\375\205\377\377\377\202\377\376\377\2\377\377\377\377\377" \ + "\375\202\377\377\377\202\376\377\377\222\377\377\377\5\377\377\375\377" \ + "\377\377\377\377\375\377\377\377\377\377\375\202\377\377\377\1\377\376" \ + "\372\212\377\377\377\1\377\375\377\202\377\377\377\3\377\376\377\377" \ + "\377\377\377\377\375\225\377\377\377\1\376\376\376\211\377\377\377\1" \ + "\376\376\376\204\377\377\377\1\376\376\376\205\377\377\377\1\376\376" \ + "\376\206\377\377\377\3\376\376\376\377\377\377\376\376\376\206\377\377" \ + "\377\1\376\376\376\233\377\377\377\1\376\376\376\203\377\377\377\5\376" \ + "\376\376\377\377\377\376\376\376\377\377\377\376\376\376\223\377\377" \ + "\377\3\376\376\376\377\377\377\376\376\376\205\377\377\377\3\376\376" \ + "\376\377\377\377\376\376\376\203\377\377\377\3\376\376\376\377\377\377" \ + "\376\376\376\203\377\377\377\1\376\376\376\205\377\377\377\1\376\376" \ + "\376\246\377\377\377\3\376\376\376\377\377\377\376\376\376\220\377\377" \ + "\377\1\376\376\376\246\377\377\377\1\376\376\376\225\377\377\377\1\376" \ + "\376\376\202\377\377\377\1\376\376\376\240\377\377\377\1\376\376\376" \ + "\230\377\377\377\6\377\377\375\377\377\377\377\376\377\376\377\375\374" \ + "\377\377\376\375\377\242\377\377\377\202\377\376\377\6\376\376\376\375" \ + "\376\377\377\377\377\377\377\375\377\377\377\376\377\375\220\377\377" \ + "\377\7\377\377\375\377\377\377\377\377\375\377\375\376\376\377\375\376" \ + "\377\377\376\376\376\212\377\377\377\4\377\376\377\377\377\375\377\377" \ + "\377\377\377\375\203\377\376\377\210\377\377\377\5\377\377\375\377\377" \ + "\377\377\375\376\377\376\377\377\377\375\202\377\377\377\1\376\377\377" \ + "\221\377\377\377\1\375\376\377\203\377\377\375\2\376\377\375\377\375" \ + "\376\211\377\377\377\204\377\376\377\4\377\377\377\376\377\375\377\377" \ + "\375\377\376\377\221\377\377\377\5\376\377\377\376\376\376\377\377\373" \ + "\376\376\377\376\377\377\202\377\377\377\2\377\376\377\377\377\375\202" \ + "\377\377\377\7\377\377\375\377\376\377\376\376\377\377\377\377\376\377" \ + "\377\376\377\375\376\377\377\202\377\377\377\203\376\377\377\2\377\377" \ + "\377\376\376\374\202\377\376\377\13\376\376\376\377\377\375\377\377\377" \ + "\377\375\376\376\377\377\377\377\377\376\376\377\377\376\377\376\376" \ + "\374\376\377\377\377\377\375\221\377\377\377\203\377\377\375\4\377\377" \ + "\377\377\377\375\377\376\377\376\376\376\210\377\377\377\1\377\377\373" \ + "\203\377\377\377\1\377\377\375\202\376\377\377\222\377\377\377\1\377" \ + "\377\375\202\377\376\377\3\377\377\377\377\376\377\377\376\374\202\376" \ + "\377\377\210\377\377\377\4\377\377\375\377\377\377\376\377\375\377\375" \ + "\377\202\376\377\377\1\377\376\375\227\377\377\377\1\376\376\376\207" \ + "\377\377\377\1\376\376\376\217\377\377\377\1\376\376\376\205\377\377" \ + "\377\1\376\376\376\204\377\377\377\1\376\376\376\233\377\377\377\1\376" \ + "\376\376\211\377\377\377\1\376\376\376\222\377\377\377\1\376\376\376" \ + "\206\377\377\377\1\376\376\376\207\377\377\377\1\376\376\376\262\377" \ + "\377\377\1\376\376\376\212\377\377\377\1\376\376\376\202\377\377\377" \ + "\1\376\376\376\202\377\377\377\1\376\376\376\225\377\377\377\1\376\376" \ + "\376\306\377\377\377\1\376\376\376\235\377\377\377\7\377\376\377\376" \ + "\377\377\377\377\377\377\377\375\376\375\377\377\377\375\377\376\377" \ + "\241\377\377\377\1\376\377\377\203\377\377\377\3\377\377\375\377\375" \ + "\376\377\376\377\221\377\377\377\202\376\377\377\5\377\377\377\377\377" \ + "\375\377\377\377\377\376\377\377\377\375\211\377\377\377\203\377\377" \ + "\375\202\377\377\377\202\376\377\377\1\377\377\375\212\377\377\377\202" \ + "\376\377\375\3\376\377\377\377\377\375\377\376\377\223\377\377\377\6" \ + "\377\377\375\377\376\377\374\377\377\377\377\377\377\376\377\376\377" \ + "\375\210\377\377\377\3\377\377\375\376\377\377\377\377\375\202\377\377" \ + "\377\1\377\377\375\223\377\377\377\4\376\376\376\377\377\375\376\376" \ + "\376\377\376\377\202\377\377\375\1\376\376\376\206\377\377\377\1\377" \ + "\377\375\215\377\377\377\1\377\377\375\202\377\377\377\5\376\377\377" \ + "\377\377\377\376\376\374\377\377\377\377\376\377\202\377\377\377\1\376" \ + "\376\376\221\377\377\377\7\376\377\375\377\375\377\377\377\377\376\377" \ + "\377\377\377\377\377\377\373\377\376\377\202\377\377\377\1\377\377\375" \ + "\202\377\377\377\1\377\377\375\204\377\377\377\6\376\376\377\377\377" \ + "\375\376\377\377\377\377\375\377\376\377\375\377\374\222\377\377\377" \ + "\3\376\377\375\377\377\377\376\377\375\203\376\377\377\1\377\376\377" \ + "\211\377\377\377\7\377\377\373\377\376\377\377\377\375\377\377\377\377" \ + "\376\377\376\376\376\376\377\377") + + diff --git a/recipes-core/psplash/files/psplash-portrait.conf b/recipes-core/psplash/files/psplash-portrait.conf new file mode 100644 index 00000000..d74f9779 --- /dev/null +++ b/recipes-core/psplash/files/psplash-portrait.conf @@ -0,0 +1,2 @@ +[Service] +Environment=PSPLASH_ANGLE_ARGS='--angle 90' diff --git a/recipes-core/psplash/psplash-inverted-config.bb b/recipes-core/psplash/psplash-inverted-config.bb new file mode 100644 index 00000000..f11b255d --- /dev/null +++ b/recipes-core/psplash/psplash-inverted-config.bb @@ -0,0 +1,20 @@ +SUMMARY = "Systemd unit override for psplash inverted mode for the AGL Demonstrator" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd allarch + +SRC_URI = "file://psplash-inverted.conf" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + # Install override + install -d ${D}${systemd_system_unitdir}/psplash-start.service.d + install -m 0644 ${WORKDIR}/psplash-inverted.conf ${D}${systemd_system_unitdir}/psplash-start.service.d/ +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "psplash" diff --git a/recipes-core/psplash/psplash-portrait-config.bb b/recipes-core/psplash/psplash-portrait-config.bb new file mode 100644 index 00000000..7afee442 --- /dev/null +++ b/recipes-core/psplash/psplash-portrait-config.bb @@ -0,0 +1,20 @@ +SUMMARY = "Systemd unit override for psplash portrait mode for the AGL Demonstrator" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd allarch + +SRC_URI = "file://psplash-portrait.conf" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + # Install override + install -d ${D}${systemd_system_unitdir}/psplash-start.service.d + install -m 0644 ${WORKDIR}/psplash-portrait.conf ${D}${systemd_system_unitdir}/psplash-start.service.d/ +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "psplash" diff --git a/recipes-core/psplash/psplash_agldemo.inc b/recipes-core/psplash/psplash_agldemo.inc new file mode 100644 index 00000000..cc5b5b7b --- /dev/null +++ b/recipes-core/psplash/psplash_agldemo.inc @@ -0,0 +1,20 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI:append = " \ + file://psplash-colors.h \ + file://psplash-args.conf \ +" + +SPLASH_IMAGES = "file://psplash-poky-img.h;outsuffix=default" + +do_configure:append () { + cp -f ${WORKDIR}/psplash-colors.h ${S} +} + +do_install:append () { + # Install override + install -d ${D}${systemd_system_unitdir}/psplash-start.service.d + install -m 0644 ${WORKDIR}/psplash-args.conf ${D}${systemd_system_unitdir}/psplash-start.service.d/ +} + +FILES:${PN} += "${systemd_system_unitdir}" diff --git a/recipes-core/psplash/psplash_git.bbappend b/recipes-core/psplash/psplash_git.bbappend new file mode 100644 index 00000000..931b27c7 --- /dev/null +++ b/recipes-core/psplash/psplash_git.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'psplash_agldemo.inc', '', d)} diff --git a/recipes-core/udev/demo-i2c-udev-conf/99-agl-led-rtc.rules b/recipes-core/udev/demo-i2c-udev-conf/99-agl-led-rtc.rules index 34fa0678..f406646a 100644 --- a/recipes-core/udev/demo-i2c-udev-conf/99-agl-led-rtc.rules +++ b/recipes-core/udev/demo-i2c-udev-conf/99-agl-led-rtc.rules @@ -6,7 +6,7 @@ ACTION=="add", ENV{DEVTYPE}=="usb_interface", ENV{DRIVER}=="i2c-tiny-usb", RUN+= ACTION=="add", ENV{DEVTYPE}=="usb_interface", ENV{DRIVER}=="i2c-tiny-usb", RUN+="/usr/bin/logger 'Loading rtc driver'", RUN+="/sbin/modprobe rtc-ds1307" # %k is the blinkm i2c device e.g. 6-0009 -ACTION=="add", ENV{DRIVER}=="blinkm", SUBSYSTEM=="i2c", RUN+="/usr/bin/logger 'the blinkm device is %k'", TAG+="systemd", ENV{SYSTEMD_WANTS}="hvac-json-in-rewrite@%k.service", GOTO="very_end" +ACTION=="add", ENV{DRIVER}=="blinkm", SUBSYSTEM=="i2c", RUN+="/usr/bin/logger 'the blinkm device is %k'", TAG+="systemd", ENV{SYSTEMD_WANTS}="hvac-conf-in-rewrite@%k.service", GOTO="very_end" # FIXME: We do not exclude the blinkm on the next lines, yet. The rule is too broad, but that is all we know already. Above is actually later in time. # For now this is not critical as the rtc init will just fail and we're done. diff --git a/recipes-core/udev/demo-i2c-udev-conf/agl-service-hvac-leds.conf.in b/recipes-core/udev/demo-i2c-udev-conf/agl-service-hvac-leds.conf.in new file mode 100644 index 00000000..b4f2eb77 --- /dev/null +++ b/recipes-core/udev/demo-i2c-udev-conf/agl-service-hvac-leds.conf.in @@ -0,0 +1,4 @@ +[leds] +red = "/sys/class/leds/blinkm-@DEVICE@-red/brightness" +green = "/sys/class/leds/blinkm-@DEVICE@-green/brightness" +blue = "/sys/class/leds/blinkm-@DEVICE@-blue/brightness" diff --git a/recipes-core/udev/demo-i2c-udev-conf/hvac-json-in-rewrite.sh b/recipes-core/udev/demo-i2c-udev-conf/hvac-conf-in-rewrite.sh index 55576601..c1e08f1c 100755 --- a/recipes-core/udev/demo-i2c-udev-conf/hvac-json-in-rewrite.sh +++ b/recipes-core/udev/demo-i2c-udev-conf/hvac-conf-in-rewrite.sh @@ -1,17 +1,19 @@ #!/bin/bash - +# SPDX-License-Identifier: Apache-2.0 # (C) 2018 Jan-Simon Möller, dl9pf@gmx.de, jsmoeller@linuxfoundation.org -# License: Apache License 2.0 +# (C) 2022 Scott Murray <scott.murray@konsulko.com> #set -x set -e +TARGET="/etc/xdg/AGL/agl-service-hvac-leds.conf" + if [ $1 ] ; then # The device is always 0009 -> 9 . Only change is the i2c IF . LED=`echo $1 | sed -e "s#0009#9#g"` if [ $? -eq 0 ] ; then echo "$LED" - sed -e "s#@DEVICE@#$LED#" /etc/hvac.json.in > /etc/hvac.json + sed -e "s#@DEVICE@#$LED#" ${TARGET}.in > ${TARGET} else echo "Invalid argument" exit 1 @@ -19,4 +21,4 @@ if [ $1 ] ; then else echo "Need argument" exit 1 -fi
\ No newline at end of file +fi diff --git a/recipes-core/udev/demo-i2c-udev-conf/hvac-conf-in-rewrite@.service b/recipes-core/udev/demo-i2c-udev-conf/hvac-conf-in-rewrite@.service new file mode 100644 index 00000000..e6e0c1d6 --- /dev/null +++ b/recipes-core/udev/demo-i2c-udev-conf/hvac-conf-in-rewrite@.service @@ -0,0 +1,8 @@ +[Unit] +Description=AGL hvac LED write agl-service-hvac-leds.conf +Before=agl-service-hvac.service + +[Service] +Type=oneshot +ExecStartPre=/usr/bin/logger '#hvac i2c device has been attached - %i' +ExecStart=/usr/sbin/hvac-conf-in-rewrite.sh %i diff --git a/recipes-core/udev/demo-i2c-udev-conf/hvac-json-in-rewrite@.service b/recipes-core/udev/demo-i2c-udev-conf/hvac-json-in-rewrite@.service deleted file mode 100644 index 2fb09959..00000000 --- a/recipes-core/udev/demo-i2c-udev-conf/hvac-json-in-rewrite@.service +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=AGL hvac LED write /etc/hvac.json -#Before= todo: add dependency of hvac service ? - -[Service] -Type=oneshot -ExecStartPre=/usr/bin/logger '#hvac i2c device has been attached - %i' -ExecStart=/usr/sbin/hvac-json-in-rewrite.sh %i diff --git a/recipes-core/udev/demo-i2c-udev-conf/hvac.json.in b/recipes-core/udev/demo-i2c-udev-conf/hvac.json.in deleted file mode 100644 index 01541a60..00000000 --- a/recipes-core/udev/demo-i2c-udev-conf/hvac.json.in +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ledtemp": { - "red": "/sys/class/leds/blinkm-@DEVICE@-red/brightness", - "green": "/sys/class/leds/blinkm-@DEVICE@-green/brightness", - "blue": "/sys/class/leds/blinkm-@DEVICE@-blue/brightness" - } -} diff --git a/recipes-core/udev/demo-i2c-udev-conf_1.0.bb b/recipes-core/udev/demo-i2c-udev-conf_1.0.bb index 04101cf3..7707df60 100644 --- a/recipes-core/udev/demo-i2c-udev-conf_1.0.bb +++ b/recipes-core/udev/demo-i2c-udev-conf_1.0.bb @@ -2,27 +2,27 @@ SUMMARY = "USB attached I2C demo hardware udev configuration" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" -SRC_URI = "file://hvac-json-in-rewrite.sh \ +SRC_URI = "file://hvac-conf-in-rewrite.sh \ file://rtc-i2c-attach.sh \ - file://hvac-json-in-rewrite@.service \ + file://hvac-conf-in-rewrite@.service \ file://rtc-i2c-attach@.service \ file://99-agl-led-rtc.rules \ - file://hvac.json.in \ + file://agl-service-hvac-leds.conf.in \ " do_compile[noexec] = "1" do_install() { - install -d ${D}${sysconfdir} - install -m 0644 ${WORKDIR}/hvac.json.in ${D}${sysconfdir} + install -d ${D}${sysconfdir}/xdg/AGL + install -m 0644 ${WORKDIR}/agl-service-hvac-leds.conf.in ${D}${sysconfdir}/xdg/AGL install -d ${D}${sbindir} - install -m 0755 ${WORKDIR}/hvac-json-in-rewrite.sh ${D}${sbindir} + install -m 0755 ${WORKDIR}/hvac-conf-in-rewrite.sh ${D}${sbindir} install -m 0755 ${WORKDIR}/rtc-i2c-attach.sh ${D}${sbindir} if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/hvac-json-in-rewrite@.service ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/hvac-conf-in-rewrite@.service ${D}${systemd_system_unitdir} install -m 0644 ${WORKDIR}/rtc-i2c-attach@.service ${D}${systemd_system_unitdir} install -d ${D}${sysconfdir}/udev/rules.d @@ -30,6 +30,6 @@ do_install() { fi } -FILES_${PN} += "${systemd_unitdir}" +FILES:${PN} += "${systemd_unitdir}" -RDEPENDS_${PN} += "bash" +RDEPENDS:${PN} += "bash" diff --git a/recipes-core/udev/output-udev-conf/91-output.rules b/recipes-core/udev/output-udev-conf/91-output.rules new file mode 100644 index 00000000..9b09a7ca --- /dev/null +++ b/recipes-core/udev/output-udev-conf/91-output.rules @@ -0,0 +1,6 @@ +# Associate all input devices with the first display +# +# NOTE: Can be more selective with something like: +# SUBSYSTEM=="input", ATTRS{idVendor}=="*", ATTRS{idProduct}=="004a", OWNER="agl-driver", ENV{ID_SEAT}="seat0", ENV{WL_OUTPUT}="HDMI-A-1" +# +SUBSYSTEM=="input", ENV{ID_SEAT}="seat0", ENV{WL_OUTPUT}="HDMI-A-1" diff --git a/recipes-core/udev/output-udev-conf_1.0.bb b/recipes-core/udev/output-udev-conf_1.0.bb new file mode 100644 index 00000000..c4e05ad0 --- /dev/null +++ b/recipes-core/udev/output-udev-conf_1.0.bb @@ -0,0 +1,18 @@ +SUMMARY = "Input device output assignment udev configuration" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = "file://91-output.rules" + +do_compile[noexec] = "1" + +do_install() { + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -d ${D}${sysconfdir}/udev/rules.d + install -m 0644 ${WORKDIR}/91-output.rules ${D}${sysconfdir}/udev/rules.d/ + fi +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "udev" diff --git a/recipes-core/udev/sw-gpsd-udev-conf/60-sw-gpsd.rules b/recipes-core/udev/sw-gpsd-udev-conf/60-sw-gpsd.rules new file mode 100644 index 00000000..a5547003 --- /dev/null +++ b/recipes-core/udev/sw-gpsd-udev-conf/60-sw-gpsd.rules @@ -0,0 +1,8 @@ +# udev rules for gpsd for Sierra Wireless modems +SUBSYSTEM!="tty", GOTO="sw_gpsd_rules_end" + +ENV{ID_VENDOR_ID}=="1199", ATTRS{bInterfaceNumber}=="02", SYMLINK+="gps%n", TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service" + +ACTION=="remove", TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service" + +LABEL="sw_gpsd_rules_end" diff --git a/recipes-core/udev/sw-gpsd-udev-conf_1.0.bb b/recipes-core/udev/sw-gpsd-udev-conf_1.0.bb new file mode 100644 index 00000000..bcad0f41 --- /dev/null +++ b/recipes-core/udev/sw-gpsd-udev-conf_1.0.bb @@ -0,0 +1,16 @@ +SUMMARY = "Sierra-Wireless MC7xxx modem gpsd udev configuration" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = "file://60-sw-gpsd.rules" + +do_compile[noexec] = "1" + +do_install() { + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -d ${D}${sysconfdir}/udev/rules.d + install -m 0644 ${WORKDIR}/60-sw-gpsd.rules ${D}${sysconfdir}/udev/rules.d/ + fi +} + +RDEPENDS:${PN} += "udev" diff --git a/recipes-core/udev/usb-can-udev-conf/60-usb-can.rules b/recipes-core/udev/usb-can-udev-conf/60-usb-can.rules new file mode 100644 index 00000000..3aa800a8 --- /dev/null +++ b/recipes-core/udev/usb-can-udev-conf/60-usb-can.rules @@ -0,0 +1,7 @@ +# udev rules for USB CAN adapters +SUBSYSTEM!="tty", GOTO="usb_can_rules_end" + +# VScom USB-CAN Plus +ATTRS{idProduct}=="6015", ATTRS{idVendor}=="0403", SYMLINK+="usbcan%n", TAG+="systemd", ENV{SYSTEMD_WANTS}="slcand@%k.service" + +LABEL="usb_can_rules_end" diff --git a/recipes-core/udev/usb-can-udev-conf/slcand-default b/recipes-core/udev/usb-can-udev-conf/slcand-default new file mode 100644 index 00000000..a86552fd --- /dev/null +++ b/recipes-core/udev/usb-can-udev-conf/slcand-default @@ -0,0 +1,2 @@ +# Defaults for VScom USB-CAN Plus @ 500 Kb/s CAN rate +SLCAND_OPTS="-o -s6 -t hw -S 3000000" diff --git a/recipes-core/udev/usb-can-udev-conf/slcand@.service b/recipes-core/udev/usb-can-udev-conf/slcand@.service new file mode 100644 index 00000000..3c30e51b --- /dev/null +++ b/recipes-core/udev/usb-can-udev-conf/slcand@.service @@ -0,0 +1,13 @@ +[Unit] +Description=Serial CAN daemon (can-utils) +BindsTo=dev-%i.device +After=dev-%i.device + +[Service] +Type=forking +StopWhenUnneeded=yes +Environment=SLCAND_OPTS="-o -c -s6" SLCAND_DEV=can0 +EnvironmentFile=-/etc/default/slcand +EnvironmentFile=-/etc/sysconfig/slcand +ExecStart=/usr/bin/slcand $SLCAND_OPTS %I $SLCAND_DEV +ExecStartPost=/bin/sh -c '/bin/sleep 3; /sbin/ip link set $SLCAND_DEV up' diff --git a/recipes-core/udev/usb-can-udev-conf_1.0.bb b/recipes-core/udev/usb-can-udev-conf_1.0.bb new file mode 100644 index 00000000..1b76550d --- /dev/null +++ b/recipes-core/udev/usb-can-udev-conf_1.0.bb @@ -0,0 +1,25 @@ +SUMMARY = "USB CAN adapter udev configuration" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = "file://60-usb-can.rules \ + file://slcand@.service \ + file://slcand-default \ +" + +do_compile[noexec] = "1" + +do_install() { + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -d ${D}${sysconfdir}/udev/rules.d + install -m 0644 ${WORKDIR}/60-usb-can.rules ${D}${sysconfdir}/udev/rules.d/ + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/slcand@.service ${D}${systemd_system_unitdir}/ + install -d ${D}${sysconfdir}/default + install -m 0644 ${WORKDIR}/slcand-default ${D}${sysconfdir}/default/slcand + fi +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "udev" diff --git a/recipes-demo-hmi/alexa-viewer/alexa-viewer_git.bb b/recipes-demo-hmi/alexa-viewer/alexa-viewer_git.bb deleted file mode 100644 index f98704ee..00000000 --- a/recipes-demo-hmi/alexa-viewer/alexa-viewer_git.bb +++ /dev/null @@ -1,33 +0,0 @@ -SUMMARY = "Demo voice capabilities template viewer for Alexa voiceagent" -DESCRIPTION = "Demo voice capabilities template viewer for Alexa voiceagent" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/alexa-viewer" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -DEPENDS = " \ - qtquickcontrols2 \ - qlibwindowmanager \ - qlibhomescreen \ - af-binder \ - libqtappfw \ -" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/alexa-viewer;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -inherit cmake_qt5 aglwgt - -OECMAKE_CXX_FLAGS_append = " ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', '' , '-DQT_NO_DEBUG_OUTPUT', d)}" - -RDEPENDS_${PN} = " \ - libqtappfw \ - libafbwsc \ - qlibwindowmanager \ - qlibhomescreen \ - agl-service-voice-high-capabilities \ -" diff --git a/recipes-demo-hmi/als-meter-demo/als-meter-demo_git.bb b/recipes-demo-hmi/als-meter-demo/als-meter-demo_git.bb deleted file mode 100644 index 6b0e054a..00000000 --- a/recipes-demo-hmi/als-meter-demo/als-meter-demo_git.bb +++ /dev/null @@ -1,21 +0,0 @@ -SUMMARY = "Demo app for streeting-wheel" -DESCRIPTION = "AGL demo app for streeting-wheel" -HOMEPAGE = "http://192.168.160.148/shenhui/als-meter-demo-release" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/als-meter-demo;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "0.1+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2 opencv libhomescreen qlibwindowmanager" - -# runtime dependencies -RDEPENDS_${PN} += "agl-service-steering-wheel" - -inherit qmake5 aglwgt diff --git a/recipes-demo-hmi/controls/controls_git.bb b/recipes-demo-hmi/controls/controls_git.bb deleted file mode 100644 index 1b19759c..00000000 --- a/recipes-demo-hmi/controls/controls_git.bb +++ /dev/null @@ -1,18 +0,0 @@ -SUMMARY = "Controls for CES2017 AGL Demonstration" -DESCRIPTION = "AGL HMI Application for demonstrating UI components on AGL Distribution" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/controls" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/controls;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2" - -inherit qmake5 aglwgt diff --git a/recipes-demo-hmi/dashboard/dashboard_git.bb b/recipes-demo-hmi/dashboard/dashboard_git.bb deleted file mode 100644 index 822207b1..00000000 --- a/recipes-demo-hmi/dashboard/dashboard_git.bb +++ /dev/null @@ -1,23 +0,0 @@ -SUMMARY = "Dashboard for CES2017 AGL Demonstration" -DESCRIPTION = "AGL HMI Application for demonstrating dashboard on AGL Distribution" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/dashboard" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/dashboard;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2 qttools-native qtaglextras libqtappfw" - -inherit qmake5 aglwgt - -RDEPENDS_${PN} += " \ - libqtappfw \ - agl-service-signal-composer \ -" diff --git a/recipes-demo-hmi/homescreen/homescreen_git.bb b/recipes-demo-hmi/homescreen/homescreen_git.bb deleted file mode 100644 index 984e5153..00000000 --- a/recipes-demo-hmi/homescreen/homescreen_git.bb +++ /dev/null @@ -1,31 +0,0 @@ -SUMMARY = "AGL Home Screen Application" -DESCRIPTION = "AGL Home Screen Application build with recipe method" -HOMEPAGE = "http://docs.automotivelinux.org" -LICENSE = "Apache-2.0" -SECTION = "apps" -LIC_FILES_CHKSUM = "file://homescreen/LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -DEPENDS = "\ - qtbase \ - qtdeclarative \ - qtquickcontrols2 \ - agl-service-homescreen \ - agl-service-windowmanager \ - agl-service-weather \ - libqtappfw \ - qlibwindowmanager \ - libhomescreen \ - libafb-helpers-qt \ -" - -inherit qmake5 systemd pkgconfig aglwgt - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/homescreen;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git/" - -PATH_prepend = "${STAGING_DIR_NATIVE}${OE_QMAKE_PATH_QT_BINS}:" - -OE_QMAKE_CXXFLAGS_append = " ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', '' , '-DQT_NO_DEBUG_OUTPUT', d)}" diff --git a/recipes-demo-hmi/html5-dashboard/html5-dashboard_git.bb b/recipes-demo-hmi/html5-dashboard/html5-dashboard_git.bb deleted file mode 100644 index 534bd2d3..00000000 --- a/recipes-demo-hmi/html5-dashboard/html5-dashboard_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "AGL HTML5 dashboard Application" -HOMEPAGE = "https://git.automotivelinux.org/apps/html5-dashboard/" -SECTION = "apps" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git/" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-dashboard;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -DEPENDS += " nodejs-native" - -inherit aglwgt - -do_configure() { - cd ${B} - npm install -} - -do_aglwgt_package() { - cd ${B} - npm run build -} diff --git a/recipes-demo-hmi/html5-homescreen/html5-homescreen_git.bb b/recipes-demo-hmi/html5-homescreen/html5-homescreen_git.bb deleted file mode 100644 index 68956263..00000000 --- a/recipes-demo-hmi/html5-homescreen/html5-homescreen_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "AGL HTML5 Homescreen Application" -HOMEPAGE = "https://git.automotivelinux.org/apps/html5-homescreen/" -SECTION = "apps" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git/" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-homescreen;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -DEPENDS += " nodejs-native" - -inherit aglwgt - -do_configure() { - cd ${B} - npm install -} - -do_aglwgt_package() { - cd ${B} - npm run build -} diff --git a/recipes-demo-hmi/html5-hvac/html5-hvac_git.bb b/recipes-demo-hmi/html5-hvac/html5-hvac_git.bb deleted file mode 100644 index d45dc80d..00000000 --- a/recipes-demo-hmi/html5-hvac/html5-hvac_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "AGL HTML5 HVAC Application" -HOMEPAGE = "https://git.automotivelinux.org/apps/html5-hvac/" -SECTION = "apps" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git/" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-hvac;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -DEPENDS += " nodejs-native" - -inherit aglwgt - -do_configure() { - cd ${B} - npm install -} - -do_aglwgt_package() { - cd ${B} - npm run build -} diff --git a/recipes-demo-hmi/html5-launcher/html5-launcher_git.bb b/recipes-demo-hmi/html5-launcher/html5-launcher_git.bb deleted file mode 100644 index ce8a1d11..00000000 --- a/recipes-demo-hmi/html5-launcher/html5-launcher_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "AGL HTML5 Launcher Application" -HOMEPAGE = "https://git.automotivelinux.org/apps/html5-launcher/" -SECTION = "apps" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git/" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-launcher;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -DEPENDS += " nodejs-native" - -inherit aglwgt - -do_configure() { - cd ${B} - npm install -} - -do_aglwgt_package() { - cd ${B} - npm run build -} diff --git a/recipes-demo-hmi/html5-mediaplayer/html5-mediaplayer_git.bb b/recipes-demo-hmi/html5-mediaplayer/html5-mediaplayer_git.bb deleted file mode 100644 index 2b143766..00000000 --- a/recipes-demo-hmi/html5-mediaplayer/html5-mediaplayer_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "AGL HTML5 Mediaplayer Application" -HOMEPAGE = "https://git.automotivelinux.org/apps/html5-mediaplayer/" -SECTION = "apps" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git/" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-mediaplayer;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -DEPENDS += " nodejs-native" - -inherit aglwgt - -do_configure() { - cd ${B} - npm install -} - -do_aglwgt_package() { - cd ${B} - npm run build -} diff --git a/recipes-demo-hmi/html5-mixer/html5-mixer_git.bb b/recipes-demo-hmi/html5-mixer/html5-mixer_git.bb deleted file mode 100644 index babef57c..00000000 --- a/recipes-demo-hmi/html5-mixer/html5-mixer_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "AGL HTML5 Mixer Application" -HOMEPAGE = "https://git.automotivelinux.org/apps/html5-mixer/" -SECTION = "apps" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git/" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-mixer;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -DEPENDS += " nodejs-native" - -inherit aglwgt - -do_configure() { - cd ${B} - npm install -} - -do_aglwgt_package() { - cd ${B} - npm run build -} diff --git a/recipes-demo-hmi/html5-settings/html5-settings_git.bb b/recipes-demo-hmi/html5-settings/html5-settings_git.bb deleted file mode 100644 index dea1ec35..00000000 --- a/recipes-demo-hmi/html5-settings/html5-settings_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "AGL HTML5 Settings Application" -HOMEPAGE = "https://git.automotivelinux.org/apps/html5-settings/" -SECTION = "apps" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git/" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-settings;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -DEPENDS += " nodejs-native" - -inherit aglwgt - -do_configure() { - cd ${B} - npm install -} - -do_aglwgt_package() { - cd ${B} - npm run build -} diff --git a/recipes-demo-hmi/hvac/hvac_git.bb b/recipes-demo-hmi/hvac/hvac_git.bb deleted file mode 100644 index 93e85f45..00000000 --- a/recipes-demo-hmi/hvac/hvac_git.bb +++ /dev/null @@ -1,21 +0,0 @@ -SUMMARY = "HVAC for CES2017 AGL Demonstration" -DESCRIPTION = "AGL HMI Application for demonstrating HVAC on AGL Distribution" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/hvac" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/hvac;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2 libhomescreen \ - qlibwindowmanager qttools-native \ - qtaglextras libqtappfw" -RDEPENDS_${PN} = "agl-service-hvac" - -inherit qmake5 aglwgt diff --git a/recipes-demo-hmi/inputeventmanager/inputeventmanager_git.bb b/recipes-demo-hmi/inputeventmanager/inputeventmanager_git.bb deleted file mode 100644 index 73da4878..00000000 --- a/recipes-demo-hmi/inputeventmanager/inputeventmanager_git.bb +++ /dev/null @@ -1,30 +0,0 @@ -SUMMARY = "AGL InputEventManager Application" -DESCRIPTION = "InputEventManager" -HOMEPAGE = "http://docs.automotivelinux.org" -LICENSE = "Apache-2.0" -SECTION = "apps" -S = "${WORKDIR}/git/" - -inherit qmake5 systemd -DEPENDS = " qtbase " - -LIC_FILES_CHKSUM = "file://inputeventmanager/LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/inputeventmanager.git;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "b2f1646ac78cf61acd66c643b7638bd1b007d5a0" -# PV needs to be modified with SRCPV to work AUTOREV correctly -PV = "0.0+git${SRCPV}" - -PATH_prepend = "${STAGING_DIR_NATIVE}${OE_QMAKE_PATH_QT_BINS}:" - -do_install() { - install -d ${D}/usr/AGL/${PN} - install -m 0755 ${B}/inputeventmanager/InputEventManager ${D}/usr/AGL/${PN}/ - - install -d ${D}${systemd_user_unitdir} - install -m 0644 ${S}/inputeventmanager/conf/InputEventManager.service ${D}${systemd_user_unitdir} -} - -FILES_${PN} += "/usr/AGL/${PN}/ ${systemd_user_unitdir}" -FILES_${PN}-dbg += "/usr/AGL/${PN}/.debug" - diff --git a/recipes-demo-hmi/launcher/launcher_git.bb b/recipes-demo-hmi/launcher/launcher_git.bb deleted file mode 100644 index 8c3f72f6..00000000 --- a/recipes-demo-hmi/launcher/launcher_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "AGL Launcher Application" -DESCRIPTION = "AGL Launcher Application build with recipe method" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/launcher" -SECTION = "apps" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -DEPENDS = "\ - qtbase \ - qtdeclarative \ - qtquickcontrols2 \ - qtwebsockets \ - qlibwindowmanager \ - qlibhomescreen \ -" - -inherit qmake5 systemd pkgconfig aglwgt - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/launcher;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git/" - -PATH_prepend = "${STAGING_DIR_NATIVE}${OE_QMAKE_PATH_QT_BINS}:" diff --git a/recipes-demo-hmi/low-can-demo/low-can-demo_git.bb b/recipes-demo-hmi/low-can-demo/low-can-demo_git.bb deleted file mode 100644 index 707cdde8..00000000 --- a/recipes-demo-hmi/low-can-demo/low-can-demo_git.bb +++ /dev/null @@ -1,19 +0,0 @@ -SUMMARY = "Low CAN demo HTML5 UI" -DESCRIPTION = "AGL HTML5 UI to display car metric (speed, rpm, ...) on AGL Distribution" -HOMEPAGE = "https://github.com/iotbzh/low-can-demo" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" - -SRC_URI = "gitsm://github.com/iotbzh/low-can-demo.git;protocol=https" -SRCREV = "9f0973a50c4d0c797cd63d6dccb8f865ef398b11" - -PV = "4.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# Run-time dependencies -RDEPENDS_${PN} += " agl-service-can-low-level" - -inherit cmake aglwgt - -AGLWGT_AUTOINSTALL_${PN} := "0" diff --git a/recipes-demo-hmi/mediaplayer/mediaplayer_git.bb b/recipes-demo-hmi/mediaplayer/mediaplayer_git.bb deleted file mode 100644 index 9a3690f7..00000000 --- a/recipes-demo-hmi/mediaplayer/mediaplayer_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "Media Player for CES2017 AGL Demonstration" -DESCRIPTION = "AGL HMI Application for demonstrating Media Player on AGL Distribution" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/mediaplayer" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/mediaplayer;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2 \ - qtwebsockets \ - libqtappfw \ - libhomescreen \ - qlibwindowmanager \ -" - -inherit qmake5 aglwgt - -RDEPENDS_${PN} += "agl-service-mediaplayer" diff --git a/recipes-demo-hmi/messaging/messaging_git.bb b/recipes-demo-hmi/messaging/messaging_git.bb deleted file mode 100644 index 5812cea7..00000000 --- a/recipes-demo-hmi/messaging/messaging_git.bb +++ /dev/null @@ -1,24 +0,0 @@ -SUMMARY = "Messaging application for AGL Demonstration" -DESCRIPTION = "AGL HMI Application for demonstrating messaging on AGL Distribution" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/messaging" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/messaging;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2 \ - libqtappfw \ - libhomescreen \ - qlibwindowmanager \ -" - -inherit qmake5 aglwgt - -RDEPENDS_${PN} += "agl-service-bluetooth-map" diff --git a/recipes-demo-hmi/mixer/mixer_git.bb b/recipes-demo-hmi/mixer/mixer_git.bb deleted file mode 100644 index 9524bed6..00000000 --- a/recipes-demo-hmi/mixer/mixer_git.bb +++ /dev/null @@ -1,29 +0,0 @@ -SUMMARY = "Mixer for CES2017 AGL Demonstration" -DESCRIPTION = "AGL HMI application for control of PipeWire mixer elements" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/mixer" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/mixer;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2 \ - qtwebsockets \ - qtaglextras \ - libafb-helpers-qt \ -" - -RDEPENDS_${PN} += "agl-service-audiomixer" - -PROVIDES += "virtual/mixer" -RPROVIDES_${PN} += "virtual/mixer" - -inherit cmake_qt5 aglwgt - -OECMAKE_CXX_FLAGS_append = " ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', '' , '-DQT_NO_DEBUG_OUTPUT', d)}" diff --git a/recipes-demo-hmi/navigation/navigation-demo_git.bb b/recipes-demo-hmi/navigation/navigation-demo_git.bb deleted file mode 100644 index b1d0407f..00000000 --- a/recipes-demo-hmi/navigation/navigation-demo_git.bb +++ /dev/null @@ -1,33 +0,0 @@ -SUMMARY = "Navigation demo based on Qt examples" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/navigation" -SECTION = "apps" - -LICENSE = "BSD-3-Clause & CC0v1" -LIC_FILES_CHKSUM = "file://LICENSE;md5=b6bbd37d85cd2b68082aa7be27853da1 \ - file://LICENSE.for_car_png;md5=65d3616852dbf7b1a6d4b53b00626032 \ - " - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/navigation;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -RPROVIDES_${PN} = "virtual/navigation" - -DEPENDS += "qtquickcontrols2 \ - libhomescreen \ - qlibwindowmanager \ - qtvirtualkeyboard \ - qtlocation \ - " - -RDEPENDS_${PN} = " \ - agl-service-gps \ - agl-service-geoclue \ - agl-service-geofence \ - qtlocation \ - qtvirtualkeyboard \ - " - -inherit qmake5 aglwgt diff --git a/recipes-demo-hmi/navigation/ondemandnavi_git.bb b/recipes-demo-hmi/navigation/ondemandnavi_git.bb deleted file mode 100644 index c52655ef..00000000 --- a/recipes-demo-hmi/navigation/ondemandnavi_git.bb +++ /dev/null @@ -1,35 +0,0 @@ -SUMMARY = "AGL Reference On Demand Navigation application." -DESCRIPTION = "Demo AGL navigation application based on QtLocation widget." -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/ondemandnavi" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -DEPENDS += "qtquickcontrols2 \ - qlibhomescreen \ - qlibwindowmanager \ - qtlocation \ - qtaglextras \ - libqtappfw \ -" - -PV = "1.0+git${SRCPV}" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/ondemandnavi;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -S = "${WORKDIR}/git" - -inherit qmake5 aglwgt pkgconfig - -RDEPENDS_${PN} += "qtlocation \ - flite \ - libqtappfw \ - openjtalk \ - gstreamer1.0 \ - ondemandnavi-config \ -" - -RPROVIDES_${PN} = "virtual/navigation" - diff --git a/recipes-demo-hmi/navigation/poiapp-api-key_1.0.bb b/recipes-demo-hmi/navigation/poiapp-api-key_1.0.bb deleted file mode 100644 index d353d7dd..00000000 --- a/recipes-demo-hmi/navigation/poiapp-api-key_1.0.bb +++ /dev/null @@ -1,21 +0,0 @@ -SUMMARY = "AGL Reference POI application API key." -DESCRIPTION = "Preload the API key for the AGL POI application." -HOMEPAGE = "https://github.com/AGLExport/genivi-navi-yelp-client" -SECTION = "apps" -LICENSE = "Proprietary" -LIC_FILES_CHKSUM="file://${COMMON_LICENSE_DIR}/Proprietary;md5=0557f9d92cf58f2ccdd50f62f8ac0b28" - -inherit allarch - -do_fetch[noexec] = "1" -do_unpack[noexec] = "1" -do_compile[noexec] = "1" - -POIAPP_CLIENT_ID ?= "" -POIAPP_API_KEY ?= "" - -do_install () { - install -d ${D}${sysconfdir} - echo "${POIAPP_CLIENT_ID}" > ${D}${sysconfdir}/poikey - echo "${POIAPP_API_KEY}" >> ${D}${sysconfdir}/poikey -} diff --git a/recipes-demo-hmi/navigation/poiapp/0001-add-display-permission.patch b/recipes-demo-hmi/navigation/poiapp/0001-add-display-permission.patch deleted file mode 100644 index 25a8fc31..00000000 --- a/recipes-demo-hmi/navigation/poiapp/0001-add-display-permission.patch +++ /dev/null @@ -1,21 +0,0 @@ -Add display permission - -Add display permission required to work with the running as non-root -change for applications. - -Upstream-Status: pending - -Signed-off-by: Scott Murray <scott.murray@konsulko.com> - -diff --git a/config.xml.in b/config.xml.in -index b8cfccd..bec206d 100755 ---- a/config.xml.in -+++ b/config.xml.in -@@ -13,6 +13,7 @@ - <feature name="urn:AGL:widget:required-permission"> - <param name="urn:AGL:permission::public:no-htdocs" value="required" /> - <param name="http://tizen.org/privilege/internal/dbus" value="required" /> -+ <param name="urn:AGL:permission::public:display" value="required" /> - </feature> - <license>GPL</license> - </widget> diff --git a/recipes-demo-hmi/navigation/poiapp_git.bb b/recipes-demo-hmi/navigation/poiapp_git.bb deleted file mode 100644 index b8db9ac9..00000000 --- a/recipes-demo-hmi/navigation/poiapp_git.bb +++ /dev/null @@ -1,21 +0,0 @@ -SUMMARY = "AGL Reference POI application." -DESCRIPTION = "This application provides the function of destination search to AGL. It uses the API provided by AGL Reference Navigation. This application uses yelp WebAPI." -HOMEPAGE = "https://github.com/AGLExport/genivi-navi-yelp-client" -SECTION = "apps" - -LICENSE = "GPLv2" -LIC_FILES_CHKSUM = "file://COPYING;md5=947b2d60ca3872e172034438e9801200" - -DEPENDS += "qtbase json-c \ - qlibwindowmanager libhomescreen \ - libqtappfw \ - " - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/poi-yelp;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -S = "${WORKDIR}/git" - -inherit cmake_qt5 pkgconfig aglwgt - -RDEPENDS_${PN} = "qtbase libqtappfw" diff --git a/recipes-demo-hmi/navigation/tbtnavi_git.bb b/recipes-demo-hmi/navigation/tbtnavi_git.bb deleted file mode 100644 index a61f2c92..00000000 --- a/recipes-demo-hmi/navigation/tbtnavi_git.bb +++ /dev/null @@ -1,36 +0,0 @@ -SUMMARY = "AGL Reference Navigation Cluster Streaming application" -DESCRIPTION = "Demo AGL turn by turn cluster navigation application based on QtLocation widget." -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/admin/repos/apps/tbtnavi" -SECTION = "apps" - -LICENSE = "Apache-2.0 & ISC & BSD-3-Clause & BSL-1.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984 \ - file://LICENSE.mapbox-cheap-ruler-cpp;md5=761263ee6bdc98e8697d9fbc897021ba \ - file://LICENSE.mapbox-geometry.hpp;md5=6e44f5d6aeec54f40fc84eebe3c6fc6c \ - file://LICENSE.mapbox-variant;md5=79558839a9db3e807e4ae6f8cd100c1c \ - file://include/mapbox/recursive_wrapper.hpp;beginline=4;endline=13;md5=cd3341aae76c0cf8345935abd20f0051 \ -" - -DEPENDS += "qtbase \ - qtquickcontrols2 \ - qlibhomescreen \ - qlibwindowmanager \ - qtlocation \ - libqtappfw \ -" - -PV = "1.0+git${SRCPV}" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/tbtnavi;protocol=https;branch=${AGL_BRANCH}" -#SRCREV = "4a8b7a6301e4b093c99329d0a16fbee6c535f312" -SRCREV = "${AGL_APP_REVISION}" - -S = "${WORKDIR}/git" - -inherit qmake5 aglwgt pkgconfig - -RDEPENDS_${PN} += "qtlocation \ - ondemandnavi-config \ - agl-service-navigation \ - libqtappfw \ -" diff --git a/recipes-demo-hmi/onscreenapp/onscreenapp_git.bb b/recipes-demo-hmi/onscreenapp/onscreenapp_git.bb deleted file mode 100644 index ae905ea6..00000000 --- a/recipes-demo-hmi/onscreenapp/onscreenapp_git.bb +++ /dev/null @@ -1,18 +0,0 @@ -SUMMARY = "onscreenapp for displaying onscreen" -DESCRIPTION = "AGL HMI Application for displaying onscreen" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/onscreenapp" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/onscreenapp;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2 libhomescreen qlibhomescreen libwindowmanager qlibwindowmanager" - -inherit qmake5 aglwgt diff --git a/recipes-demo-hmi/phone/phone_git.bb b/recipes-demo-hmi/phone/phone_git.bb deleted file mode 100644 index 553cc8ac..00000000 --- a/recipes-demo-hmi/phone/phone_git.bb +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY = "Phone for CES2017 AGL Demonstration" -DESCRIPTION = "AGL HMI Application for demonstrating phone on AGL Distribution" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/phone" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/phone;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2 \ - libqtappfw \ - libhomescreen \ - qlibwindowmanager \ - gstreamer1.0 \ -" - -inherit qmake5 aglwgt - -RDEPENDS_${PN} += "agl-service-telephony agl-service-bluetooth-pbap" diff --git a/recipes-demo-hmi/qtquickcontrols2-agl-style/qtquickcontrols2-agl-style_git.bb b/recipes-demo-hmi/qtquickcontrols2-agl-style/qtquickcontrols2-agl-style_git.bb deleted file mode 100644 index e9e8b2b3..00000000 --- a/recipes-demo-hmi/qtquickcontrols2-agl-style/qtquickcontrols2-agl-style_git.bb +++ /dev/null @@ -1,28 +0,0 @@ -SUMMARY = "AGL QtQuickControls2 style customizations" -HOMEPAGE = "https://git.automotivelinux.org/gerrit/#/admin/projects/src/qtquickcontrols2-agl-style" -LICENSE = "MPL-2.0" -LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=815ca599c9df247a0c7f619bab123dad" - -DEPENDS = "qtquickcontrols2" - -PV = "1.0+git${SRCPV}" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/qtquickcontrols2-agl-style;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "c02692a3c20d9aed1192137a67d5be882c60e71f" - -S = "${WORKDIR}/git/" - -inherit qmake5 - -FILES_${PN} += "${OE_QMAKE_PATH_QML}/QtQuick/Controls.2/AGL/*" - -RDEPENDS_${PN} += " \ - qtquickcontrols-qmlplugins \ - qtquickcontrols2-qmlplugins \ - qtsvg-plugins \ -" - -do_install_append_class-target() { - install -d ${D}/${sysconfdir}/afm/unit.env.d - echo "QT_QUICK_CONTROLS_STYLE=AGL" > ${D}${sysconfdir}/afm/unit.env.d/qtquickcontrols2-style -} diff --git a/recipes-demo-hmi/settings-log-utils/settings-log-utils_git.bb b/recipes-demo-hmi/settings-log-utils/settings-log-utils_git.bb deleted file mode 100644 index 90dc0bee..00000000 --- a/recipes-demo-hmi/settings-log-utils/settings-log-utils_git.bb +++ /dev/null @@ -1,24 +0,0 @@ -SUMMARY = "App for log record" -DESCRIPTION = "AGL HMI Application for demonstrating Log Record on AGL Distribution" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/settings-log-utils" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=89aea4e17d99a7cacdbeed46a0096b10" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/settings-log-utils;protocol=https;branch=master" -SRCREV = "${AUTOREV}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "libqtappfw qtquickcontrols2 qtwebsockets opencv boost" -DEPENDS += "libhomescreen qlibwindowmanager qtvirtualkeyboard" - -# runtime dependencies -RDEPENDS_${PN} += " \ - agl-service-bluetooth \ - agl-service-network" - -inherit qmake5 aglwgt diff --git a/recipes-demo-hmi/settings/settings_git.bb b/recipes-demo-hmi/settings/settings_git.bb deleted file mode 100644 index 72e0323f..00000000 --- a/recipes-demo-hmi/settings/settings_git.bb +++ /dev/null @@ -1,26 +0,0 @@ -SUMMARY = "Settings for CES2017 AGL Demonstration" -DESCRIPTION = "AGL HMI Application for demonstrating Settings on AGL Distribution" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/settings" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/settings;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "libqtappfw qtquickcontrols2 qt-qrcode" -DEPENDS += "libhomescreen qlibwindowmanager qtvirtualkeyboard" - -# runtime dependencies -RDEPENDS_${PN} += " \ - qt-qrcode \ - agl-service-bluetooth \ - agl-service-network \ -" - -inherit qmake5 aglwgt diff --git a/recipes-demo-hmi/taskmanager/taskmanager_git.bb b/recipes-demo-hmi/taskmanager/taskmanager_git.bb deleted file mode 100644 index f616b4d7..00000000 --- a/recipes-demo-hmi/taskmanager/taskmanager_git.bb +++ /dev/null @@ -1,26 +0,0 @@ -SUMMARY = "Task Manager for AGL Demonstration" -DESCRIPTION = "AGL HMI Application for demonstrating task visualisation and management on AGL Distribution" -HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/taskmanager" -SECTION = "apps" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/taskmanager;protocol=https;branch=${AGL_BRANCH}" -SRCREV = "${AGL_APP_REVISION}" - -PV = "1.0+git${SRCPV}" -S = "${WORKDIR}/git" - -# build-time dependencies -DEPENDS += "qtquickcontrols2 \ - qtwebsockets \ - qtcharts \ - libqtappfw \ - libhomescreen \ - qlibwindowmanager \ -" - -inherit qmake5 aglwgt - -RDEPENDS_${PN} += "agl-service-taskmanager" diff --git a/recipes-demo-hmi/vod-server/files/0001-Fix-cross-compilation-with-yocto.patch b/recipes-demo-hmi/vod-server/files/0001-Fix-cross-compilation-with-yocto.patch deleted file mode 100644 index c034d4ee..00000000 --- a/recipes-demo-hmi/vod-server/files/0001-Fix-cross-compilation-with-yocto.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/buildX86/Makefile-Release.mk 2016-12-09 15:48:37.000000000 +0100 -+++ b/buildX86/Makefile-Release.mk 2016-12-09 16:56:35.071740652 +0100 -@@ -11,14 +11,14 @@ - MKDIR=mkdir - CP=cp - GREP=grep --NM=nm --CCADMIN=CCadmin --RANLIB=ranlib --CC=${CROSS_COMPILE}gcc --CCC=${CROSS_COMPILE}g++ --CXX=${CROSS_COMPILE}g++ --FC=${CROSS_COMPILE}gfortran --AS=${CROSS_COMPILE}as -+#NM=nm -+#CCADMIN=CCadmin -+#RANLIB=ranlib -+#CC=${CROSS_COMPILE}gcc -+#CCC=${CROSS_COMPILE}g++ -+#CXX=${CROSS_COMPILE}g++ -+#FC=${CROSS_COMPILE}gfortran -+#AS=${CROSS_COMPILE}as - - # Macros - CND_PLATFORM=GNU-Linux-x86 diff --git a/recipes-demo-hmi/vod-server/files/vod-demo.service b/recipes-demo-hmi/vod-server/files/vod-demo.service deleted file mode 100644 index c783bd4a..00000000 --- a/recipes-demo-hmi/vod-server/files/vod-demo.service +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=Video On Demand AGL Demo -After=WindowManager.service most-network-manager.service - -[Service] -Type=simple -ExecStart=/usr/bin/VideoOnDemand -p /home/root/Video - -[Install] -WantedBy=default.target diff --git a/recipes-demo-hmi/vod-server/vod-server_0.1.bb b/recipes-demo-hmi/vod-server/vod-server_0.1.bb deleted file mode 100644 index d1cbb669..00000000 --- a/recipes-demo-hmi/vod-server/vod-server_0.1.bb +++ /dev/null @@ -1,35 +0,0 @@ -DESCRIPTION = "Build VideoOnDemand server" -LICENSE = "GPLv2" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" -#LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e \ -# " - -PV = "0.1" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/vod-server;protocol=https;branch=${AGL_BRANCH}" -SRC_URI += "file://0001-Fix-cross-compilation-with-yocto.patch \ - file://vod-demo.service" - -S = "${WORKDIR}/git" -SRCREV = "faafe61dd5f88859a005a59082d57339089ddca1" - -do_install() { - install -m 0755 -d ${D}${bindir} - install -m 0755 ${S}/VideoOnDemand ${D}${bindir}/VideoOnDemand - - # Install VOD server systemd service (user) - if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then - install -m 644 -p -D ${WORKDIR}/vod-demo.service ${D}${systemd_user_unitdir}/vod-demo.service - - # Execute install manually for root user on behalf of systemctl script - # because it doesn't support user mode of systemd. - install -m 0755 -d ${D}${ROOT_HOME}/.config/systemd/user/default.target.wants/ - ln -sf ${systemd_user_unitdir}/vod-demo.service ${D}${ROOT_HOME}/.config/systemd/user/default.target.wants/vod-demo.service - sed -i "s:/home/root:${ROOT_HOME}:" ${D}${ROOT_HOME}/.config/systemd/user/default.target.wants/vod-demo.service - fi -} - -FILES_${PN} += " \ - ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/vod-demo.service', '', d)} \ - ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${ROOT_HOME}/.config/systemd/user/default.target.wants/vod-demo.service', '', d)} \ - " diff --git a/recipes-demo-hmi/windowmanager/windowmanager_git.bb b/recipes-demo-hmi/windowmanager/windowmanager_git.bb deleted file mode 100644 index 84a43a86..00000000 --- a/recipes-demo-hmi/windowmanager/windowmanager_git.bb +++ /dev/null @@ -1,37 +0,0 @@ -SUMMARY = "AGL WindowManager Application" -DESCRIPTION = "WindowManager" -HOMEPAGE = "http://docs.automotivelinux.org" -LICENSE = "Apache-2.0" -SECTION = "apps" -S = "${WORKDIR}/git/" - -inherit qmake5 systemd -DEPENDS = " qtbase " - -# for WindowManager: -DEPENDS += " wayland-ivi-extension " - -LIC_FILES_CHKSUM = "file://windowmanager/LICENSE;md5=ae6497158920d9524cf208c09cc4c984" -SRCREV = "eeedc5e9e67917bd3346dbe5332e667757a3b28d" -# PV needs to be modified with SRCPV to work AUTOREV correctly -PV = "0.0+git${SRCPV}" - -SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/windowmanager.git;protocol=https;branch=${AGL_BRANCH}" - -PATH_prepend = "${STAGING_DIR_NATIVE}${OE_QMAKE_PATH_QT_BINS}:" - -do_install() { - install -d ${D}/usr/AGL/${PN} - install -m 0755 ${B}/windowmanager/WindowManager ${D}/usr/AGL/${PN}/ - - install -d ${D}${systemd_user_unitdir} - install -m 0644 ${S}/windowmanager/conf/WindowManager.service ${D}${systemd_user_unitdir} - install -m 0644 ${S}/windowmanager/conf/WindowManager.path ${D}${systemd_user_unitdir} - - install -d ${D}${sysconfdir}/systemd/user/default.target.wants - ln -sf ${systemd_user_unitdir}/WindowManager.path ${D}${sysconfdir}/systemd/user/default.target.wants -} - -FILES_${PN} += "/usr/AGL/${PN}/ ${systemd_user_unitdir}" -FILES_${PN}-dbg += "/usr/AGL/${PN}/.debug" - diff --git a/recipes-demo/agl-demo-control-panel/agl-demo-control-panel_git.bb b/recipes-demo/agl-demo-control-panel/agl-demo-control-panel_git.bb new file mode 100644 index 00000000..c3ae99dc --- /dev/null +++ b/recipes-demo/agl-demo-control-panel/agl-demo-control-panel_git.bb @@ -0,0 +1,59 @@ +SUMMARY = "AGL demo control panel" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=685e0faaaec2c2334cf8159ca6bd2975" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/agl-demo-control-panel;protocol=https;branch=${AGL_BRANCH} \ + file://agl-demo-control-panel.service \ +" +SRCREV = "545256365dc0603658ad5e17bfa1fa00ba829d7e" + +S = "${WORKDIR}/git" + +inherit systemd allarch + +require recipes-config/agl-users/agl-users.inc + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + # There's no provision for a Pythonic install into /usr/lib, so dump + # into a directory /usr/libexec. + install -d ${D}${libexecdir}/${BPN} + cp -drv ${S}/* ${D}${libexecdir}/${BPN} + + # Remove stray shell script from Docker container build support to + # avoid QA complaints + rm -rf ${D}${libexecdir}/${BPN}/docker + + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service + + # Install conf file + install -d ${D}/home/agl-driver/.local/share/agl-demo-control-panel + sed 's/=user-session/=AGL-databroker/' ${S}/extras/config.ini > \ + ${D}/home/agl-driver/.local/share/agl-demo-control-panel/config.ini + chown -R agl-driver:agl-driver ${D}/home/agl-driver +} + +# For now generate resource wrapper on first boot, as it looks non-trivial +# to get python3-pyqt5-native working to run pyrcc5 during build. +pkg_postinst_ontarget:${PN} () { + /usr/bin/pyrcc5 -o ${libexecdir}/${BPN}/res_rc.py ${libexecdir}/${BPN}/assets/res.qrc + true +} + +FILES:${PN} += "/home/agl-driver" + +RDEPENDS:${PN} += " \ + python3 \ + python3-modules \ + python3-packaging \ + python3-qtwidgets \ + python3-can \ + agl-users \ + weston \ +" diff --git a/recipes-demo/agl-demo-control-panel/files/agl-demo-control-panel.service b/recipes-demo/agl-demo-control-panel/files/agl-demo-control-panel.service new file mode 100644 index 00000000..5780bdfa --- /dev/null +++ b/recipes-demo/agl-demo-control-panel/files/agl-demo-control-panel.service @@ -0,0 +1,16 @@ +[Unit] +Requires=weston.service +After=weston.service +Before=graphical.target + +[Service] +Type=simple +User=agl-driver +Group=agl-driver +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +Environment=WAYLAND_DISPLAY=wayland-1 +ExecStart=/usr/bin/python3 /usr/libexec/agl-demo-control-panel/main.py +Restart=on-failure + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/agl-service-audiomixer/agl-service-audiomixer/agl-service-audiomixer.conf b/recipes-demo/agl-service-audiomixer/agl-service-audiomixer/agl-service-audiomixer.conf new file mode 100644 index 00000000..e0d84f8f --- /dev/null +++ b/recipes-demo/agl-service-audiomixer/agl-service-audiomixer/agl-service-audiomixer.conf @@ -0,0 +1,2 @@ +[kuksa-client] +authorization = "/etc/xdg/AGL/agl-service-audiomixer/agl-service-audiomixer.token" diff --git a/recipes-demo/agl-service-audiomixer/agl-service-audiomixer/agl-service-audiomixer.json b/recipes-demo/agl-service-audiomixer/agl-service-audiomixer/agl-service-audiomixer.json new file mode 100644 index 00000000..87c8bb03 --- /dev/null +++ b/recipes-demo/agl-service-audiomixer/agl-service-audiomixer/agl-service-audiomixer.json @@ -0,0 +1,10 @@ +{ + "sub": "local dev", + "iss": "createToken.py", + "aud": [ + "kuksa.val" + ], + "iat": 1516239022, + "exp": 1767225599, + "scope": "provide:Vehicle.Cabin.Infotainment.Media.Volume provide:Vehicle.Cabin.Infotainment.Navigation.Volume provide:Vehicle.Cabin.Infotainment.Navigation.Mute provide:Vehicle.Cabin.Infotainment.Media.Audio read:Vehicle.Cabin.SteeringWheel.Switches" +} diff --git a/recipes-demo/agl-service-audiomixer/agl-service-audiomixer/agl-service-audiomixer.token b/recipes-demo/agl-service-audiomixer/agl-service-audiomixer/agl-service-audiomixer.token new file mode 100644 index 00000000..a1ff0c1d --- /dev/null +++ b/recipes-demo/agl-service-audiomixer/agl-service-audiomixer/agl-service-audiomixer.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoicHJvdmlkZTpWZWhpY2xlLkNhYmluLkluZm90YWlubWVudC5NZWRpYS5Wb2x1bWUgcHJvdmlkZTpWZWhpY2xlLkNhYmluLkluZm90YWlubWVudC5OYXZpZ2F0aW9uLlZvbHVtZSBwcm92aWRlOlZlaGljbGUuQ2FiaW4uSW5mb3RhaW5tZW50Lk5hdmlnYXRpb24uTXV0ZSBwcm92aWRlOlZlaGljbGUuQ2FiaW4uSW5mb3RhaW5tZW50Lk1lZGlhLkF1ZGlvIHJlYWQ6VmVoaWNsZS5DYWJpbi5TdGVlcmluZ1doZWVsLlN3aXRjaGVzIn0.XMRtp91vXg9WAyISkema6jbt1WfHtbXZBxa2XwwsIVZet89gqfQhp30KJiwR1zS23vhBKHmLVFvPCD6kEMzIj-5vump6qeoksMAmk5x0b6jZaffjZklHQuRKMHCOCCdsQqSkaEPQDrR78DGpO39Qd_eC0N7TLNJRWZaVLs2JOwnglizo65rqA7ZUDhqaXv7EOWT24Cr2Mj-MRpoyxQmSGbzwBWeV2BG1DIn5uRlHS514pA6er6vVIPA_oGcbSWSN1AWytYfkBUIoNaqHE78YqJBLU7lDg21nV93MRi7D7Zs2g-lxbl5uwRuXik6g2Dj86hIjRX3VpJzaepMbFvXV1_DIZ_LEagMhfJrXqwfXkY3ivjCrrC6Y4bL9bnKyOLVwFhlqlMOWN4MWNeZyTG0fHzp2dVwpoVUx0X1_wepSFhhm2OD3LYY5VlqZUUxQGdM3i5p-dMrFTfhe_kzjPxwMTvENpk1D7w75LzlZp4NHDREqcKLNXE-5gY828NpFGdytdZRrvs7yKqAJEUabNj4VBguUrv3Xoy0k-ANdE3XFEAc_IrnENsxDqk_OPPljeG8-yF1BTksG3Of-ozbN8dBWmZIJHRqm5EgH3QHbvOUVcQwCFlUsgRhe3TQH2NYD1UBavN67BDUO5UCarD3aWZoUKMKtQMCjvr217qvCCUNOLmA
\ No newline at end of file diff --git a/recipes-demo/agl-service-audiomixer/agl-service-audiomixer_git.bb b/recipes-demo/agl-service-audiomixer/agl-service-audiomixer_git.bb new file mode 100644 index 00000000..e6b7d64b --- /dev/null +++ b/recipes-demo/agl-service-audiomixer/agl-service-audiomixer_git.bb @@ -0,0 +1,52 @@ +SUMMARY = "Audio Mixer Service Daemon" +DESCRIPTION = "AGL Audio Mixer Service Daemon" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/agl-service-audiomixer" +SECTION = "apps" +LICENSE = "MIT & Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;beginline=3;md5=e8ad01a5182f2c1b3a2640e9ea268264" + +DEPENDS = " \ + glib-2.0 \ + boost \ + openssl \ + systemd \ + pipewire \ + wireplumber \ + protobuf-native \ + grpc-native \ + protobuf \ + grpc \ + kuksa-databroker \ +" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-service-audiomixer.git;protocol=https;branch=${AGL_BRANCH} \ + file://agl-service-audiomixer.conf \ + file://agl-service-audiomixer.token \ +" +SRCREV = "0ff3ef1b254364639fc42495bbcfb4760250990a" + +PV = "2.0+git${SRCPV}" +S = "${WORKDIR}/git" + +inherit meson pkgconfig systemd + +EXTRA_OEMESON += "-Dprotos=${STAGING_INCDIR}" + +SYSTEMD_SERVICE:${PN} = "agl-service-audiomixer.service" + +do_install:append() { + # Currently using default global client and CA certificates + # for KUKSA.val SSL, installing app specific ones would go here. + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/agl-service-audiomixer + install -m 0644 ${WORKDIR}/agl-service-audiomixer.conf ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/agl-service-audiomixer.token ${D}${sysconfdir}/xdg/AGL/agl-service-audiomixer/ +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "kuksa-databroker" diff --git a/recipes-demo/agl-service-hvac/agl-service-hvac/agl-service-hvac.conf b/recipes-demo/agl-service-hvac/agl-service-hvac/agl-service-hvac.conf new file mode 100644 index 00000000..ca2f4f69 --- /dev/null +++ b/recipes-demo/agl-service-hvac/agl-service-hvac/agl-service-hvac.conf @@ -0,0 +1,2 @@ +[kuksa-client] +authorization = "/etc/xdg/AGL/agl-service-hvac/agl-service-hvac.token" diff --git a/recipes-demo/agl-service-hvac/agl-service-hvac/agl-service-hvac.json b/recipes-demo/agl-service-hvac/agl-service-hvac/agl-service-hvac.json new file mode 100644 index 00000000..3b348b4a --- /dev/null +++ b/recipes-demo/agl-service-hvac/agl-service-hvac/agl-service-hvac.json @@ -0,0 +1,10 @@ +{ + "sub": "local dev", + "iss": "createToken.py", + "aud": [ + "kuksa.val" + ], + "iat": 1516239022, + "exp": 1767225599, + "scope": "provide:Vehicle.Cabin.HVAC" +}
\ No newline at end of file diff --git a/recipes-demo/agl-service-hvac/agl-service-hvac/agl-service-hvac.token b/recipes-demo/agl-service-hvac/agl-service-hvac/agl-service-hvac.token new file mode 100644 index 00000000..6bbfc59d --- /dev/null +++ b/recipes-demo/agl-service-hvac/agl-service-hvac/agl-service-hvac.token @@ -0,0 +1 @@ +eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoicHJvdmlkZTpWZWhpY2xlLkNhYmluLkhWQUMifQ.c-Z-DFLu0XmPR0w5Xwx33fUQzd04m-u0kBOyu0Q1ai4Vgh5oHBsMH4NI59X-wz96iX5acI2WDFhpbkjNZ9rQ7piXDmfGuvec_QZ2MAMyYjeP6F26XkapLAkq71cq0ddblQOb7gyqtUFPLssDh-j5kENZev_zAYWEvynym7FHlFdMnBdwsndnMkCAyNJiKhbYKM5glcChJ3zsQWB5BttxDpZS96C4WgvAFAoJejXzvdPxj3LEgDzCyrInrTLZjhvJNyo5aP9iR3wCe1DCYsf4nkrkvjnpr47mH2XfeXxI2RAxNFwxfUs_ylLkZfpyL6nXLLffFhl7Zm_NX2aI5qaebLBUa1imE69Ap84vplJOVkK5nBRa41HA12Y52C83mqZ1Q2jEUEit5eY1r1B-WJ0ldc3CmlQOdhICIe0vyb1cOPCLuinKHw6cP4UxybDHnMVhH7IdO-IOXqAn_EdBVdLFsa5Kz-ujoGnDZWLEKXEZI7zLzrSH8zQdONycr7BV3RU_H1jesvEgfLW-kqkELV26eallbnL2st6R0vsX4Svc7RMOzeU4NUVP6xD020G3YeIci7LDC5V2YY2k4YfwUR3DI4b0nSMFOJlRaZu0OOPZCLB5OmPynKlUDohUn37FK1HXIxKLlx2x6BQIAypAxBkiHQfX-CwCGKnWPFM9dXhrUgo
\ No newline at end of file diff --git a/recipes-demo/agl-service-hvac/agl-service-hvac_git.bb b/recipes-demo/agl-service-hvac/agl-service-hvac_git.bb new file mode 100644 index 00000000..73d35f55 --- /dev/null +++ b/recipes-demo/agl-service-hvac/agl-service-hvac_git.bb @@ -0,0 +1,50 @@ +SUMMARY = "Demo HVAC Service Daemon" +DESCRIPTION = "Demo HVAC Service Daemon" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/agl-service-hvac" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = " \ + glib-2.0 \ + boost \ + openssl \ + systemd \ + protobuf-native \ + grpc-native \ + protobuf \ + grpc \ + kuksa-databroker \ +" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-service-hvac;protocol=https;branch=${AGL_BRANCH} \ + file://agl-service-hvac.conf \ + file://agl-service-hvac.token \ +" +SRCREV = "1f55937667e35fb79dabee0e180787e34a59169a" + +PV = "2.0+git${SRCPV}" +S = "${WORKDIR}/git" + +inherit meson pkgconfig systemd + +EXTRA_OEMESON += "-Dprotos=${STAGING_INCDIR}" + +SYSTEMD_SERVICE:${PN} = "agl-service-hvac.service" + +do_install:append() { + # Currently using default global client and CA certificates + # for KUKSA.val SSL, installing app specific ones would go here. + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/agl-service-hvac + install -m 0644 ${WORKDIR}/agl-service-hvac.conf ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/agl-service-hvac.token ${D}${sysconfdir}/xdg/AGL/agl-service-hvac/ +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "kuksa-databroker kuksa-databroker-agl" diff --git a/recipes-demo/agl-service-radio/agl-service-radio_git.bb b/recipes-demo/agl-service-radio/agl-service-radio_git.bb new file mode 100644 index 00000000..bc517524 --- /dev/null +++ b/recipes-demo/agl-service-radio/agl-service-radio_git.bb @@ -0,0 +1,47 @@ +SUMMARY = "Demo Radio Service Daemon" +DESCRIPTION = "Demo Radio Service Daemon" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/agl-service-radio" +LICENSE = "Apache-2.0 & GPL-2.0-or-later" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984 \ + file://LICENSE.GPL-2.0-only;md5=751419260aa954499f7abaabaa882bbe" + +DEPENDS = " \ + glib-2.0 \ + glib-2.0-native \ + gstreamer1.0 \ + protobuf-native \ + grpc-native \ + grpc \ + systemd \ + rtl-sdr \ + libusb-compat \ +" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-service-radio;protocol=https;branch=${AGL_BRANCH} \ + file://radio.conf.kvm-demo" +SRCREV = "b4debfc9e238b57dace7cae6ad0ad42ce42fbaf4" + +PV = "2.0+git${SRCPV}" +S = "${WORKDIR}/git" + +inherit meson pkgconfig systemd + +SYSTEMD_SERVICE:${PN} = "agl-service-radio.service" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/radio.conf.kvm-demo ${D}${sysconfdir}/xdg/AGL.conf +} + +PACKAGE_BEFORE_PN += "${PN}-conf-kvm-demo" + +FILES:${PN} += "${systemd_system_unitdir}" + +FILES:${PN}-conf-kvm-demo += " \ + ${sysconfdir}/xdg/AGL.conf \ +" + +RDEPENDS:${PN} += " \ + gstreamer1.0 \ + gstreamer1.0-plugins-base \ + gstreamer1.0-pipewire \ +" diff --git a/recipes-demo/agl-service-radio/files/radio.conf.kvm-demo b/recipes-demo/agl-service-radio/files/radio.conf.kvm-demo new file mode 100644 index 00000000..d855eb4b --- /dev/null +++ b/recipes-demo/agl-service-radio/files/radio.conf.kvm-demo @@ -0,0 +1,2 @@ +[radio] +bind=0.0.0.0 diff --git a/recipes-demo/agl-vss-helper/agl-vss-helper.bb b/recipes-demo/agl-vss-helper/agl-vss-helper.bb new file mode 100644 index 00000000..88e14511 --- /dev/null +++ b/recipes-demo/agl-vss-helper/agl-vss-helper.bb @@ -0,0 +1,35 @@ +DESCRIPTION = "AGL VSS helper daemon" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +SRC_URI = "file://agl-vss-helper.py \ + file://agl-vss-helper.yaml \ + file://agl-vss-helper.token \ + file://agl-vss-helper.service \ +" + +inherit systemd + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + install -d ${D}${sbindir} + install -m 0755 ${WORKDIR}/${BPN}.py ${D}${sbindir} + install -d ${D}${sysconfdir}/xdg/AGL/${BPN} + install -m 0644 ${WORKDIR}/${BPN}.yaml ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/${BPN}.token ${D}${sysconfdir}/xdg/AGL/${BPN}/ + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service +} + +RDEPENDS:${PN} = " \ + python3 \ + python3-asyncio \ + python3-systemd \ + kuksa-databroker \ + kuksa-databroker-agl \ + kuksa-client \ + kuksa-certificates-agl-ca \ +" diff --git a/recipes-demo/agl-vss-helper/files/agl-vss-helper.py b/recipes-demo/agl-vss-helper/files/agl-vss-helper.py new file mode 100644 index 00000000..73ac6b9d --- /dev/null +++ b/recipes-demo/agl-vss-helper/files/agl-vss-helper.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 Aakash Solanki, tech2aks@gmail.com +# Copyright (c) 2024 Scott Murray <scott.murray@konsulko.com> +# +# SPDX-License-Identifier: MIT + +import sys +from pathlib import Path +import yaml +import asyncio +import concurrent.futures +from kuksa_client.grpc.aio import VSSClient +from kuksa_client.grpc import Datapoint +from systemd.daemon import notify + +# Defaults +hostname = "localhost" +port = 55555 +config_filename = "/etc/xdg/AGL/agl-vss-helper.yaml" +token_filename = "/etc/xdg/AGL/agl-vss-helper/agl-vss-helper.token" +ca_cert_filename = "/etc/kuksa-val/CA.pem" +tls_server_name = "localhost" +verbose = False + +async def main(): + client = VSSClient(hostname, + port, + root_certificates=Path(ca_cert_filename), + tls_server_name=tls_server_name, + token=token, + ensure_startup_connection=True) + await client.connect() + print(f"Connected to KUKSA.val databroker at {hostname}:{port}") + if "initialize" in config and isinstance(config["initialize"], list): + for entry in config["initialize"]: + if "signal" in entry and "value" in entry: + if verbose: + print(f"Setting {entry['signal']} to {entry['value']}") + await client.set_current_values({ entry["signal"] : Datapoint(entry["value"]) }) + + notify("READY=1") + + if "mock" in config and isinstance(config["mock"], list): + if len(config["mock"]) != 0: + print(f"Mocking actuators:") + for signal in config["mock"]: + print(f" {signal}") + async for updates in client.subscribe_target_values(config["mock"]): + for signal in updates: + if updates[signal] is not None: + if verbose: + print(f"Actuating {signal} to {updates[signal].value}") + await client.set_current_values({ signal : Datapoint(updates[signal].value) }) + + +# +# Initialization +# + +try: + config_file = open(config_filename, "r") + config = yaml.safe_load(config_file) +except yaml.YAMLError as exc: + print(f"Could not parse configuration: ${exc}") +except: + print(f"Could not read configuration") + +if "verbose" in config and isinstance(config["verbose"], bool): + verbose = config["verbose"] +if "hostname" in config and isinstance(config["hostname"], string): + hostname = config["hostname"] +if "port" in config and isinstance(config["port"], int): + port = config["port"] +if "use-tls" in config and isinstance(config["use-tls"], bool): + use_tls = config["use-tls"] +if "token-file" in config and isinstance(config["token-file"], string): + token_filename = config["token-file"] +if "ca-certificate" in config and isinstance(config["ca-certificate"], string): + ca_cert_filename = config["ca-certificate"] + +if token_filename != "": + if verbose: + print(f"Reading authorization token {token_filename}") + token_file = open(token_filename, "r") + token = token_file.read() +else: + token = "" + +print("Starting") +try: + asyncio.run(main()) +except KeyboardInterrupt: + print("Exiting") + +notify("STOPPING=1") +sys.exit(0) diff --git a/recipes-demo/agl-vss-helper/files/agl-vss-helper.service b/recipes-demo/agl-vss-helper/files/agl-vss-helper.service new file mode 100644 index 00000000..0199b6cd --- /dev/null +++ b/recipes-demo/agl-vss-helper/files/agl-vss-helper.service @@ -0,0 +1,11 @@ +[Unit] +Wants=network.target kuksa-databroker.service +After=network.target kuksa-databroker.service + +[Service] +Type=notify +ExecStart=/usr/bin/python3 -u /usr/sbin/agl-vss-helper.py +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/recipes-demo/agl-vss-helper/files/agl-vss-helper.token b/recipes-demo/agl-vss-helper/files/agl-vss-helper.token new file mode 100644 index 00000000..110d3c41 --- /dev/null +++ b/recipes-demo/agl-vss-helper/files/agl-vss-helper.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZSBwcm92aWRlIn0.x-bUZwDCC663wGYrWCYjQZwQWhN1CMuKgxuIN5dUF_izwMutiqF6Xc-tnXgZa93BbT3I74WOMk4awKHBUSTWekGs3-qF6gajorbat6n5180TOqvNu4CXuIPZN5zpngf4id3smMkKOT699tPnSEbmlkj4vk-mIjeOAU-FcYA-VbkKBTsjvfFgKa2OdB5h9uZARBg5Rx7uBN3JsH1I6j9zoLid184Ewa6bhU2qniFt5iPsGJniNsKsRrrndN1KzthO13My44s56yvwSHIOrgDGbXdja_eLuOVOq9pHCjCtorPScgEuUUE4aldIuML-_j397taNP9Y3VZYVvofEK7AuiePTbzwxrZ1RAjK74h1-4ued3A2gUTjr5BsRlc9b7eLZzxLJkrqdfGAzBh_rtrB7p32TbvpjeFP30NW6bB9JS43XACUUm_S_RcyI7BLuUdnFyQDQr6l6sRz9XayYXceilHdCxbAVN0HVnBeui5Bb0mUZYIRZeY8k6zcssmokANTD8ZviDMpKlOU3t5AlXJ0nLkgyMhV9IUTwPUv6F8BTPc-CquJCUNbTyo4ywTSoODWbm3PmQ3Y46gWF06xqnB4wehLscBdVk3iAihQp3tckGhMnx5PI_Oy7utIncr4pRCMos63TnBkfrl7d43cHQTuK0kO76EWtv4ODEHgLvEAv4HA
\ No newline at end of file diff --git a/recipes-demo/agl-vss-helper/files/agl-vss-helper.yaml b/recipes-demo/agl-vss-helper/files/agl-vss-helper.yaml new file mode 100644 index 00000000..21b5ce9a --- /dev/null +++ b/recipes-demo/agl-vss-helper/files/agl-vss-helper.yaml @@ -0,0 +1,108 @@ +initialize: +- signal: Vehicle.Speed + value: 0 +- signal: Vehicle.Powertrain.CombustionEngine.Speed + value: 600 +- signal: Vehicle.Powertrain.FuelSystem.RelativeLevel + value: 70 +- signal: Vehicle.Powertrain.FuelSystem.Range + value: 300000 +- signal: Vehicle.Powertrain.CombustionEngine.ECT + value: 70 +- signal: Vehicle.Body.Lights.DirectionIndicator.Left.IsSignaling + value: false +- signal: Vehicle.Body.Lights.DirectionIndicator.Right.IsSignaling + value: false +- signal: Vehicle.Powertrain.Transmission.SelectedGear + value: 127 +- signal: Vehicle.Body.Lights.Beam.Low.IsOn + value: true +- signal: Vehicle.Body.Lights.Beam.High.IsOn + value: false +- signal: Vehicle.Body.Lights.Parking.IsOn + value: false +- signal: Vehicle.Body.Lights.Hazard.IsSignaling + value: false +- signal: Vehicle.TraveledDistance + value: 1763 +- signal: Vehicle.TraveledDistanceSinceStart + value: 0 +- signal: Vehicle.Body.Trunk.Rear.IsLocked + value: true +- signal: Vehicle.Body.Trunk.Rear.IsOpen + value: false +- signal: Vehicle.Powertrain.Transmission.PerformanceMode + value: "NORMAL" +- signal: Vehicle.Cabin.HVAC.AmbientAirTemperature + value: 22 +- signal: Vehicle.Exterior.AirTemperature + value: 24 +- signal: Vehicle.Chassis.Axle.Row1.Wheel.Left.Tire.Pressure + value: 220 +- signal: Vehicle.Chassis.Axle.Row1.Wheel.Right.Tire.Pressure + value: 216 +- signal: Vehicle.Chassis.Axle.Row2.Wheel.Left.Tire.Pressure + value: 217 +- signal: Vehicle.Chassis.Axle.Row2.Wheel.Right.Tire.Pressure + value: 222 +- signal: Vehicle.OBD.Status.IsMILOn + value: false +- signal: Vehicle.Cabin.Infotainment.HMI.DistanceUnit + value: "KILOMETERS" +- signal: Vehicle.Cabin.Infotainment.HMI.TemperatureUnit + value: "C" +- signal: Vehicle.Cabin.Infotainment.HMI.TirePressureUnit + value: "KPA" +- signal: Vehicle.ADAS.CruiseControl.IsEnabled + value: false +- signal: Vehicle.ADAS.CruiseControl.IsActive + value: false +- signal: Vehicle.ADAS.CruiseControl.SpeedSet + value: false +- signal: Vehicle.ADAS.CruiseControl.IsError + value: false +- signal: Vehicle.Powertrain.TractionBattery.Charging.IsCharging + value: false +- signal: Vehicle.Powertrain.TractionBattery.Charging.IsChargingCableConnected + value: false +- signal: Vehicle.Powertrain.TractionBattery.Charging.IsChargingCableLocked + value: false +- signal: Vehicle.Powertrain.TractionBattery.Charging.IsDischarging + value: false +#- signal: Vehicle.CurrentLocation.Latitude +# value: +#- signal: Vehicle.CurrentLocation.Longitude +# value: +# +# AGL specific signals +# +- signal: Vehicle.Cabin.Infotainment.Navigation.State + value: "STOPPED" +- signal: Vehicle.Cabin.Infotainment.Navigation.ElapsedDistance + value: 0.0 +#- signal: Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Latitude +# value: +#- signal: Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Longitude +# value: +- signal: Vehicle.Cabin.SteeringWheel.Switches.Info + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.VolumeUp + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.VolumeDown + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.VolumeMute + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.Next + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.Previous + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.Mode + value: false + +mock: +- Vehicle.Cabin.Infotainment.HMI.DistanceUnit +- Vehicle.Cabin.Infotainment.HMI.TemperatureUnit +- Vehicle.Cabin.Infotainment.HMI.TirePressureUnit +- Vehicle.ADAS.CruiseControl.IsEnabled +- Vehicle.ADAS.CruiseControl.IsActive +- Vehicle.ADAS.CruiseControl.SpeedSet diff --git a/recipes-demo/camera-gstreamer/camera-gstreamer_git.bb b/recipes-demo/camera-gstreamer/camera-gstreamer_git.bb new file mode 100644 index 00000000..da9d5d91 --- /dev/null +++ b/recipes-demo/camera-gstreamer/camera-gstreamer_git.bb @@ -0,0 +1,29 @@ +SUMMARY = "Camera gstreamer demo application" +DESCRIPTION = "AGL demonstration of displaying incoming camera feed" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/camera-gstreamer" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = " \ + wayland wayland-native grpc grpc-native \ + gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-bad \ +" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/camera-gstreamer;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "97faa830c65258ba8b60fa53cdbfb3f9d810abb3" + +S = "${WORKDIR}/git" + +inherit meson pkgconfig agl-app + +AGL_APP_NAME = "Camera" + +RDEPENDS:${PN} += " \ + gstreamer1.0-plugins-base \ + gstreamer1.0-plugins-good \ + gstreamer1.0-plugins-bad \ +" diff --git a/recipes-demo/cluster-dashboard/cluster-dashboard/cluster-dashboard.conf b/recipes-demo/cluster-dashboard/cluster-dashboard/cluster-dashboard.conf new file mode 100644 index 00000000..87fc79a8 --- /dev/null +++ b/recipes-demo/cluster-dashboard/cluster-dashboard/cluster-dashboard.conf @@ -0,0 +1,4 @@ +[kuksa-client] +server = "192.168.10.2" +tls-server-name = "localhost" +authorization = "/etc/xdg/AGL/cluster-dashboard/cluster-dashboard.token" diff --git a/recipes-demo/cluster-dashboard/cluster-dashboard/cluster-dashboard.service b/recipes-demo/cluster-dashboard/cluster-dashboard/cluster-dashboard.service new file mode 100644 index 00000000..de34e0a5 --- /dev/null +++ b/recipes-demo/cluster-dashboard/cluster-dashboard/cluster-dashboard.service @@ -0,0 +1,22 @@ +[Unit] +Description=cluster-dashboard + +Requires=agl-compositor.service +After=agl-compositor.service + +# Since we are part of the agl session, make sure we are started before +# it is complete. +Before=graphical.target + +[Service] +User=agl-driver +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStart=/usr/bin/cluster-dashboard + +Restart=always + +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/cluster-dashboard/cluster-dashboard/cluster-dashboard.token b/recipes-demo/cluster-dashboard/cluster-dashboard/cluster-dashboard.token new file mode 100644 index 00000000..770aadcf --- /dev/null +++ b/recipes-demo/cluster-dashboard/cluster-dashboard/cluster-dashboard.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJrdWtzYS52YWwiLCJpc3MiOiJFY2xpcHNlIEtVS1NBIERldiIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTc2NzIyNTU5OSwia3Vrc2EtdnNzIjp7IioiOiJydyJ9fQ.QQcVR0RuRJIoasPXYsMGZhdvhLjUalk4GcRaxhh3-0_j3CtVSZ0lTbv_Z3As5BfIYzaMlwUzFGvCVOq2MXVjRK81XOAZ6wIsyKOxva16zjbZryr2V_m3yZ4twI3CPEzJch11_qnhInirHltej-tGg6ySfLaTYeAkw4xYGwENMBBhN5t9odANpScZP_xx5bNfwdW1so6FkV1WhpKlCywoxk_vYZxo187d89bbiu-xOZUa5D-ycFkd1-1rjPXLGE_g5bc4jcQBvNBc-5FDbvt4aJlTQqjpdeppxhxn_gjkPGIAacYDI7szOLC-WYajTStbksUju1iQCyli11kPx0E66me_ZVwOX07f1lRF6D2brWm1LcMAHM3bQUK0LuyVwWPxld64uSAEsvSKsRyJERc7nZUgLf7COnUrrkxgIUNjukbdT2JVN_I-3l3b4YXg6JVD7Y5g0QYBKgXEFpZrDbBVhzo7PXPAhJD6-c3DcUQyRZExbrnFV56RwWuExphw8lYnbMvxPWImiVmB9nRVgFKD0TYaw1sidPSSlZt8Uw34VZzHWIZQAQY0BMjR33fefg42XQ1YzIwPmDx4GYXLl7HNIIVbsRsibKaJnf49mz2qnLC1K272zXSPljO11Ke1MNnsnKyUH7mcwEs9nhTsnMgEOx_TyMLRYo-VEHBDLuEOiBo
\ No newline at end of file diff --git a/recipes-demo/cluster-dashboard/cluster-dashboard_git.bb b/recipes-demo/cluster-dashboard/cluster-dashboard_git.bb new file mode 100644 index 00000000..dd0e411a --- /dev/null +++ b/recipes-demo/cluster-dashboard/cluster-dashboard_git.bb @@ -0,0 +1,57 @@ +SUMMARY = "Instrument Cluster Dashboard application" +DESCRIPTION = "AGL demonstration instrument cluster dashboard application" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/agl-cluster-demo-dashboard" +SECTION = "apps" + +LICENSE = "Apache-2.0 & BSD-3-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984 \ + file://app/cluster-gauges.qml;beginline=9;endline=48;md5=54187d50b29429abee6095fe8b7c1a78" + +DEPENDS = " \ + qtquickcontrols2 \ + libqtappfw \ + glib-2.0 \ + wayland wayland-native \ + qtwayland qtwayland-native \ +" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-cluster-demo-dashboard;protocol=https;branch=${AGL_BRANCH} \ + file://cluster-dashboard.service \ + file://cluster-dashboard.conf \ + file://cluster-dashboard.token \ +" +SRCREV = "137144c447d8adb618f5acbcbafd65f50264d6eb" + +S = "${WORKDIR}/git" + +inherit pkgconfig cmake_qt5 systemd + +CLUSTER_DEMO_VSS_HOSTNAME ??= "192.168.10.2" + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/cluster-dashboard + install -m 0644 ${WORKDIR}/cluster-dashboard.conf ${D}${sysconfdir}/xdg/AGL/ + sed -i "s/^server = .*/server = \"${CLUSTER_DEMO_VSS_HOSTNAME}\"/" ${D}${sysconfdir}/xdg/AGL/cluster-dashboard.conf + install -m 0644 ${WORKDIR}/cluster-dashboard.token ${D}${sysconfdir}/xdg/AGL/cluster-dashboard/ +} + +RDEPENDS:${PN} += " \ + qtwayland \ + qtbase-qmlplugins \ + qtquickcontrols \ + qtquickcontrols-qmlplugins \ + qtquickcontrols2 \ + qtquickcontrols2-qmlplugins \ + qtgraphicaleffects-qmlplugins \ + qtsvg-plugins \ +" diff --git a/recipes-demo/cluster-gauges-qtcompositor/cluster-gauges-qtcompositor/cluster-gauges-qtcompositor.service b/recipes-demo/cluster-gauges-qtcompositor/cluster-gauges-qtcompositor/cluster-gauges-qtcompositor.service new file mode 100644 index 00000000..083a1e1f --- /dev/null +++ b/recipes-demo/cluster-gauges-qtcompositor/cluster-gauges-qtcompositor/cluster-gauges-qtcompositor.service @@ -0,0 +1,15 @@ +[Unit] +Description=cluster-gauges-qtcompositor + +[Service] +User=agl-driver +Environment=XDG_RUNTIME_DIR=/run/user/1001 +ExecStart=/usr/bin/cluster-gauges + +Restart=always + +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/cluster-gauges-qtcompositor/cluster-gauges-qtcompositor_git.bb b/recipes-demo/cluster-gauges-qtcompositor/cluster-gauges-qtcompositor_git.bb new file mode 100644 index 00000000..161e6652 --- /dev/null +++ b/recipes-demo/cluster-gauges-qtcompositor/cluster-gauges-qtcompositor_git.bb @@ -0,0 +1,38 @@ +SUMMARY = "Minimal cluster demo gauges that can be used standalone" +DESCRIPTION = "AGL HMI Application for demonstrating instrument cluster gauges as a wayland compositor" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/agl-cluster-demo-gauges" +SECTION = "apps" + +LICENSE = "Apache-2.0 & BSD-3-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984 \ + file://app/cluster-gauges.qml;beginline=10;endline=49;md5=54187d50b29429abee6095fe8b7c1a78" + +DEPENDS = "qtquickcontrols2 qtwebsockets" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-cluster-demo-gauges;protocol=https;branch=${AGL_BRANCH} \ + file://cluster-gauges-qtcompositor.service \ +" + +SRCREV = "23eaf7da1f7d252aefddf9e41e52c745b7433b50" + +S = "${WORKDIR}/git" + +inherit pkgconfig cmake_qt5 systemd + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service +} + +RDEPENDS:${PN} += " \ + qtquickcontrols \ + qtquickcontrols-qmlplugins \ + qtquickcontrols2 \ + qtquickcontrols2-qmlplugins \ + qtwebsockets \ + qtwebsockets-qmlplugins \ + kms-conf \ +" diff --git a/recipes-demo/cluster-receiver/cluster-receiver/cluster-receiver.service b/recipes-demo/cluster-receiver/cluster-receiver/cluster-receiver.service new file mode 100644 index 00000000..bf48afb2 --- /dev/null +++ b/recipes-demo/cluster-receiver/cluster-receiver/cluster-receiver.service @@ -0,0 +1,22 @@ +[Unit] +Description=cluster-receiver + +Requires=agl-compositor.service +After=agl-compositor.service + +# Since we are part of the agl session, make sure we are started before +# it is complete. +Before=graphical.target + +[Service] +User=agl-driver +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStart=/usr/bin/xdg-cluster-receiver + +Restart=always + +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/cluster-receiver/cluster-receiver_git.bb b/recipes-demo/cluster-receiver/cluster-receiver_git.bb new file mode 100644 index 00000000..f28abcb6 --- /dev/null +++ b/recipes-demo/cluster-receiver/cluster-receiver_git.bb @@ -0,0 +1,36 @@ +SUMMARY = "Instrument Cluster receiver application" +DESCRIPTION = "AGL demonstration instrument cluster XDG remote display application" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/agl-cluster-demo-receiver" +SECTION = "apps" + +LICENSE = "Apache-2.0 & MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=374fee6a7817f1e1a5a7bfb7b7989553" + +DEPENDS = " \ + wayland wayland-native \ + agl-compositor \ + gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-bad \ +" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-cluster-demo-receiver;protocol=https;branch=${AGL_BRANCH} \ + file://cluster-receiver.service \ +" +SRCREV = "8633f9754fc0b644e45862fc3ed6f95554ce58cf" + +S = "${WORKDIR}/git" + +inherit cmake pkgconfig systemd + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service +} + +RDEPENDS:${PN} += " \ + gstreamer1.0-plugins-base \ + gstreamer1.0-plugins-good \ + gstreamer1.0-plugins-bad \ +" diff --git a/recipes-demo/cluster-receiver/qt-cluster-receiver/qt-cluster-receiver.service b/recipes-demo/cluster-receiver/qt-cluster-receiver/qt-cluster-receiver.service new file mode 100644 index 00000000..e3e1b952 --- /dev/null +++ b/recipes-demo/cluster-receiver/qt-cluster-receiver/qt-cluster-receiver.service @@ -0,0 +1,22 @@ +[Unit] +Description=qt-cluster-receiver + +Requires=agl-compositor.service +After=agl-compositor.service + +# Since we are part of the agl session, make sure we are started before +# it is complete. +Before=graphical.target + +[Service] +User=agl-driver +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStart=/usr/bin/qt-cluster-receiver + +Restart=always + +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/cluster-receiver/qt-cluster-receiver_git.bb b/recipes-demo/cluster-receiver/qt-cluster-receiver_git.bb new file mode 100644 index 00000000..d50e9dd1 --- /dev/null +++ b/recipes-demo/cluster-receiver/qt-cluster-receiver_git.bb @@ -0,0 +1,41 @@ +SUMMARY = "Instrument Cluster receiver application" +DESCRIPTION = "AGL demonstration instrument cluster Qt remote display application" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/admin/repos/apps/agl-qt-cluster-demo-receiver" +SECTION = "apps" + +LICENSE = "Apache-2.0 & MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984 \ + file://app/surface.hpp;beginline=5;endline=21;md5=5351c531a191f0e3463aafcd0a6a00a3" + +DEPENDS = " \ + wayland wayland-native \ + qtwayland qtwayland-native \ + qtquickcontrols2 qtwebsockets qtbase qtdeclarative \ + gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-bad \ +" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-qt-cluster-demo-receiver;protocol=https;branch=${AGL_BRANCH} \ + file://qt-cluster-receiver.service \ +" +SRCREV = "b5622ce91307589b03ad5d903214b47ff2277e48" + +S = "${WORKDIR}/git" + +inherit cmake_qt5 pkgconfig systemd + +do_install:append() { + # Only install unit, do not enable it by default + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service +} + +RDEPENDS:${PN} += " \ + qtwayland \ + gstreamer1.0-plugins-base \ + gstreamer1.0-plugins-good \ + gstreamer1.0-plugins-bad \ +" + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" +SYSTEMD_AUTO_ENABLE:${PN} = "disable" diff --git a/recipes-demo/dashboard/dashboard/dashboard.conf b/recipes-demo/dashboard/dashboard/dashboard.conf new file mode 100644 index 00000000..87467ef0 --- /dev/null +++ b/recipes-demo/dashboard/dashboard/dashboard.conf @@ -0,0 +1,2 @@ +[kuksa-client] +authorization = "/etc/xdg/AGL/dashboard/dashboard.token" diff --git a/recipes-demo/dashboard/dashboard/dashboard.token b/recipes-demo/dashboard/dashboard/dashboard.token new file mode 100644 index 00000000..10fafb53 --- /dev/null +++ b/recipes-demo/dashboard/dashboard/dashboard.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoicmVhZCJ9.P6tJPRSJWB51UOFDFs8qQ-lGqb1NoWgCekHUKyMiYcs8sR3FGVKSRjSkcqv1tXOlILvqhUwyuTKui25_kFKkTPv47GI0xAqcXtaTmDwHAWZHFC6HWGWGXohu7XvURrim5kMRVHy_VGlzasGgVap0JFk3wmaY-nyFYL_PLDjvGjIQuOwFiUtKK1PfiKviZKyc5EzPUEAoHxFL_BSOsTdDDcaydFe9rSKJzpYrj7qXY0hMJCje2BUGlSUIttR95aSjOZflSxiGystWHME8fKMmDERAx749Jpt37M3taCxBsUzER5olPz65MGzFSikfC-jH_KGmJ4zNYS65_OM1a-CPfW7Ts__pyAXxFULNMHRMIfh8Wiig4UcooMy_ZJO_DN2rq95XdaBbzRua5mxvO2wM6iu5kv4lhNxhjVNGuWFRLLJ_icBUZlvAuC3eqp66B-Y3jJNI0cSnIvsVX8YFVS3ebW8tf40OdeVou8fWZPcQsFAAafBhIxNOW8FbLZ9sRvQ-FGwZy-GyF52IJ5ZKeGfAkeEh9ZLIcyJ2YlGp4q0EOKIdwIBsWfCFtZbAvi2ornO3XvJm94NBqprpvQYN_IB7yyRxDduLjNKqqcFqnrlWYI-ZhvghWH2rEblplgHZdyVD1G9Mbv0_zdNTKFs6J7IP96aV6-4hBOt3kROlS1G7ObA
\ No newline at end of file diff --git a/recipes-demo/dashboard/dashboard_git.bb b/recipes-demo/dashboard/dashboard_git.bb new file mode 100644 index 00000000..8ea658b1 --- /dev/null +++ b/recipes-demo/dashboard/dashboard_git.bb @@ -0,0 +1,47 @@ +SUMMARY = "Dashboard application" +DESCRIPTION = "AGL demonstration Dashboard application" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/dashboard" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = " \ + qttools-native \ + qtquickcontrols2 \ + libqtappfw \ +" + +PV = "2.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/dashboard;protocol=https;branch=${AGL_BRANCH} \ + file://dashboard.conf \ + file://dashboard.token \ +" +SRCREV = "0cfd9c9473dcb218d095f9e6b88f41e81765fdff" + +S = "${WORKDIR}/git" + +inherit qmake5 pkgconfig agl-app + +AGL_APP_NAME = "Dashboard" + +do_install:append() { + # Currently using default global client and CA certificates + # for KUKSA.val SSL, installing app specific ones would go here. + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/dashboard + install -m 0644 ${WORKDIR}/dashboard.conf ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/dashboard.token ${D}${sysconfdir}/xdg/AGL/dashboard/ +} + +RDEPENDS:${PN} += " \ + qtwayland \ + qtbase-qmlplugins \ + qtgraphicaleffects-qmlplugins \ + qtquickcontrols2-agl-style \ +" diff --git a/recipes-demo/flutter-cluster-dashboard/files/cluster-dashboard.token b/recipes-demo/flutter-cluster-dashboard/files/cluster-dashboard.token new file mode 100644 index 00000000..10fafb53 --- /dev/null +++ b/recipes-demo/flutter-cluster-dashboard/files/cluster-dashboard.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoicmVhZCJ9.P6tJPRSJWB51UOFDFs8qQ-lGqb1NoWgCekHUKyMiYcs8sR3FGVKSRjSkcqv1tXOlILvqhUwyuTKui25_kFKkTPv47GI0xAqcXtaTmDwHAWZHFC6HWGWGXohu7XvURrim5kMRVHy_VGlzasGgVap0JFk3wmaY-nyFYL_PLDjvGjIQuOwFiUtKK1PfiKviZKyc5EzPUEAoHxFL_BSOsTdDDcaydFe9rSKJzpYrj7qXY0hMJCje2BUGlSUIttR95aSjOZflSxiGystWHME8fKMmDERAx749Jpt37M3taCxBsUzER5olPz65MGzFSikfC-jH_KGmJ4zNYS65_OM1a-CPfW7Ts__pyAXxFULNMHRMIfh8Wiig4UcooMy_ZJO_DN2rq95XdaBbzRua5mxvO2wM6iu5kv4lhNxhjVNGuWFRLLJ_icBUZlvAuC3eqp66B-Y3jJNI0cSnIvsVX8YFVS3ebW8tf40OdeVou8fWZPcQsFAAafBhIxNOW8FbLZ9sRvQ-FGwZy-GyF52IJ5ZKeGfAkeEh9ZLIcyJ2YlGp4q0EOKIdwIBsWfCFtZbAvi2ornO3XvJm94NBqprpvQYN_IB7yyRxDduLjNKqqcFqnrlWYI-ZhvghWH2rEblplgHZdyVD1G9Mbv0_zdNTKFs6J7IP96aV6-4hBOt3kROlS1G7ObA
\ No newline at end of file diff --git a/recipes-demo/flutter-cluster-dashboard/files/cluster-dashboard.yaml b/recipes-demo/flutter-cluster-dashboard/files/cluster-dashboard.yaml new file mode 100644 index 00000000..0a115645 --- /dev/null +++ b/recipes-demo/flutter-cluster-dashboard/files/cluster-dashboard.yaml @@ -0,0 +1,2 @@ +authorization : "/etc/xdg/AGL/cluster-dashboard/cluster-dashboard.token" +use-tls : true diff --git a/recipes-demo/flutter-cluster-dashboard/files/cluster-dashboard.yaml.demo b/recipes-demo/flutter-cluster-dashboard/files/cluster-dashboard.yaml.demo new file mode 100644 index 00000000..32545c2b --- /dev/null +++ b/recipes-demo/flutter-cluster-dashboard/files/cluster-dashboard.yaml.demo @@ -0,0 +1,4 @@ +hostname: 192.168.10.2 +authorization : "/etc/xdg/AGL/cluster-dashboard/cluster-dashboard.token" +use-tls : true +tls-server-name : "localhost" diff --git a/recipes-demo/flutter-cluster-dashboard/files/flutter-cluster-dashboard.service b/recipes-demo/flutter-cluster-dashboard/files/flutter-cluster-dashboard.service new file mode 100644 index 00000000..21082e7e --- /dev/null +++ b/recipes-demo/flutter-cluster-dashboard/files/flutter-cluster-dashboard.service @@ -0,0 +1,14 @@ +[Unit] +Requires=agl-compositor.service +After=agl-compositor.service + +[Service] +User=agl-driver +EnvironmentFile=/etc/default/flutter +EnvironmentFile=-/etc/default/flutter-cluster-dashboard +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStart=/usr/bin/flutter-auto --b=/usr/share/flutter/flutter_cluster_dashboard/${FLUTTER_VERSION}/${FLUTTER_RUNTIME} --j=/usr/share/flutter/flutter-cluster-dashboard.json +Restart=on-failure + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/flutter-cluster-dashboard/files/flutter-cluster-dashboard.yaml b/recipes-demo/flutter-cluster-dashboard/files/flutter-cluster-dashboard.yaml new file mode 100644 index 00000000..35f5bdfd --- /dev/null +++ b/recipes-demo/flutter-cluster-dashboard/files/flutter-cluster-dashboard.yaml @@ -0,0 +1,6 @@ +hostname: localhost +port: 8090 +homeLat: 31.708643 +homeLng: 76.931882 +orsPathParam: driving-car +kuskaAuthToken: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJrdWtzYS52YWwiLCJpc3MiOiJFY2xpcHNlIEtVS1NBIERldiIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTc2NzIyNTU5OSwia3Vrc2EtdnNzIjp7IioiOiJydyJ9fQ.QQcVR0RuRJIoasPXYsMGZhdvhLjUalk4GcRaxhh3-0_j3CtVSZ0lTbv_Z3As5BfIYzaMlwUzFGvCVOq2MXVjRK81XOAZ6wIsyKOxva16zjbZryr2V_m3yZ4twI3CPEzJch11_qnhInirHltej-tGg6ySfLaTYeAkw4xYGwENMBBhN5t9odANpScZP_xx5bNfwdW1so6FkV1WhpKlCywoxk_vYZxo187d89bbiu-xOZUa5D-ycFkd1-1rjPXLGE_g5bc4jcQBvNBc-5FDbvt4aJlTQqjpdeppxhxn_gjkPGIAacYDI7szOLC-WYajTStbksUju1iQCyli11kPx0E66me_ZVwOX07f1lRF6D2brWm1LcMAHM3bQUK0LuyVwWPxld64uSAEsvSKsRyJERc7nZUgLf7COnUrrkxgIUNjukbdT2JVN_I-3l3b4YXg6JVD7Y5g0QYBKgXEFpZrDbBVhzo7PXPAhJD6-c3DcUQyRZExbrnFV56RwWuExphw8lYnbMvxPWImiVmB9nRVgFKD0TYaw1sidPSSlZt8Uw34VZzHWIZQAQY0BMjR33fefg42XQ1YzIwPmDx4GYXLl7HNIIVbsRsibKaJnf49mz2qnLC1K272zXSPljO11Ke1MNnsnKyUH7mcwEs9nhTsnMgEOx_TyMLRYo-VEHBDLuEOiBo diff --git a/recipes-demo/flutter-cluster-dashboard/files/flutter-cluster-dashboard.yaml.demo b/recipes-demo/flutter-cluster-dashboard/files/flutter-cluster-dashboard.yaml.demo new file mode 100644 index 00000000..2b01da66 --- /dev/null +++ b/recipes-demo/flutter-cluster-dashboard/files/flutter-cluster-dashboard.yaml.demo @@ -0,0 +1,6 @@ +hostname: 192.168.10.2 +port: 8090 +homeLat: 31.708643 +homeLng: 76.931882 +orsPathParam: driving-car +kuskaAuthToken: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJrdWtzYS52YWwiLCJpc3MiOiJFY2xpcHNlIEtVS1NBIERldiIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTc2NzIyNTU5OSwia3Vrc2EtdnNzIjp7IioiOiJydyJ9fQ.QQcVR0RuRJIoasPXYsMGZhdvhLjUalk4GcRaxhh3-0_j3CtVSZ0lTbv_Z3As5BfIYzaMlwUzFGvCVOq2MXVjRK81XOAZ6wIsyKOxva16zjbZryr2V_m3yZ4twI3CPEzJch11_qnhInirHltej-tGg6ySfLaTYeAkw4xYGwENMBBhN5t9odANpScZP_xx5bNfwdW1so6FkV1WhpKlCywoxk_vYZxo187d89bbiu-xOZUa5D-ycFkd1-1rjPXLGE_g5bc4jcQBvNBc-5FDbvt4aJlTQqjpdeppxhxn_gjkPGIAacYDI7szOLC-WYajTStbksUju1iQCyli11kPx0E66me_ZVwOX07f1lRF6D2brWm1LcMAHM3bQUK0LuyVwWPxld64uSAEsvSKsRyJERc7nZUgLf7COnUrrkxgIUNjukbdT2JVN_I-3l3b4YXg6JVD7Y5g0QYBKgXEFpZrDbBVhzo7PXPAhJD6-c3DcUQyRZExbrnFV56RwWuExphw8lYnbMvxPWImiVmB9nRVgFKD0TYaw1sidPSSlZt8Uw34VZzHWIZQAQY0BMjR33fefg42XQ1YzIwPmDx4GYXLl7HNIIVbsRsibKaJnf49mz2qnLC1K272zXSPljO11Ke1MNnsnKyUH7mcwEs9nhTsnMgEOx_TyMLRYo-VEHBDLuEOiBo diff --git a/recipes-demo/flutter-cluster-dashboard/files/flutter_cluster_dashboard_on_bg.json b/recipes-demo/flutter-cluster-dashboard/files/flutter_cluster_dashboard_on_bg.json new file mode 100644 index 00000000..c90e5e3a --- /dev/null +++ b/recipes-demo/flutter-cluster-dashboard/files/flutter_cluster_dashboard_on_bg.json @@ -0,0 +1,10 @@ +{ + "view": [ + { + "window_type": "BG", + "width": 1920, + "height": 1080, + "fullscreen": true + } + ] +} diff --git a/recipes-demo/flutter-cluster-dashboard/files/kvm.conf b/recipes-demo/flutter-cluster-dashboard/files/kvm.conf new file mode 100644 index 00000000..0a38143e --- /dev/null +++ b/recipes-demo/flutter-cluster-dashboard/files/kvm.conf @@ -0,0 +1,3 @@ +[Unit] +Wants=network-online.target +After=network-online.target diff --git a/recipes-demo/flutter-cluster-dashboard/flutter-cluster-dashboard_git.bb b/recipes-demo/flutter-cluster-dashboard/flutter-cluster-dashboard_git.bb new file mode 100644 index 00000000..beee7005 --- /dev/null +++ b/recipes-demo/flutter-cluster-dashboard/flutter-cluster-dashboard_git.bb @@ -0,0 +1,72 @@ +SUMMARY = "Flutter Instrument Cluster " +DESCRIPTION = "An instrument cluster app written in dart for the flutter runtime" +AUTHOR = "Aakash Solanki" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/flutter-instrument-cluster" + +SECTION = "graphics" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE.md;md5=0c52b0e4b5f0dbf57ea7d44bebb2e29d" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/flutter-instrument-cluster;protocol=https;branch=${AGL_BRANCH} \ + file://flutter-cluster-dashboard.service \ + file://flutter_cluster_dashboard_on_bg.json \ + file://cluster-dashboard.yaml \ + file://cluster-dashboard.yaml.demo \ + file://cluster-dashboard.token \ + file://kvm.conf \ +" + +PV = "1.0+git${SRCPV}" +SRCREV = "5bd594ae8ad92e8e74966c4ad87df83ec8088c2d" + +S = "${WORKDIR}/git" + +PUBSPEC_APPNAME = "flutter_cluster_dashboard" + +inherit flutter-app update-alternatives systemd + +CLUSTER_DEMO_VSS_HOSTNAME ??= "192.168.10.2" + +APP_CONFIG = "flutter_cluster_dashboard_on_bg.json" + +SYSTEMD_SERVICE:${PN} = "flutter-cluster-dashboard.service" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service + + install -D -m 0644 ${WORKDIR}/kvm.conf ${D}${systemd_system_unitdir}/${BPN}.service.d/kvm.conf + + install -D -m 0644 ${WORKDIR}/${APP_CONFIG} ${D}${datadir}/flutter/${BPN}.json + + install -d ${D}${sysconfdir}/xdg/AGL/cluster-dashboard + install -m 0644 ${WORKDIR}/cluster-dashboard.yaml ${D}${sysconfdir}/xdg/AGL/cluster-dashboard.yaml.default + install -m 0644 ${WORKDIR}/cluster-dashboard.yaml.demo ${D}${sysconfdir}/xdg/AGL/ + sed -i "s/^hostname: .*/hostname: ${CLUSTER_DEMO_VSS_HOSTNAME}/" ${D}${sysconfdir}/xdg/AGL/cluster-dashboard.yaml.demo + install -m 0644 ${WORKDIR}/cluster-dashboard.token ${D}${sysconfdir}/xdg/AGL/cluster-dashboard/ +} + +ALTERNATIVE_LINK_NAME[cluster-dashboard.yaml] = "${sysconfdir}/xdg/AGL/cluster-dashboard.yaml" + +FILES:${PN} += "${datadir} ${sysconfdir}/xdg/AGL" + +RDEPENDS:${PN} += "flutter-auto agl-flutter-env liberation-fonts" + +PACKAGE_BEFORE_PN += "${PN}-conf ${PN}-conf-demo" + +FILES:${PN}-conf += "${sysconfdir}/xdg/AGL/cluster-dashboard.yaml.default" +RDEPENDS:${PN}-conf = "${PN}" +RPROVIDES:${PN}-conf = "cluster-dashboard.yaml" +RCONFLICTS:${PN}-conf = "${PN}-conf-demo" +ALTERNATIVE:${PN}-conf = "cluster-dashboard.yaml" +ALTERNATIVE_TARGET_${PN}-conf = "${sysconfdir}/xdg/AGL/cluster-dashboard.yaml.default" + +FILES:${PN}-conf-demo += " \ + ${sysconfdir}/xdg/AGL/cluster-dashboard.yaml.demo \ + ${systemd_system_unitdir}/flutter-cluster-dashboard.service.d/kvm.conf \ +" +RDEPENDS:${PN}-conf-demo = "${PN}" +RPROVIDES:${PN}-conf-demo = "cluster-dashboard.yaml" +RCONFLICTS:${PN}-conf-demo = "${PN}-conf" +ALTERNATIVE:${PN}-conf-demo = "cluster-dashboard.yaml" +ALTERNATIVE_TARGET_${PN}-conf-demo = "${sysconfdir}/xdg/AGL/cluster-dashboard.yaml.demo" diff --git a/recipes-demo/flutter-dashboard/files/dashboard.token b/recipes-demo/flutter-dashboard/files/dashboard.token new file mode 100644 index 00000000..10fafb53 --- /dev/null +++ b/recipes-demo/flutter-dashboard/files/dashboard.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoicmVhZCJ9.P6tJPRSJWB51UOFDFs8qQ-lGqb1NoWgCekHUKyMiYcs8sR3FGVKSRjSkcqv1tXOlILvqhUwyuTKui25_kFKkTPv47GI0xAqcXtaTmDwHAWZHFC6HWGWGXohu7XvURrim5kMRVHy_VGlzasGgVap0JFk3wmaY-nyFYL_PLDjvGjIQuOwFiUtKK1PfiKviZKyc5EzPUEAoHxFL_BSOsTdDDcaydFe9rSKJzpYrj7qXY0hMJCje2BUGlSUIttR95aSjOZflSxiGystWHME8fKMmDERAx749Jpt37M3taCxBsUzER5olPz65MGzFSikfC-jH_KGmJ4zNYS65_OM1a-CPfW7Ts__pyAXxFULNMHRMIfh8Wiig4UcooMy_ZJO_DN2rq95XdaBbzRua5mxvO2wM6iu5kv4lhNxhjVNGuWFRLLJ_icBUZlvAuC3eqp66B-Y3jJNI0cSnIvsVX8YFVS3ebW8tf40OdeVou8fWZPcQsFAAafBhIxNOW8FbLZ9sRvQ-FGwZy-GyF52IJ5ZKeGfAkeEh9ZLIcyJ2YlGp4q0EOKIdwIBsWfCFtZbAvi2ornO3XvJm94NBqprpvQYN_IB7yyRxDduLjNKqqcFqnrlWYI-ZhvghWH2rEblplgHZdyVD1G9Mbv0_zdNTKFs6J7IP96aV6-4hBOt3kROlS1G7ObA
\ No newline at end of file diff --git a/recipes-demo/flutter-dashboard/files/dashboard.yaml b/recipes-demo/flutter-dashboard/files/dashboard.yaml new file mode 100644 index 00000000..e54c469e --- /dev/null +++ b/recipes-demo/flutter-dashboard/files/dashboard.yaml @@ -0,0 +1,2 @@ +authorization : "/etc/xdg/AGL/dashboard/dashboard.token" +use-tls : true diff --git a/recipes-demo/flutter-dashboard/flutter-dashboard_git.bb b/recipes-demo/flutter-dashboard/flutter-dashboard_git.bb new file mode 100644 index 00000000..d378df9a --- /dev/null +++ b/recipes-demo/flutter-dashboard/flutter-dashboard_git.bb @@ -0,0 +1,42 @@ +SUMMARY = "Flutter Dashboard" +DESCRIPTION = "A Flutter based IVI Dashboard Application for automotive grade Linux." +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/flutter-dashboard" +SECTION = "graphics" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://License.md;md5=f712ede8d4f845976061925d1416fc40" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/flutter-dashboard;protocol=https;branch=${AGL_BRANCH} \ + file://dashboard.yaml \ + file://dashboard.token \ +" +SRCREV = "2fbe5f8c19863eb4ac013dce5546900592149a26" + +S = "${WORKDIR}/git" + +inherit agl-app flutter-app + +# flutter-app +############# +PUBSPEC_APPNAME = "dashboard_app" +FLUTTER_BUILD_ARGS = "bundle -v" + +# agl-app +######### +AGL_APP_TEMPLATE = "agl-app-flutter" +AGL_APP_ID = "dashboard_app" +AGL_APP_NAME = "Dashboard" + +do_install:append() { + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/dashboard + install -m 0644 ${WORKDIR}/dashboard.yaml ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/dashboard.token ${D}${sysconfdir}/xdg/AGL/dashboard/ +} + +FILES:${PN} += "${sysconfdir}/xdg/AGL" +RDEPENDS:${PN} += "flutter-auto" + diff --git a/recipes-demo/flutter-homescreen/files/flutter-homescreen.json b/recipes-demo/flutter-homescreen/files/flutter-homescreen.json new file mode 100644 index 00000000..83aa09a8 --- /dev/null +++ b/recipes-demo/flutter-homescreen/files/flutter-homescreen.json @@ -0,0 +1,10 @@ +{ + "view" : [ { + "window_type" : "BG", + "width" : 1920, + "height": 1080, + "fullscreen": true, + "window_activation_area" : { "x" : 0, "y" : 160, "width" : 1080, "height" : 1600 } + } + ] +} diff --git a/recipes-demo/flutter-homescreen/files/flutter-homescreen.service b/recipes-demo/flutter-homescreen/files/flutter-homescreen.service new file mode 100644 index 00000000..3024fced --- /dev/null +++ b/recipes-demo/flutter-homescreen/files/flutter-homescreen.service @@ -0,0 +1,14 @@ +[Unit] +Requires=agl-compositor.service applaunchd.service +After=agl-compositor.service applaunchd.service + +[Service] +User=agl-driver +EnvironmentFile=/etc/default/flutter +EnvironmentFile=-/etc/default/flutter-homescreen +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStart=/usr/bin/flutter-auto --b=/usr/share/flutter/flutter_homescreen/${FLUTTER_VERSION}/${FLUTTER_RUNTIME} --j=/usr/share/flutter/flutter-homescreen.json --xdg-shell-app-id=homescreen +Restart=on-failure + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/flutter-homescreen/files/homescreen.token b/recipes-demo/flutter-homescreen/files/homescreen.token new file mode 100644 index 00000000..110d3c41 --- /dev/null +++ b/recipes-demo/flutter-homescreen/files/homescreen.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZSBwcm92aWRlIn0.x-bUZwDCC663wGYrWCYjQZwQWhN1CMuKgxuIN5dUF_izwMutiqF6Xc-tnXgZa93BbT3I74WOMk4awKHBUSTWekGs3-qF6gajorbat6n5180TOqvNu4CXuIPZN5zpngf4id3smMkKOT699tPnSEbmlkj4vk-mIjeOAU-FcYA-VbkKBTsjvfFgKa2OdB5h9uZARBg5Rx7uBN3JsH1I6j9zoLid184Ewa6bhU2qniFt5iPsGJniNsKsRrrndN1KzthO13My44s56yvwSHIOrgDGbXdja_eLuOVOq9pHCjCtorPScgEuUUE4aldIuML-_j397taNP9Y3VZYVvofEK7AuiePTbzwxrZ1RAjK74h1-4ued3A2gUTjr5BsRlc9b7eLZzxLJkrqdfGAzBh_rtrB7p32TbvpjeFP30NW6bB9JS43XACUUm_S_RcyI7BLuUdnFyQDQr6l6sRz9XayYXceilHdCxbAVN0HVnBeui5Bb0mUZYIRZeY8k6zcssmokANTD8ZviDMpKlOU3t5AlXJ0nLkgyMhV9IUTwPUv6F8BTPc-CquJCUNbTyo4ywTSoODWbm3PmQ3Y46gWF06xqnB4wehLscBdVk3iAihQp3tckGhMnx5PI_Oy7utIncr4pRCMos63TnBkfrl7d43cHQTuK0kO76EWtv4ODEHgLvEAv4HA
\ No newline at end of file diff --git a/recipes-demo/flutter-homescreen/files/homescreen.yaml b/recipes-demo/flutter-homescreen/files/homescreen.yaml new file mode 100644 index 00000000..b5849a3d --- /dev/null +++ b/recipes-demo/flutter-homescreen/files/homescreen.yaml @@ -0,0 +1,2 @@ +authorization : "/etc/xdg/AGL/homescreen/homescreen.token" +use-tls : true diff --git a/recipes-demo/flutter-homescreen/flutter-homescreen_git.bb b/recipes-demo/flutter-homescreen/flutter-homescreen_git.bb new file mode 100644 index 00000000..0448bdd0 --- /dev/null +++ b/recipes-demo/flutter-homescreen/flutter-homescreen_git.bb @@ -0,0 +1,43 @@ +SUMMARY = "AGL Flutter Homescreen" +DESCRIPTION = "Demo Flutter homescreen for Automotive Grade Linux." +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/flutter-homescreen" +SECTION = "graphics" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/flutter-homescreen;protocol=https;branch=${AGL_BRANCH} \ + file://flutter-homescreen.json \ + file://flutter-homescreen.service \ + file://homescreen.yaml \ + file://homescreen.token \ +" +SRCREV = "6c016a39fb993165d0c103691ecf5333e09ef438" + +S = "${WORKDIR}/git" + +PUBSPEC_APPNAME = "flutter_homescreen" +FLUTTER_BUILD_ARGS = "bundle -v" + +inherit flutter-app systemd + +APP_CONFIG = "${BPN}.json" + +SYSTEMD_SERVICE:${PN} = "flutter-homescreen.service" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service + + install -D -m 0644 ${WORKDIR}/${APP_CONFIG} ${D}${datadir}/flutter/${BPN}.json + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/homescreen + install -m 0644 ${WORKDIR}/homescreen.yaml ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/homescreen.token ${D}${sysconfdir}/xdg/AGL/homescreen/ +} + +FILES:${PN} += "${datadir} ${sysconfdir}/xdg/AGL" +RDEPENDS:${PN} += "flutter-auto agl-flutter-env" diff --git a/recipes-demo/flutter-hvac/files/hvac.json b/recipes-demo/flutter-hvac/files/hvac.json new file mode 100644 index 00000000..20d842a6 --- /dev/null +++ b/recipes-demo/flutter-hvac/files/hvac.json @@ -0,0 +1,10 @@ +{ + "sub": "local dev", + "iss": "createToken.py", + "aud": [ + "kuksa.val" + ], + "iat": 1516239022, + "exp": 1767225599, + "scope": "actuate:Vehicle.Cabin.HVAC" +} diff --git a/recipes-demo/flutter-hvac/files/hvac.token b/recipes-demo/flutter-hvac/files/hvac.token new file mode 100644 index 00000000..76a554f8 --- /dev/null +++ b/recipes-demo/flutter-hvac/files/hvac.token @@ -0,0 +1 @@ +eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZTpWZWhpY2xlLkNhYmluLkhWQUMifQ.mDJd7Xn2C6xH9BRTURC2LtN_wlUgq3hJxBWNq8Dpelq43-4qDrNtfOEg2VV5wBcXimg64TwnopCHauqKyilgDt1q0VFIH9vcpp2m8QMV9Z06tR8A3zAJJ9DX4qU3WluY_STR5lnzRwvIW9fuZmyJ_msdnUB3vLp7bS47uekE6rX0OwoBzrw2Z38D5dnLilR4uknwMdWCVciBIg00xyj6hkufHyIyvgVI2Yfl8XMLgdklmgGIYRb3ljPxHsZ8MQkULbjOWsdRKJNqHP-lU17e9avzvBBXecakB0-Q-QSkuZr5H8gWLJG1a6jfcgbah1JfLJVkKWjX9knGT5csvXMGt7Mf9bGg43xb2bPkolKnmEXIlRxWyXGr_DSLmrVMukY2G_cmpj4E1v2cyyu6AtzhGyli3BD1O7ZTywZlLdGvrhxlQ1FU22OPLV8yyUoppGZLyAF_4tUaftcXXoE1HbqgzpvlPp7leB-pwmNTr9-wT8D5YAt5E5YrWGZOH6OYg-oV9Hl7JU-2zfFdm0stK_6P5D1xt0kHEjbML16SGJVO49aoeP8Fj_cNG5tc7GqHOkHBWlH7YUx2Ty4PLd91DGGHkhA-69vGs2Fg3ljpej-IHbsY269HTQd7v_wyQk_rEDMNqsOssjuFVHEd8vzdmQ-hG5BB5d_oWtCww6AAWqIlIOo
\ No newline at end of file diff --git a/recipes-demo/flutter-hvac/files/hvac.yaml b/recipes-demo/flutter-hvac/files/hvac.yaml new file mode 100644 index 00000000..3684d3d3 --- /dev/null +++ b/recipes-demo/flutter-hvac/files/hvac.yaml @@ -0,0 +1,2 @@ +authorization : "/etc/xdg/AGL/hvac/hvac.token" +use-tls : true diff --git a/recipes-demo/flutter-hvac/flutter-hvac_git.bb b/recipes-demo/flutter-hvac/flutter-hvac_git.bb new file mode 100644 index 00000000..365cc57a --- /dev/null +++ b/recipes-demo/flutter-hvac/flutter-hvac_git.bb @@ -0,0 +1,41 @@ +SUMMARY = "Flutter HVAC" +DESCRIPTION = "A Flutter based IVI Dashboard Application for automotive grade Linux." + +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/flutter-hvac" + +BUGTRACKER = "https://github.com/hritik-chouhan/HVAC_dashboard/issues" + +SECTION = "graphics" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://License.md;md5=f712ede8d4f845976061925d1416fc40" + + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/flutter-hvac;protocol=https;branch=${AGL_BRANCH} \ + file://hvac.yaml \ + file://hvac.token \ + " + +SRCREV = "802b3f1fefae4b1c05484d2eb6656afcd7fceedf" +S = "${WORKDIR}/git" + +inherit agl-app flutter-app + +# flutter-app +############# +PUBSPEC_APPNAME = "flutter_hvac" +FLUTTER_BUILD_ARGS = "bundle -v" + +# agl-app +######### +AGL_APP_TEMPLATE = "agl-app-flutter" +AGL_APP_ID = "flutter_hvac" +AGL_APP_NAME = "HVAC" + +do_install:append() { + install -d ${D}${sysconfdir}/xdg/AGL/hvac + install -m 0644 ${WORKDIR}/hvac.yaml ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/hvac.token ${D}${sysconfdir}/xdg/AGL/hvac/ +} + +FILES:${PN} += "${sysconfdir}/xdg/AGL" diff --git a/recipes-demo/flutter-ics-homescreen/files/flutter-ics-homescreen.json b/recipes-demo/flutter-ics-homescreen/files/flutter-ics-homescreen.json new file mode 100644 index 00000000..2817e5fe --- /dev/null +++ b/recipes-demo/flutter-ics-homescreen/files/flutter-ics-homescreen.json @@ -0,0 +1,10 @@ +{ + "view" : [ { + "window_type" : "BG", + "width" : 1080, + "height": 1920, + "fullscreen": true, + "window_activation_area" : { "x" : 0, "y" : 56, "width" : 1080, "height" : 1712 } + } + ] +} diff --git a/recipes-demo/flutter-ics-homescreen/files/flutter-ics-homescreen.service b/recipes-demo/flutter-ics-homescreen/files/flutter-ics-homescreen.service new file mode 100644 index 00000000..a61b4a1d --- /dev/null +++ b/recipes-demo/flutter-ics-homescreen/files/flutter-ics-homescreen.service @@ -0,0 +1,14 @@ +[Unit] +Requires=agl-compositor.service applaunchd.service +After=agl-compositor.service applaunchd.service + +[Service] +User=agl-driver +EnvironmentFile=/etc/default/flutter +EnvironmentFile=-/etc/default/flutter-ics-homescreen +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStart=/usr/bin/flutter-auto --b=/usr/share/flutter/flutter_ics_homescreen/${FLUTTER_VERSION}/${FLUTTER_RUNTIME} --j=/usr/share/flutter/flutter-ics-homescreen.json --xdg-shell-app-id=homescreen +Restart=on-failure + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/flutter-ics-homescreen/files/ics-homescreen.token b/recipes-demo/flutter-ics-homescreen/files/ics-homescreen.token new file mode 100644 index 00000000..110d3c41 --- /dev/null +++ b/recipes-demo/flutter-ics-homescreen/files/ics-homescreen.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZSBwcm92aWRlIn0.x-bUZwDCC663wGYrWCYjQZwQWhN1CMuKgxuIN5dUF_izwMutiqF6Xc-tnXgZa93BbT3I74WOMk4awKHBUSTWekGs3-qF6gajorbat6n5180TOqvNu4CXuIPZN5zpngf4id3smMkKOT699tPnSEbmlkj4vk-mIjeOAU-FcYA-VbkKBTsjvfFgKa2OdB5h9uZARBg5Rx7uBN3JsH1I6j9zoLid184Ewa6bhU2qniFt5iPsGJniNsKsRrrndN1KzthO13My44s56yvwSHIOrgDGbXdja_eLuOVOq9pHCjCtorPScgEuUUE4aldIuML-_j397taNP9Y3VZYVvofEK7AuiePTbzwxrZ1RAjK74h1-4ued3A2gUTjr5BsRlc9b7eLZzxLJkrqdfGAzBh_rtrB7p32TbvpjeFP30NW6bB9JS43XACUUm_S_RcyI7BLuUdnFyQDQr6l6sRz9XayYXceilHdCxbAVN0HVnBeui5Bb0mUZYIRZeY8k6zcssmokANTD8ZviDMpKlOU3t5AlXJ0nLkgyMhV9IUTwPUv6F8BTPc-CquJCUNbTyo4ywTSoODWbm3PmQ3Y46gWF06xqnB4wehLscBdVk3iAihQp3tckGhMnx5PI_Oy7utIncr4pRCMos63TnBkfrl7d43cHQTuK0kO76EWtv4ODEHgLvEAv4HA
\ No newline at end of file diff --git a/recipes-demo/flutter-ics-homescreen/files/ics-homescreen.yaml b/recipes-demo/flutter-ics-homescreen/files/ics-homescreen.yaml new file mode 100644 index 00000000..f8e400b3 --- /dev/null +++ b/recipes-demo/flutter-ics-homescreen/files/ics-homescreen.yaml @@ -0,0 +1,4 @@ +kuksa: + port : 55555 + authorization : "/etc/xdg/AGL/ics-homescreen/ics-homescreen.token" + use-tls : true diff --git a/recipes-demo/flutter-ics-homescreen/files/ics-homescreen.yaml.kvm-demo b/recipes-demo/flutter-ics-homescreen/files/ics-homescreen.yaml.kvm-demo new file mode 100644 index 00000000..22e7e390 --- /dev/null +++ b/recipes-demo/flutter-ics-homescreen/files/ics-homescreen.yaml.kvm-demo @@ -0,0 +1,10 @@ +kuksa: + hostname : 172.16.10.1 + port : 55555 + authorization : "/etc/xdg/AGL/ics-homescreen/ics-homescreen.token" + use-tls : true + tls-server-name : localhost +radio: + hostname : 172.16.10.1 +mpd: + hostname : 172.16.10.1 diff --git a/recipes-demo/flutter-ics-homescreen/files/kvm.conf b/recipes-demo/flutter-ics-homescreen/files/kvm.conf new file mode 100644 index 00000000..0a38143e --- /dev/null +++ b/recipes-demo/flutter-ics-homescreen/files/kvm.conf @@ -0,0 +1,3 @@ +[Unit] +Wants=network-online.target +After=network-online.target diff --git a/recipes-demo/flutter-ics-homescreen/files/radio-presets.yaml b/recipes-demo/flutter-ics-homescreen/files/radio-presets.yaml new file mode 100644 index 00000000..6af08377 --- /dev/null +++ b/recipes-demo/flutter-ics-homescreen/files/radio-presets.yaml @@ -0,0 +1,13 @@ +fm: +- frequency: 93100000 + name: 93.1 The Mountain +- frequency: 94100000 + name: Mix 94.1 +- frequency: 96300000 + name: 96.3 KKLZ +- frequency: 102700000 + name: 102.7 VGS +- frequency: 88900000 + name: News 88.9 +- frequency: 91500000 + name: KUNV diff --git a/recipes-demo/flutter-ics-homescreen/flutter-ics-homescreen_git.bb b/recipes-demo/flutter-ics-homescreen/flutter-ics-homescreen_git.bb new file mode 100644 index 00000000..576e5a7d --- /dev/null +++ b/recipes-demo/flutter-ics-homescreen/flutter-ics-homescreen_git.bb @@ -0,0 +1,82 @@ +SUMMARY = "AGL ICS Flutter Homescreen" +DESCRIPTION = "Demo Flutter homescreen for Automotive Grade Linux by ICS." +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/flutter-ics-homescreen" +SECTION = "graphics" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/flutter-ics-homescreen;protocol=https;branch=${AGL_BRANCH} \ + file://flutter-ics-homescreen.json \ + file://flutter-ics-homescreen.service \ + file://ics-homescreen.yaml \ + file://ics-homescreen.yaml.kvm-demo \ + file://ics-homescreen.token \ + file://radio-presets.yaml \ + file://kvm.conf \ +" +SRCREV = "5587c6ae79b482fbff26442bb239d7d7eb55a337" + +S = "${WORKDIR}/git" + +PUBSPEC_APPNAME = "flutter_ics_homescreen" +FLUTTER_BUILD_ARGS = "bundle -v" + +inherit flutter-app systemd update-alternatives + +APP_CONFIG = "${BPN}.json" + +SYSTEMD_SERVICE:${PN} = "flutter-ics-homescreen.service" + +# Disable the background animation on all platforms except the Renesas M3/H3 for now +DISABLE_BG_ANIMATION = "-DDISABLE_BKG_ANIMATION=true" +DISABLE_BG_ANIMATION:rcar-gen3 = "" +APP_AOT_EXTRA:append = " ${DISABLE_BG_ANIMATION}" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service + + install -D -m 0644 ${WORKDIR}/kvm.conf ${D}${systemd_system_unitdir}/${BPN}.service.d/kvm.conf + + install -D -m 0644 ${WORKDIR}/${APP_CONFIG} ${D}${datadir}/flutter/${BPN}.json + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/ics-homescreen + install -m 0644 ${WORKDIR}/ics-homescreen.yaml ${D}${sysconfdir}/xdg/AGL/ics-homescreen.yaml.default + install -m 0644 ${WORKDIR}/ics-homescreen.yaml.kvm-demo ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/ics-homescreen.token ${D}${sysconfdir}/xdg/AGL/ics-homescreen/ + install -m 0644 ${WORKDIR}/radio-presets.yaml ${D}${sysconfdir}/xdg/AGL/ics-homescreen/ +} + +ALTERNATIVE_LINK_NAME[ics-homescreen.yaml] = "${sysconfdir}/xdg/AGL/ics-homescreen.yaml" + +FILES:${PN} += "${datadir} ${sysconfdir}/xdg/AGL" + +RDEPENDS:${PN} += " \ + flutter-auto \ + agl-flutter-env \ + applaunchd \ + ${@bb.utils.contains('AGL_FEATURES', 'agl-kvm-host-audio', '', 'agl-service-radio mpd', d)} \ +" + +PACKAGE_BEFORE_PN += "${PN}-conf ${PN}-conf-kvm-demo" + +FILES:${PN}-conf += "${sysconfdir}/xdg/AGL/ics-homescreen.yaml.default" +RDEPENDS:${PN}-conf = "${PN}" +RPROVIDES:${PN}-conf = "ics-homescreen.yaml" +RCONFLICTS:${PN}-conf = "${PN}-conf-kvm-demo" +ALTERNATIVE:${PN}-conf = "ics-homescreen.yaml" +ALTERNATIVE_TARGET_${PN}-conf = "${sysconfdir}/xdg/AGL/ics-homescreen.yaml.default" + +FILES:${PN}-conf-kvm-demo += " \ + ${sysconfdir}/xdg/AGL/ics-homescreen.yaml.kvm-demo \ + ${systemd_system_unitdir}/flutter-ics-homescreen.service.d/kvm.conf \ +" +RDEPENDS:${PN}-conf-kvm-demo = "${PN}" +RPROVIDES:${PN}-conf-kvm-demo = "ics-homescreen.yaml" +RCONFLICTS:${PN}-conf-kvm-demo = "${PN}-conf" +ALTERNATIVE:${PN}-conf-kvm-demo = "ics-homescreen.yaml" +ALTERNATIVE_TARGET_${PN}-conf-kvm-demo = "${sysconfdir}/xdg/AGL/ics-homescreen.yaml.kvm-demo" diff --git a/recipes-demo/flutter-mediaplayer/flutter-mediaplayer_git.bb b/recipes-demo/flutter-mediaplayer/flutter-mediaplayer_git.bb new file mode 100644 index 00000000..8bf013e8 --- /dev/null +++ b/recipes-demo/flutter-mediaplayer/flutter-mediaplayer_git.bb @@ -0,0 +1,29 @@ +SUMMARY = "Flutter MediaPlayer app for IVI" +DESCRIPTION = "A Flutter based IVI Dashboard Application for automotive grade Linux" + +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/flutter-mediaplayer" + +BUGTRACKER = "https://github.com/hritik-chouhan/musicplayer/issues" + +SECTION = "graphics" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://License.md;md5=f712ede8d4f845976061925d1416fc40" + + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/flutter-mediaplayer;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "735de5a38ea937ee13157f6ac594053ddb8b027b" +S = "${WORKDIR}/git" + +inherit agl-app flutter-app + +# flutter-app +############# +PUBSPEC_APPNAME = "musicplayer" +FLUTTER_BUILD_ARGS = "bundle -v" + +# agl-app +######### +AGL_APP_TEMPLATE = "agl-app-flutter" +AGL_APP_ID = "musicplayer" +AGL_APP_NAME = "Flutter MediaPlayer" diff --git a/recipes-demo/flutter-nav/files/nav_config.yaml b/recipes-demo/flutter-nav/files/nav_config.yaml new file mode 100644 index 00000000..6824c6b7 --- /dev/null +++ b/recipes-demo/flutter-nav/files/nav_config.yaml @@ -0,0 +1,3 @@ +hostname : localhost +port : 8090 +kuskaAuthToken : eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJrdWtzYS52YWwiLCJpc3MiOiJFY2xpcHNlIEtVS1NBIERldiIsImFkbWluIjp0cnVlLCJtb2RpZnlUcmVlIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTc2NzIyNTU5OSwia3Vrc2EtdnNzIjp7IioiOiJydyJ9fQ.p2cnFGH16QoQ14l6ljPVKggFXZKmD-vrw8G6Vs6DvAokjsUG8FHh-F53cMsE-GDjyZH_1_CrlDCnbGlqjsFbgAylqA7IAJWp9_N6dL5p8DHZTwlZ4IV8L1CtCALs7XVqvcQKHCCzB63Y8PgVDCAqpQSRb79JPVD4pZwkBKpOknfEY5y9wfbswZiRKdgz7o61_oFnd-yywpse-23HD6v0htThVF1SuGL1PuvGJ8p334nt9bpkZO3gaTh1xVD_uJMwHzbuBCF33_f-I5QMZO6bVooXqGfe1zvl3nDrPEjq1aPulvtP8RgREYEqE6b2hB8jouTiC_WpE3qrdMw9sfWGFbm04qC-2Zjoa1yYSXoxmYd0SnliSYHAad9aXoEmFENezQV-of7sc-NX1-2nAXRAEhaqh0IRuJwB4_sG7SvQmnanwkz-sBYxKqkoFpOsZ6hblgPDOPYY2NAsZlYkjvAL2mpiInrsmY_GzGsfwPeAx31iozImX75rao8rm-XucAmCIkRlpBz6MYKCjQgyRz3UtZCJ2DYF4lKqTjphEAgclbYZ7KiCuTn9HualwtEmVzHHFneHMKl7KnRQk-9wjgiyQ5nlsVpCCblg6JKr9of4utuPO3cBvbjhB4_ueQ40cpWVOICcOLS7_w0i3pCq1ZKDEMrYDJfz87r2sU9kw1zeFQk diff --git a/recipes-demo/flutter-nav/flutter-nav_git.bb b/recipes-demo/flutter-nav/flutter-nav_git.bb new file mode 100644 index 00000000..11668052 --- /dev/null +++ b/recipes-demo/flutter-nav/flutter-nav_git.bb @@ -0,0 +1,51 @@ +SUMMARY = "Flutter Navigation app" +DESCRIPTION = "A Flutter based IVI Dashboard Application for automotive grade Linux." + +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/flutter-navigation" + +BUGTRACKER = "https://github.com/hritik-chouhan/nav-app/issues" + +SECTION = "graphics" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://License.md;md5=f712ede8d4f845976061925d1416fc40" + + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/flutter-navigation;protocol=https;branch=${AGL_BRANCH} \ + file://nav_config.yaml \ + " +SRCREV = "53164c0441db946b4293f483a28b524ecdc91e30" +S = "${WORKDIR}/git" + +MAPBOX_API_KEY ??= "YOU_NEED_TO_SET_IT_IN_LOCAL_CONF" + +inherit agl-app flutter-app + +# flutter-app +############# +PUBSPEC_APPNAME = "flutter_navigation" +FLUTTER_BUILD_ARGS = "bundle -v" + +# agl-app +######### +AGL_APP_TEMPLATE = "agl-app-flutter" +AGL_APP_ID = "flutter_navigation" +AGL_APP_NAME = "Flutter Navigation" + +do_configure:prepend() { + if [ "${MAPBOX_API_KEY}" = "YOU_NEED_TO_SET_IT_IN_LOCAL_CONF" ]; then + bbwarn "WARNING: You should set mapbox API key to mapbox_API_KEY variable in local.conf." + fi +} + +do_install:append() { + install -d ${D}${sysconfdir}/xdg/AGL + install -m 0644 ${WORKDIR}/nav_config.yaml ${D}${sysconfdir}/xdg/AGL/ + + install -m 0755 -d ${D}${sysconfdir}/default/ + + echo 'MAPBOX_API_KEY:${MAPBOX_API_KEY}' >> ${D}${sysconfdir}/default/mapboxkey +} + +FILES:${PN} += "${sysconfdir}/xdg/AGL ${sysconfdir}/default/" + diff --git a/recipes-demo/homescreen/files/homescreen.conf b/recipes-demo/homescreen/files/homescreen.conf new file mode 100644 index 00000000..d3998d9a --- /dev/null +++ b/recipes-demo/homescreen/files/homescreen.conf @@ -0,0 +1,2 @@ +[kuksa-client] +authorization = "/etc/xdg/AGL/homescreen/homescreen.token" diff --git a/recipes-demo/homescreen/files/homescreen.service b/recipes-demo/homescreen/files/homescreen.service new file mode 100644 index 00000000..d7b85f6f --- /dev/null +++ b/recipes-demo/homescreen/files/homescreen.service @@ -0,0 +1,15 @@ +[Unit] +Requires=agl-compositor.service applaunchd.service +After=agl-compositor.service applaunchd.service +Before=graphical.target + +[Service] +Type=simple +User=agl-driver +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +EnvironmentFile=-/etc/default/homescreen +ExecStart=/usr/bin/homescreen +Restart=on-failure + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/homescreen/files/homescreen.token b/recipes-demo/homescreen/files/homescreen.token new file mode 100644 index 00000000..110d3c41 --- /dev/null +++ b/recipes-demo/homescreen/files/homescreen.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZSBwcm92aWRlIn0.x-bUZwDCC663wGYrWCYjQZwQWhN1CMuKgxuIN5dUF_izwMutiqF6Xc-tnXgZa93BbT3I74WOMk4awKHBUSTWekGs3-qF6gajorbat6n5180TOqvNu4CXuIPZN5zpngf4id3smMkKOT699tPnSEbmlkj4vk-mIjeOAU-FcYA-VbkKBTsjvfFgKa2OdB5h9uZARBg5Rx7uBN3JsH1I6j9zoLid184Ewa6bhU2qniFt5iPsGJniNsKsRrrndN1KzthO13My44s56yvwSHIOrgDGbXdja_eLuOVOq9pHCjCtorPScgEuUUE4aldIuML-_j397taNP9Y3VZYVvofEK7AuiePTbzwxrZ1RAjK74h1-4ued3A2gUTjr5BsRlc9b7eLZzxLJkrqdfGAzBh_rtrB7p32TbvpjeFP30NW6bB9JS43XACUUm_S_RcyI7BLuUdnFyQDQr6l6sRz9XayYXceilHdCxbAVN0HVnBeui5Bb0mUZYIRZeY8k6zcssmokANTD8ZviDMpKlOU3t5AlXJ0nLkgyMhV9IUTwPUv6F8BTPc-CquJCUNbTyo4ywTSoODWbm3PmQ3Y46gWF06xqnB4wehLscBdVk3iAihQp3tckGhMnx5PI_Oy7utIncr4pRCMos63TnBkfrl7d43cHQTuK0kO76EWtv4ODEHgLvEAv4HA
\ No newline at end of file diff --git a/recipes-demo/homescreen/homescreen_git.bb b/recipes-demo/homescreen/homescreen_git.bb new file mode 100644 index 00000000..1f8e0c77 --- /dev/null +++ b/recipes-demo/homescreen/homescreen_git.bb @@ -0,0 +1,63 @@ +SUMMARY = "Home Screen application" +DESCRIPTION = "AGL demonstration Home Screen application" +HOMEPAGE = "http://docs.automotivelinux.org" +LICENSE = "Apache-2.0" +SECTION = "apps" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = " \ + qtbase \ + qtdeclarative \ + qtquickcontrols2 \ + libqtappfw \ + wayland-native \ + wayland \ + qtwayland \ + qtwayland-native \ + protobuf \ + grpc grpc-native \ + agl-compositor \ + applaunchd \ +" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/homescreen;protocol=https;branch=${AGL_BRANCH} \ + file://homescreen.service \ + file://homescreen.conf \ + file://homescreen.token \ +" +SRCREV = "2c91ad7b3b125176b2e26b435705557a089604a0" + +S = "${WORKDIR}/git" + +inherit meson pkgconfig systemd + +PATH:prepend = "${STAGING_DIR_NATIVE}${OE_QMAKE_PATH_QT_BINS}:" + +OE_QMAKE_CXXFLAGS:append = " ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', '' , '-DQT_NO_DEBUG_OUTPUT', d)}" + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_install:append() { + install -D -m0644 ${WORKDIR}/homescreen.service ${D}${systemd_system_unitdir}/homescreen.service + + # Currently using default global client and CA certificates + # for KUKSA.val SSL, installing app specific ones would go here. + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/homescreen + install -m 0644 ${WORKDIR}/homescreen.conf ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/homescreen.token ${D}${sysconfdir}/xdg/AGL/homescreen/ +} + +RDEPENDS:${PN} += " \ + libqtappfw \ + applaunchd \ + qtwayland \ + qtbase-qmlplugins \ + qtgraphicaleffects-qmlplugins \ +" diff --git a/recipes-demo/html5-background/html5-background_git.bb b/recipes-demo/html5-background/html5-background_git.bb new file mode 100644 index 00000000..c8487107 --- /dev/null +++ b/recipes-demo/html5-background/html5-background_git.bb @@ -0,0 +1,41 @@ +SUMMARY = "AGL HTML5 Background" +HOMEPAGE = "https://github.com/AGL-web-applications/background" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" +B = "${WORKDIR}/build" + +SRC_URI = " \ + git://gerrit.automotivelinux.org/gerrit/apps/html5-background;protocol=https;branch=master \ +" +SRCREV = "aa7e2a81e91ed076c0bc9ba07db5aee0f34668df" + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-${BPN}" +AGL_APP_NAME = "HTML5 Background" + +DEPENDS = "nodejs-native" + +do_compile[network] = "1" +do_compile() { + cd ${S} + rm -rf package node_modules package-lock.json + npm install + npm run build +} + +WAM_APPLICATIONS_DIR = "${libdir}/wam_apps" + +do_install() { + install -d ${D}${WAM_APPLICATIONS_DIR}/${PN} + cp -R --no-dereference --preserve=mode,links ${S}/dist/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + +FILES:${PN} = "${WAM_APPLICATIONS_DIR}/${PN}" + +RCONFLICTS:${PN} = "homescreen" diff --git a/recipes-demo/html5-dashboard/html5-dashboard_git.bb b/recipes-demo/html5-dashboard/html5-dashboard_git.bb new file mode 100644 index 00000000..586627c8 --- /dev/null +++ b/recipes-demo/html5-dashboard/html5-dashboard_git.bb @@ -0,0 +1,39 @@ +SUMMARY = "AGL HTML5 dashboard Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-dashboard/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" +B = "${WORKDIR}/build" + +SRC_URI = " \ + git://gerrit.automotivelinux.org/gerrit/apps/html5-dashboard;protocol=https;branch=master \ +" +SRCREV = "38befd7704f64781bf4bce85fd9b2cdffc7845fa" + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-dashboard" +AGL_APP_NAME = "HTML5 Dashboard" + +DEPENDS = "nodejs-native" + +do_compile[network] = "1" +do_compile() { + cd ${S} + rm -rf package node_modules package-lock.json + npm install + npm run build +} + +WAM_APPLICATIONS_DIR = "${libdir}/wam_apps" + +do_install() { + install -d ${D}${WAM_APPLICATIONS_DIR}/${PN} + cp -R --no-dereference --preserve=mode,links ${S}/dist/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + +FILES:${PN} = "${WAM_APPLICATIONS_DIR}/${PN}" diff --git a/recipes-demo/html5-homescreen/files/homescreen.service b/recipes-demo/html5-homescreen/files/homescreen.service new file mode 100644 index 00000000..b8d34caa --- /dev/null +++ b/recipes-demo/html5-homescreen/files/homescreen.service @@ -0,0 +1,16 @@ +[Unit] +Description=AGL Homescreen +Requires=WebAppMgr.service dbus.service +After=WebAppMgr.service dbus.service + +[Service] +Type=simple +User=agl-driver +EnvironmentFile=-/etc/default/WebAppMgr.env +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStartPre=sleep 5 +ExecStart=/usr/bin/WebAppMgrCli --appid=homescreen --app-install-dir=/usr/lib/wam_apps/html5-homescreen/ +Restart=on-failure + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/html5-homescreen/html5-homescreen_git.bb b/recipes-demo/html5-homescreen/html5-homescreen_git.bb new file mode 100644 index 00000000..2c46b95a --- /dev/null +++ b/recipes-demo/html5-homescreen/html5-homescreen_git.bb @@ -0,0 +1,45 @@ +SUMMARY = "AGL HTML5 Homescreen" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-homescreen/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +SRC_URI = " \ + git://gerrit.automotivelinux.org/gerrit/apps/html5-homescreen;protocol=https;branch=master \ + file://homescreen.service \ +" +SRCREV = "32098508fa7375690ea1b8dc9da4e7ca641494c1" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" +B = "${WORKDIR}/build" + +inherit systemd + +DEPENDS = "nodejs-native" + +do_compile[network] = "1" +do_compile() { + cd ${S} + rm -rf package node_modules package-lock.json + npm install + npm run build +} + +WAM_APPLICATIONS_DIR = "${libdir}/wam_apps" + +SYSTEMD_SERVICE:${PN} = "homescreen.service" + +do_install() { + install -d ${D}${WAM_APPLICATIONS_DIR}/${PN} + cp -R --no-dereference --preserve=mode,links ${S}/dist/* ${D}${WAM_APPLICATIONS_DIR}/${PN} + install -D -m 0644 ${WORKDIR}/homescreen.service ${D}${systemd_system_unitdir}/homescreen.service +} + +FILES:${PN} = " \ + ${WAM_APPLICATIONS_DIR}/${PN} \ + ${systemd_system_unitdir} \ +" + +RCONFLICTS:${PN} = "homescreen flutter-homescreen" +RDEPENDS:${PN} = "applaunchd html5-background" diff --git a/recipes-demo/html5-hvac/html5-hvac_git.bb b/recipes-demo/html5-hvac/html5-hvac_git.bb new file mode 100644 index 00000000..c0d4c545 --- /dev/null +++ b/recipes-demo/html5-hvac/html5-hvac_git.bb @@ -0,0 +1,40 @@ +SUMMARY = "AGL HTML5 HVAC Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-hvac/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" +B = "${WORKDIR}/build" + +SRC_URI = " \ + git://gerrit.automotivelinux.org/gerrit/apps/html5-hvac;protocol=https;branch=master \ +" +SRCREV = "c323ab8fde212120d8d1914d453afeb55b3576e5" + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-hvac" +AGL_APP_NAME = "HTML5 HVAC" + +DEPENDS = "nodejs-native protobuf-native" + +do_compile[network] = "1" +do_compile() { + cd ${S} + rm -rf package node_modules package-lock.json + npm install + npm run generate-grpc + npm run build +} + +WAM_APPLICATIONS_DIR = "${libdir}/wam_apps" + +do_install() { + install -d ${D}${WAM_APPLICATIONS_DIR}/${PN} + cp -R --no-dereference --preserve=mode,links ${S}/dist/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + +FILES:${PN} = "${WAM_APPLICATIONS_DIR}/${PN}" diff --git a/recipes-demo/html5-launcher/html5-launcher_git.bb b/recipes-demo/html5-launcher/html5-launcher_git.bb new file mode 100644 index 00000000..cc9143c2 --- /dev/null +++ b/recipes-demo/html5-launcher/html5-launcher_git.bb @@ -0,0 +1,42 @@ +SUMMARY = "AGL HTML5 Launcher Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-launcher/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" +B = "${WORKDIR}/build" + +SRC_URI = " \ + git://gerrit.automotivelinux.org/gerrit/apps/html5-launcher;protocol=https;branch=master \ +" +SRCREV = "ccdd59db7dc073eee0a35d0318640d9833824073" + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "launcher" +AGL_APP_NAME = "HTML5 Launcher" + +DEPENDS = "nodejs-native" + +do_compile[network] = "1" +do_compile() { + cd ${S} + rm -rf package node_modules package-lock.json + npm install + npm run build +} + +WAM_APPLICATIONS_DIR = "${libdir}/wam_apps" + +do_install() { + install -d ${D}${WAM_APPLICATIONS_DIR}/${PN} + cp -R --no-dereference --preserve=mode,links ${S}/dist/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + +FILES:${PN} = "${WAM_APPLICATIONS_DIR}/${PN}" + +RCONFLICTS:${PN} = "launcher flutter-homescreen" +RDEPENDS:${PN} = "applaunchd" diff --git a/recipes-demo/html5-mediaplayer/html5-mediaplayer_git.bb b/recipes-demo/html5-mediaplayer/html5-mediaplayer_git.bb new file mode 100644 index 00000000..c1780529 --- /dev/null +++ b/recipes-demo/html5-mediaplayer/html5-mediaplayer_git.bb @@ -0,0 +1,39 @@ +SUMMARY = "AGL HTML5 media player Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-mediaplayer/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" +B = "${WORKDIR}/build" + +SRC_URI = " \ + git://gerrit.automotivelinux.org/gerrit/apps/html5-mediaplayer;protocol=https;branch=master \ +" +SRCREV = "b87776912cc31c976415ceb49e7551f500e0975b" + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-mediaplayer" +AGL_APP_NAME = "HTML5 Media Player" + +DEPENDS = "nodejs-native" + +do_compile[network] = "1" +do_compile() { + cd ${S} + rm -rf package node_modules package-lock.json + npm install + npm run build +} + +WAM_APPLICATIONS_DIR = "${libdir}/wam_apps" + +do_install() { + install -d ${D}${WAM_APPLICATIONS_DIR}/${PN} + cp -R --no-dereference --preserve=mode,links ${S}/dist/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + +FILES:${PN} = "${WAM_APPLICATIONS_DIR}/${PN}" diff --git a/recipes-demo/html5-mixer/html5-mixer_git.bb b/recipes-demo/html5-mixer/html5-mixer_git.bb new file mode 100644 index 00000000..fe45ef1a --- /dev/null +++ b/recipes-demo/html5-mixer/html5-mixer_git.bb @@ -0,0 +1,40 @@ +SUMMARY = "AGL HTML5 mixer Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-mixer/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" +B = "${WORKDIR}/build" + +SRC_URI = " \ + git://gerrit.automotivelinux.org/gerrit/apps/html5-mixer;protocol=https;branch=master \ +" +SRCREV = "e57fc753b3a083ddea52dbe4cd003261e836b2d4" + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-mixer" +AGL_APP_NAME = "HTML5 Mixer" + +DEPENDS = "nodejs-native protobuf-native" + +do_compile[network] = "1" +do_compile() { + cd ${S} + rm -rf package node_modules package-lock.json + npm install + npm run generate-grpc + npm run build +} + +WAM_APPLICATIONS_DIR = "${libdir}/wam_apps" + +do_install() { + install -d ${D}${WAM_APPLICATIONS_DIR}/${PN} + cp -R --no-dereference --preserve=mode,links ${S}/dist/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + +FILES:${PN} = "${WAM_APPLICATIONS_DIR}/${PN}" diff --git a/recipes-demo/html5-settings/html5-settings_git.bb b/recipes-demo/html5-settings/html5-settings_git.bb new file mode 100644 index 00000000..ff94276d --- /dev/null +++ b/recipes-demo/html5-settings/html5-settings_git.bb @@ -0,0 +1,39 @@ +SUMMARY = "AGL HTML5 settings Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-settings/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" +B = "${WORKDIR}/build" + +SRC_URI = " \ + git://gerrit.automotivelinux.org/gerrit/apps/html5-settings;protocol=https;branch=master \ +" +SRCREV = "69af4d9b9b209fcb33ef9071ddfa8561106044c2" + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-settings" +AGL_APP_NAME = "HTML5 Settings" + +DEPENDS = "nodejs-native" + +do_compile[network] = "1" +do_compile() { + cd ${S} + rm -rf package node_modules package-lock.json + npm install + npm run build +} + +WAM_APPLICATIONS_DIR = "${libdir}/wam_apps" + +do_install() { + install -d ${D}${WAM_APPLICATIONS_DIR}/${PN} + cp -R --no-dereference --preserve=mode,links ${S}/dist/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + +FILES:${PN} = "${WAM_APPLICATIONS_DIR}/${PN}" diff --git a/recipes-demo/hvac/hvac/hvac.conf b/recipes-demo/hvac/hvac/hvac.conf new file mode 100644 index 00000000..dfecdc50 --- /dev/null +++ b/recipes-demo/hvac/hvac/hvac.conf @@ -0,0 +1,2 @@ +[kuksa-client] +authorization = "/etc/xdg/AGL/hvac/hvac.token" diff --git a/recipes-demo/hvac/hvac/hvac.json b/recipes-demo/hvac/hvac/hvac.json new file mode 100644 index 00000000..20d842a6 --- /dev/null +++ b/recipes-demo/hvac/hvac/hvac.json @@ -0,0 +1,10 @@ +{ + "sub": "local dev", + "iss": "createToken.py", + "aud": [ + "kuksa.val" + ], + "iat": 1516239022, + "exp": 1767225599, + "scope": "actuate:Vehicle.Cabin.HVAC" +} diff --git a/recipes-demo/hvac/hvac/hvac.token b/recipes-demo/hvac/hvac/hvac.token new file mode 100644 index 00000000..76a554f8 --- /dev/null +++ b/recipes-demo/hvac/hvac/hvac.token @@ -0,0 +1 @@ +eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZTpWZWhpY2xlLkNhYmluLkhWQUMifQ.mDJd7Xn2C6xH9BRTURC2LtN_wlUgq3hJxBWNq8Dpelq43-4qDrNtfOEg2VV5wBcXimg64TwnopCHauqKyilgDt1q0VFIH9vcpp2m8QMV9Z06tR8A3zAJJ9DX4qU3WluY_STR5lnzRwvIW9fuZmyJ_msdnUB3vLp7bS47uekE6rX0OwoBzrw2Z38D5dnLilR4uknwMdWCVciBIg00xyj6hkufHyIyvgVI2Yfl8XMLgdklmgGIYRb3ljPxHsZ8MQkULbjOWsdRKJNqHP-lU17e9avzvBBXecakB0-Q-QSkuZr5H8gWLJG1a6jfcgbah1JfLJVkKWjX9knGT5csvXMGt7Mf9bGg43xb2bPkolKnmEXIlRxWyXGr_DSLmrVMukY2G_cmpj4E1v2cyyu6AtzhGyli3BD1O7ZTywZlLdGvrhxlQ1FU22OPLV8yyUoppGZLyAF_4tUaftcXXoE1HbqgzpvlPp7leB-pwmNTr9-wT8D5YAt5E5YrWGZOH6OYg-oV9Hl7JU-2zfFdm0stK_6P5D1xt0kHEjbML16SGJVO49aoeP8Fj_cNG5tc7GqHOkHBWlH7YUx2Ty4PLd91DGGHkhA-69vGs2Fg3ljpej-IHbsY269HTQd7v_wyQk_rEDMNqsOssjuFVHEd8vzdmQ-hG5BB5d_oWtCww6AAWqIlIOo
\ No newline at end of file diff --git a/recipes-demo/hvac/hvac_git.bb b/recipes-demo/hvac/hvac_git.bb new file mode 100644 index 00000000..2ac6a69b --- /dev/null +++ b/recipes-demo/hvac/hvac_git.bb @@ -0,0 +1,50 @@ +SUMMARY = "HVAC application" +DESCRIPTION = "AGL demonstration HVAC application" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/hvac" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = " \ + qttools-native \ + qtbase \ + qtdeclarative \ + qtquickcontrols2 \ + libqtappfw \ +" + +PV = "2.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/hvac;protocol=https;branch=${AGL_BRANCH} \ + file://hvac.conf \ + file://hvac.token \ +" +SRCREV = "d37674bb6dbb5ceb15c650a0344b0caf624963bc" + +S = "${WORKDIR}/git" + +inherit qmake5 pkgconfig agl-app + +AGL_APP_NAME = "HVAC" + +do_install:append() { + # Currently using default global client and CA certificates + # for KUKSA.val SSL, installing app specific ones would go here. + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/hvac + install -m 0644 ${WORKDIR}/hvac.conf ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/hvac.token ${D}${sysconfdir}/xdg/AGL/hvac/ +} + +RDEPENDS:${PN} += " \ + qtwayland \ + qtbase-qmlplugins \ + qtgraphicaleffects-qmlplugins \ + qtquickcontrols2-agl-style \ + libqtappfw \ +" diff --git a/recipes-demo/launcher/files/launcher.service b/recipes-demo/launcher/files/launcher.service new file mode 100644 index 00000000..00dfd9ad --- /dev/null +++ b/recipes-demo/launcher/files/launcher.service @@ -0,0 +1,13 @@ +[Unit] +Requires=homescreen.service applaunchd.service +After=homescreen.service applaunchd.service + +[Service] +Type=simple +User=agl-driver +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStart=/usr/bin/launcher +Restart=on-failure + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/launcher/launcher_git.bb b/recipes-demo/launcher/launcher_git.bb new file mode 100644 index 00000000..c46a4a18 --- /dev/null +++ b/recipes-demo/launcher/launcher_git.bb @@ -0,0 +1,45 @@ +SUMMARY = "AGL Launcher Application" +DESCRIPTION = "AGL Launcher Application build with recipe method" +HOMEPAGE = "https://git.automotivelinux.org/apps/launcher" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +DEPENDS = "\ + qtbase \ + qtdeclarative \ + qtquickcontrols2 \ + libqtappfw \ + wayland-native \ + wayland \ + qtwayland \ + qtwayland-native \ + agl-compositor \ + json-c \ + applaunchd \ +" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/launcher;protocol=https;branch=${AGL_BRANCH} \ + file://launcher.service \ +" +SRCREV = "4be88c049f31b7659e09223857b92ca531835039" + +S = "${WORKDIR}/git" + +inherit qmake5 systemd pkgconfig + +PATH:prepend = "${STAGING_DIR_NATIVE}${OE_QMAKE_PATH_QT_BINS}:" + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_install:append() { + install -D -m0644 ${WORKDIR}/launcher.service ${D}${systemd_system_unitdir}/launcher.service +} + +RDEPENDS:${PN} += " \ + libqtappfw \ + applaunchd \ + homescreen \ +" diff --git a/recipes-demo/libqtappfw/libqtappfw_git.bb b/recipes-demo/libqtappfw/libqtappfw_git.bb new file mode 100644 index 00000000..85d20f41 --- /dev/null +++ b/recipes-demo/libqtappfw/libqtappfw_git.bb @@ -0,0 +1,41 @@ +SUMMARY = "AGL Qt AppFW Library" +DESCRIPTION = "libqtappfw" +HOMEPAGE = "http://docs.automotivelinux.org" +SECTION = "libs" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = " \ + qtbase \ + qtbase-native \ + qtdeclarative \ + qtwebsockets \ + glib-2.0 \ + bluez-glib \ + connman-glib \ + libmpdclient \ + protobuf-native \ + grpc-native \ + protobuf \ + grpc \ + kuksa-databroker \ +" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/libqtappfw;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "4694b211569e15dc8aa4e75b6fb70e75946e766d" +S = "${WORKDIR}/git" + +# PV needs to be modified with SRCPV to work AUTOREV correctly +PV = "2.0.1+git${SRCPV}" + +inherit meson pkgconfig + +EXTRA_OEMESON += "-Dprotos=${STAGING_INCDIR}" + +RRECOMMENDS:${PN} += " \ + bluez5 \ + connman \ + ${@bb.utils.contains('AGL_FEATURES', 'agl-kvm-host-audio', '', 'mpd', d)} \ +" + +BBCLASSEXTEND = "nativesdk" diff --git a/recipes-demo/mediaplayer/mediaplayer/mediaplayer.conf b/recipes-demo/mediaplayer/mediaplayer/mediaplayer.conf new file mode 100644 index 00000000..ef4021ff --- /dev/null +++ b/recipes-demo/mediaplayer/mediaplayer/mediaplayer.conf @@ -0,0 +1,2 @@ +[kuksa-client] +authorization = "/etc/xdg/AGL/mediaplayer/mediaplayer.token" diff --git a/recipes-demo/mediaplayer/mediaplayer/mediaplayer.json b/recipes-demo/mediaplayer/mediaplayer/mediaplayer.json new file mode 100644 index 00000000..913aed08 --- /dev/null +++ b/recipes-demo/mediaplayer/mediaplayer/mediaplayer.json @@ -0,0 +1,10 @@ +{ + "sub": "local dev", + "iss": "createToken.py", + "aud": [ + "kuksa.val" + ], + "iat": 1516239022, + "exp": 1767225599, + "scope": "read:Vehicle.Cabin.SteeringWheel.Switches" +} diff --git a/recipes-demo/mediaplayer/mediaplayer/mediaplayer.token b/recipes-demo/mediaplayer/mediaplayer/mediaplayer.token new file mode 100644 index 00000000..41b53374 --- /dev/null +++ b/recipes-demo/mediaplayer/mediaplayer/mediaplayer.token @@ -0,0 +1 @@ +eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoicmVhZDpWZWhpY2xlLkNhYmluLlN0ZWVyaW5nV2hlZWwuU3dpdGNoZXMifQ.Wqc1IMUcYlw9wrE4esdshe3rbUKOXcg-Jk6st2qX6POZ_27zg-AXse3Z3VQOjZX0mDpmAn_NMd5Fm8enUPy9Gvda0ZzyKkA_4zuKLw7kk3NVqUpY6g0kYVWsvNuG5qb4gM26zyUI1k2fmfAHRBJCLaxWCF2yHQd5MPomuDl271tj9IrA3jFpUxdl63jgKGb8KHRE29JWu2Gy_1C0zDqeaUaj4htcap3TfS9yPh95qlrvQRcETc9bUgeBOzaeHklIt_kqtZobGaAEH21RzAYYDed3UgbefVs_VyWBMxKbb3tOeFABwpPUqCYjL5kPnPeCODqSD3BI5OzbJIEwZGgAmJvXWPkF8ayDMZmMwp0ud4GvXnUugxhlPzmt1ysPb6zb6yUjNvXeH4my57fZg8uFjCmyA3OHME3VTvfhwycBK44I-_gYwdBK48pm2ak1X4FaPYjGYM4tqbI1tsAh6D3KSXAkEWAUAa2FR8efoh5ERsL-9Jef2_lui_4B1vIJCNA3-z9cG6Gg1HCJgGh4NHtcb4bBAyXA_3AIAOsDlA2FmMqCTjaL2s7CFLaxa2QdJoYymqPGMmWq4Qz0mmVf11i9e3lsFlpInrYSZyVSenRjNb9kFCp9MyOeVLHZhRDG90EkQZl4ONuGON7WhoornioFq5ybA35hTBHiD0TStShry7E
\ No newline at end of file diff --git a/recipes-demo/mediaplayer/mediaplayer_git.bb b/recipes-demo/mediaplayer/mediaplayer_git.bb new file mode 100644 index 00000000..976dcc8d --- /dev/null +++ b/recipes-demo/mediaplayer/mediaplayer_git.bb @@ -0,0 +1,38 @@ +SUMMARY = "Media Player application" +DESCRIPTION = "AGL demonstration Media Player application" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/mediaplayer" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = "qtquickcontrols2 libqtappfw" + +PV = "2.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/mediaplayer;protocol=https;branch=${AGL_BRANCH} \ + file://mediaplayer.conf \ + file://mediaplayer.token \ +" +SRCREV = "0aefba20fe07dbb79d7b3683ab38c0b0b313a655" + +S = "${WORKDIR}/git" + +inherit qmake5 pkgconfig agl-app + +AGL_APP_NAME = "Mediaplayer" + +do_install:append() { + # Currently using default global client and CA certificates + # for KUKSA.val SSL, installing app specific ones would go here. + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/mediaplayer + install -m 0644 ${WORKDIR}/mediaplayer.conf ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/mediaplayer.token ${D}${sysconfdir}/xdg/AGL/mediaplayer/ +} + +RDEPENDS:${PN} += "libqtappfw mpd" diff --git a/recipes-demo/messaging/messaging_git.bb b/recipes-demo/messaging/messaging_git.bb new file mode 100644 index 00000000..972e9b82 --- /dev/null +++ b/recipes-demo/messaging/messaging_git.bb @@ -0,0 +1,22 @@ +SUMMARY = "Messaging application" +DESCRIPTION = "AGL demonstration Messaging application" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/messaging" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = "qtquickcontrols2 libqtappfw" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/messaging;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "e58b0382de8e665d64b8e3486022a6bcb0572823" + +S = "${WORKDIR}/git" + +inherit qmake5 pkgconfig agl-app + +AGL_APP_NAME = "Messaging" + +RDEPENDS:${PN} += "libqtappfw" diff --git a/recipes-demo/native-shell-client/files/native-shell-client.service b/recipes-demo/native-shell-client/files/native-shell-client.service new file mode 100644 index 00000000..eff62011 --- /dev/null +++ b/recipes-demo/native-shell-client/files/native-shell-client.service @@ -0,0 +1,13 @@ +[Unit] +Requires=agl-compositor.service +After=agl-compositor.service + +[Service] +Type=simple +User=agl-driver +Environment=XDG_RUNTIME_DIR=/run/user/1001 +ExecStart=/usr/bin/native-shell-client +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/recipes-demo/native-shell-client/native-shell-client_agldemo.inc b/recipes-demo/native-shell-client/native-shell-client_agldemo.inc new file mode 100644 index 00000000..4c1dc101 --- /dev/null +++ b/recipes-demo/native-shell-client/native-shell-client_agldemo.inc @@ -0,0 +1,13 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI += "file://native-shell-client.service" + +inherit systemd + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/native-shell-client.service ${D}${systemd_system_unitdir}/native-shell-client.service +} + +RCONFLICTS:${PN} = "homescreen" diff --git a/recipes-demo/native-shell-client/native-shell-client_git.bbappend b/recipes-demo/native-shell-client/native-shell-client_git.bbappend new file mode 100644 index 00000000..0f2cf759 --- /dev/null +++ b/recipes-demo/native-shell-client/native-shell-client_git.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'native-shell-client_agldemo.inc', '', d)} diff --git a/recipes-demo-hmi/navigation/ondemandnavi-config/naviconfig.ini b/recipes-demo/navigation/ondemandnavi-config/naviconfig.ini index 356c6ae6..f99c4483 100644 --- a/recipes-demo-hmi/navigation/ondemandnavi-config/naviconfig.ini +++ b/recipes-demo/navigation/ondemandnavi-config/naviconfig.ini @@ -4,6 +4,6 @@ "interval":100, "latitude":36.1363, "longitude":-115.151, - "mapStyleUrls":"mapbox://styles/v1/mapbox/streets-v11", + "mapStyleUrls":"styles/v1/mapbox/streets-v11", "enableOSM":true } diff --git a/recipes-demo-hmi/navigation/ondemandnavi-config_1.0.bb b/recipes-demo/navigation/ondemandnavi-config_1.0.bb index 212971f2..644102ed 100644 --- a/recipes-demo-hmi/navigation/ondemandnavi-config_1.0.bb +++ b/recipes-demo/navigation/ondemandnavi-config_1.0.bb @@ -11,11 +11,14 @@ SRC_URI = "file://naviconfig.ini \ inherit allarch -MAPBOX_ACCESS_TOKEN ?= "Please set mapbox access token" +MAPBOX_ACCESS_TOKEN ?= "" do_compile[noexec] = "1" do_install () { install -D -m 644 ${WORKDIR}/naviconfig.ini ${D}${sysconfdir}/naviconfig.ini - sed -i -e 's/MAPBOX_ACCESS_TOKEN/${MAPBOX_ACCESS_TOKEN}/' ${D}${sysconfdir}/naviconfig.ini + if [ -n "${MAPBOX_ACCESS_TOKEN}" ]; then + sed -i -e 's/MAPBOX_ACCESS_TOKEN/${MAPBOX_ACCESS_TOKEN}/;s/\("enableOSM":\)true/\1false/' \ + ${D}${sysconfdir}/naviconfig.ini + fi } diff --git a/recipes-demo/navigation/ondemandnavi/navigation.conf b/recipes-demo/navigation/ondemandnavi/navigation.conf new file mode 100644 index 00000000..00905f75 --- /dev/null +++ b/recipes-demo/navigation/ondemandnavi/navigation.conf @@ -0,0 +1,2 @@ +[kuksa-client] +authorization = "/etc/xdg/AGL/navigation/navigation.token" diff --git a/recipes-demo/navigation/ondemandnavi/navigation.conf.kvm-demo b/recipes-demo/navigation/ondemandnavi/navigation.conf.kvm-demo new file mode 100644 index 00000000..6da2579d --- /dev/null +++ b/recipes-demo/navigation/ondemandnavi/navigation.conf.kvm-demo @@ -0,0 +1,4 @@ +[kuksa-client] +hostname = "172.16.10.1" +tls-server-name = "localhost" +authorization = "/etc/xdg/AGL/navigation/navigation.token" diff --git a/recipes-demo/navigation/ondemandnavi/navigation.json b/recipes-demo/navigation/ondemandnavi/navigation.json new file mode 100644 index 00000000..5fe18308 --- /dev/null +++ b/recipes-demo/navigation/ondemandnavi/navigation.json @@ -0,0 +1,10 @@ +{ + "sub": "local dev", + "iss": "createToken.py", + "aud": [ + "kuksa.val" + ], + "iat": 1516239022, + "exp": 1767225599, + "scope": "provide:Vehicle.Cabin.Infotainment.Navigation provide:Vehicle.CurrentLocation" +} diff --git a/recipes-demo/navigation/ondemandnavi/navigation.token b/recipes-demo/navigation/ondemandnavi/navigation.token new file mode 100644 index 00000000..f6edfdf2 --- /dev/null +++ b/recipes-demo/navigation/ondemandnavi/navigation.token @@ -0,0 +1 @@ +eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZTpWZWhpY2xlLkNhYmluLkluZm90YWlubWVudC5OYXZpZ2F0aW9uLkRlc3RpbmF0aW9uU2V0IHByb3ZpZGU6VmVoaWNsZS5DYWJpbi5JbmZvdGFpbm1lbnQuTmF2aWdhdGlvbiBwcm92aWRlOlZlaGljbGUuQ3VycmVudExvY2F0aW9uIn0.hvIPaWSJBwwDEaWKxX6MAzrmZ23PRT3bWvmhujDoT43tHv2i2fSRv4U_Mlv5wenqwcn0J4XA_mdqQdtw5xtyw6ZnNSgKiSVi3QxNkm-VTuvHv4uL6-X58ot8rI6PeiJu92TQHkMUKuaXUKoyYWIlNLEZNQKD5aRhbrF0psSJNml7NbXh8T8-7BepEOb3yb6xWWFRrp0cw6v6LgNTLnxmKcyROo-syrmrV7s3x6WK-u0E-c0lqf1FzMox23elpwKPpf5KxSvc0CDeZ9IVy2iNhi-s1ubkKNEJ9RS-eyw3bbvQ_Ny7hrPbaAgce11ci4FV5cR-MPt2IAOZlQVk0zAhqENDEl25q1ME_AntodJjxy2QNBqBFTawRV6KzZvesiBrTXYPpzUuU39Wog7AuwUvhYDPyJfld8a9kqBuwbA0MUmGMd0HXbAmtIJq3fjFQstFye-m3If1BgOos202YGUV6HLtVI9vleT3Vot6Ztp70rkmZ53R447-0Wh_YQeu0ljEbyARCnsXXFbMFzKwm7K59ouK_8_hCcZhvhZ20KCjgG382PBc7cM8HcUz3sOukGWZlh5BIm6huZtoQXUKhG2wI1q678L6kZDrNOZmxl7AUucaYb_uzotAi4U-jKvEO2qKtGiV-DGzHKulwSBZIg86yprkMXn99bnMxNgXav5bYYk
\ No newline at end of file diff --git a/recipes-demo/navigation/ondemandnavi_git.bb b/recipes-demo/navigation/ondemandnavi_git.bb new file mode 100644 index 00000000..7bfa0007 --- /dev/null +++ b/recipes-demo/navigation/ondemandnavi_git.bb @@ -0,0 +1,73 @@ +SUMMARY = "Navigation application." +DESCRIPTION = "AGL demonstration Navigation application based on QtLocation widget." +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/ondemandnavi" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = "qtquickcontrols2 qtlocation libqtappfw" + +PV = "2.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/ondemandnavi;protocol=https;branch=${AGL_BRANCH} \ + file://navigation.conf \ + file://navigation.conf.kvm-demo \ + file://navigation.token \ +" +SRCREV = "d6b883ef6bdb63fb501b03d64c9a32bc29b7b2c7" + +S = "${WORKDIR}/git" + +inherit qmake5 pkgconfig agl-app update-alternatives + +AGL_APP_ID = "navigation" +AGL_APP_NAME = "Navigation" + +do_install:append() { + # Currently using default global client and CA certificates + # for KUKSA.val SSL, installing app specific ones would go here. + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/navigation + install -m 0644 ${WORKDIR}/navigation.conf ${D}${sysconfdir}/xdg/AGL/navigation.conf.default + install -m 0644 ${WORKDIR}/navigation.conf.kvm-demo ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/navigation.token ${D}${sysconfdir}/xdg/AGL/navigation/ +} + +ALTERNATIVE_LINK_NAME[navigation.conf] = "${sysconfdir}/xdg/AGL/navigation.conf" + +PACKAGE_BEFORE_PN += "${PN}-conf ${PN}-conf-kvm-demo" + +FILES:${PN}-conf += "${sysconfdir}/xdg/AGL/navigation.conf.default" +RDEPENDS:${PN}-conf = "${PN}" +RPROVIDES:${PN}-conf = "navigation.conf" +RCONFLICTS:${PN}-conf = "${PN}-conf-kvm-demo" +ALTERNATIVE:${PN}-conf = "navigation.conf" +ALTERNATIVE_TARGET_${PN}-conf = "${sysconfdir}/xdg/AGL/navigation.conf.default" + +FILES:${PN}-conf-kvm-demo += "${sysconfdir}/xdg/AGL/navigation.conf.kvm-demo" +RDEPENDS:${PN}-conf-kvm-demo = "${PN}" +RPROVIDES:${PN}-conf-kvm-demo = "navigation.conf" +RCONFLICTS:${PN}-conf-kvm-demo = "${PN}-conf" +ALTERNATIVE:${PN}-conf-kvm-demo = "navigation.conf" +ALTERNATIVE_TARGET_${PN}-conf-kvm-demo = "${sysconfdir}/xdg/AGL/navigation.conf.kvm-demo" + +RDEPENDS:${PN} += " \ + qtwayland \ + qtbase-qmlplugins \ + qtgraphicaleffects-qmlplugins \ + qtquickcontrols-qmlplugins \ + qtquickcontrols2-qmlplugins \ + qtquickcontrols2-agl \ + qtquickcontrols2-agl-style \ + qtlocation \ + flite \ + libqtappfw \ + openjtalk \ + gstreamer1.0 \ + ondemandnavi-config \ +" diff --git a/recipes-demo/navigation/tbtnavi/kvm.conf b/recipes-demo/navigation/tbtnavi/kvm.conf new file mode 100644 index 00000000..324bac37 --- /dev/null +++ b/recipes-demo/navigation/tbtnavi/kvm.conf @@ -0,0 +1,3 @@ +[Unit] +Wants=network-online.target flutter-ics-homescreen.service +After=network-online.target flutter-ics-homescreen.service diff --git a/recipes-demo/navigation/tbtnavi/tbtnavi.conf b/recipes-demo/navigation/tbtnavi/tbtnavi.conf new file mode 100644 index 00000000..a6e97134 --- /dev/null +++ b/recipes-demo/navigation/tbtnavi/tbtnavi.conf @@ -0,0 +1,2 @@ +[kuksa-client] +authorization = "/etc/xdg/AGL/tbtnavi/tbtnavi.token" diff --git a/recipes-demo/navigation/tbtnavi/tbtnavi.conf.kvm-demo b/recipes-demo/navigation/tbtnavi/tbtnavi.conf.kvm-demo new file mode 100644 index 00000000..6e891faf --- /dev/null +++ b/recipes-demo/navigation/tbtnavi/tbtnavi.conf.kvm-demo @@ -0,0 +1,4 @@ +[kuksa-client] +hostname = "172.16.10.1" +tls-server-name = "localhost" +authorization = "/etc/xdg/AGL/tbtnavi/tbtnavi.token" diff --git a/recipes-demo/navigation/tbtnavi/tbtnavi.json b/recipes-demo/navigation/tbtnavi/tbtnavi.json new file mode 100644 index 00000000..09084cef --- /dev/null +++ b/recipes-demo/navigation/tbtnavi/tbtnavi.json @@ -0,0 +1,10 @@ +{ + "sub": "local dev", + "iss": "createToken.py", + "aud": [ + "kuksa.val" + ], + "iat": 1516239022, + "exp": 1767225599, + "scope": "read:Vehicle.Cabin read:Vehicle.CurrentLocation read:Vehicle.Speed read:Vehicle.Powertrain.CombustionEngine.Speed" +} diff --git a/recipes-demo/navigation/tbtnavi/tbtnavi.service b/recipes-demo/navigation/tbtnavi/tbtnavi.service new file mode 100644 index 00000000..fb77843c --- /dev/null +++ b/recipes-demo/navigation/tbtnavi/tbtnavi.service @@ -0,0 +1,13 @@ +[Unit] +Requires=agl-compositor.service +After=agl-compositor.service + +[Service] +Type=simple +User=agl-driver +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStart=/usr/bin/tbtnavi +Restart=on-failure + +[Install] +WantedBy=graphical.target diff --git a/recipes-demo/navigation/tbtnavi/tbtnavi.token b/recipes-demo/navigation/tbtnavi/tbtnavi.token new file mode 100644 index 00000000..fe39a4f7 --- /dev/null +++ b/recipes-demo/navigation/tbtnavi/tbtnavi.token @@ -0,0 +1 @@ +eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoicmVhZDpWZWhpY2xlLkNhYmluIHJlYWQ6VmVoaWNsZS5DdXJyZW50TG9jYXRpb24gcmVhZDpWZWhpY2xlLlNwZWVkIHJlYWQ6VmVoaWNsZS5Qb3dlcnRyYWluLkNvbWJ1c3Rpb25FbmdpbmUuU3BlZWQifQ.hIOyxqwWAshNMRo_5CIWs_hBdlcroocC_ytcdKujBoB-Xx8ntOW1Kxzxy2-WIC5n0sYDKibayIe4jxMjohe9JrM6KcZqhDbuAEhANFtlact-rTX-GJ4sjSsEsOOosIO60HAEmC27F4tPYgcVHumLC5diMyXK_2L9YYbXxWNxBnjWAVYScsd0iD7EodM_c-0ayVBEMRh6izJVGHm1pPAfgQQMFVtO3OPST2-RK55yumkeH3QswmaMyUDf8veNN8s-pxpwlsDqjcw4hHZ9okOCstq162gUIYmsh00bYyGtYPTcsWSpacXWcLupqeP1MIZwqADhGLRqrzo9pD9hCBxMmHPE3IADhGtIo_Hbh9h5NB6O9MjK4afi9omBtxqvlo6Yhz8v-kQDe1BjHaTWIifnvFPUXpy-eEKZq7PB4KLpn6EOiCHDDuB85qS_gg3lH6GJ3GKoOaZ6oMziM7zFWf7PHkJJk1C7jy8m3HFt-YQm0St9SOAKReRr3V_7nWUDd6lCrBLJrTGFz2dySGCSHH2YQst85aocaAQquqo4LnCPs_lyOQ929e3Hm3nGhcd-ksVK6wdkXAFN7Clsek6V8wb_GjbzhFPZ79sk9yyLWXwU19_XhX0bs31a8OhVYQt3ACySWzinpyLFrp7lbLb_JSa43zD5P1XNUJxNcp58Anzzv28
\ No newline at end of file diff --git a/recipes-demo/navigation/tbtnavi_git.bb b/recipes-demo/navigation/tbtnavi_git.bb new file mode 100644 index 00000000..b3703c53 --- /dev/null +++ b/recipes-demo/navigation/tbtnavi_git.bb @@ -0,0 +1,88 @@ +SUMMARY = "AGL Reference Navigation Cluster Streaming application" +DESCRIPTION = "Demo AGL turn by turn cluster navigation application based on QtLocation widget." +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/admin/repos/apps/tbtnavi" +SECTION = "apps" + +LICENSE = "Apache-2.0 & ISC & BSD-3-Clause & BSL-1.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984 \ + file://LICENSE.mapbox-cheap-ruler-cpp;md5=761263ee6bdc98e8697d9fbc897021ba \ + file://LICENSE.mapbox-geometry.hpp;md5=6e44f5d6aeec54f40fc84eebe3c6fc6c \ + file://LICENSE.mapbox-variant;md5=79558839a9db3e807e4ae6f8cd100c1c \ + file://include/mapbox/recursive_wrapper.hpp;beginline=4;endline=13;md5=cd3341aae76c0cf8345935abd20f0051 \ +" + +DEPENDS = " \ + qtbase \ + qtquickcontrols2 \ + qtlocation \ + libqtappfw \ + qtwayland-native \ + protobuf \ + grpc \ + grpc-native \ +" + +PV = "2.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/tbtnavi;protocol=https;branch=${AGL_BRANCH} \ + file://tbtnavi.service \ + file://tbtnavi.conf \ + file://tbtnavi.conf.kvm-demo \ + file://tbtnavi.token \ + file://kvm.conf \ +" +SRCREV = "f00c1e19f5c4cbcd185c8043f3062612bf1537f7" + +S = "${WORKDIR}/git" + +inherit meson systemd pkgconfig update-alternatives + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service + + install -D -m 0644 ${WORKDIR}/kvm.conf ${D}${systemd_system_unitdir}/${BPN}.service.d/kvm.conf + + # Currently using default global client and CA certificates + # for KUKSA.val SSL, installing app specific ones would go here. + + # VIS authorization token file for KUKSA.val should ideally not + # be readable by other users, but currently that's not doable + # until a packaging/sandboxing/MAC scheme is (re)implemented or + # something like OAuth is plumbed in as an alternative. + install -d ${D}${sysconfdir}/xdg/AGL/tbtnavi + install -m 0644 ${WORKDIR}/tbtnavi.conf ${D}${sysconfdir}/xdg/AGL/tbtnavi.conf.default + install -m 0644 ${WORKDIR}/tbtnavi.conf.kvm-demo ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/tbtnavi.token ${D}${sysconfdir}/xdg/AGL/tbtnavi/ +} + +ALTERNATIVE_LINK_NAME[tbtnavi.conf] = "${sysconfdir}/xdg/AGL/tbtnavi.conf" + +RDEPENDS:${PN} += " \ + qtwayland \ + qtbase-qmlplugins \ + qtgraphicaleffects-qmlplugins \ + qtlocation \ + ondemandnavi-config \ + libqtappfw \ +" + +PACKAGE_BEFORE_PN += "${PN}-conf ${PN}-conf-kvm-demo" + +FILES:${PN}-conf += "${sysconfdir}/xdg/AGL/tbtnavi.conf.default" +RDEPENDS:${PN}-conf = "${PN}" +RPROVIDES:${PN}-conf = "tbtnavi.conf" +RCONFLICTS:${PN}-conf = "${PN}-conf-kvm-demo" +ALTERNATIVE:${PN}-conf = "tbtnavi.conf" +ALTERNATIVE_TARGET_${PN}-conf = "${sysconfdir}/xdg/AGL/tbtnavi.conf.default" + +FILES:${PN}-conf-kvm-demo += " \ + ${sysconfdir}/xdg/AGL/tbtnavi.conf.kvm-demo \ + ${systemd_system_unitdir}/tbtnavi.service.d/kvm.conf \ +" +RDEPENDS:${PN}-conf-kvm-demo = "${PN}" +RPROVIDES:${PN}-conf-kvm-demo = "tbtnavi.conf" +RCONFLICTS:${PN}-conf-kvm-demo = "${PN}-conf" +ALTERNATIVE:${PN}-conf-kvm-demo = "tbtnavi.conf" +ALTERNATIVE_TARGET_${PN}-conf-kvm-demo = "${sysconfdir}/xdg/AGL/tbtnavi.conf.kvm-demo" diff --git a/recipes-demo/phone/phone_git.bb b/recipes-demo/phone/phone_git.bb new file mode 100644 index 00000000..4c59bcbc --- /dev/null +++ b/recipes-demo/phone/phone_git.bb @@ -0,0 +1,24 @@ +SUMMARY = "Phone application" +DESCRIPTION = "AGL demonstration Phone application" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/phone" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = "qtquickcontrols2 libqtappfw gstreamer1.0" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/phone;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "bfcc2fa194474a7bc317583072b62c977ae0fc14" + +S = "${WORKDIR}/git" + +inherit qmake5 pkgconfig agl-app + +AGL_APP_NAME = "Phone" + +FILES:${PN} += "${datadir}/sounds/" + +RDEPENDS:${PN} += "libqtappfw" diff --git a/recipes-demo/qtquickcontrols2-agl-style/qtquickcontrols2-agl-style_git.bb b/recipes-demo/qtquickcontrols2-agl-style/qtquickcontrols2-agl-style_git.bb new file mode 100644 index 00000000..49d2e856 --- /dev/null +++ b/recipes-demo/qtquickcontrols2-agl-style/qtquickcontrols2-agl-style_git.bb @@ -0,0 +1,23 @@ +SUMMARY = "AGL QtQuickControls2 style customizations" +HOMEPAGE = "https://git.automotivelinux.org/src/qtquickcontrols2-agl-style" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=815ca599c9df247a0c7f619bab123dad" + +DEPENDS = "qtquickcontrols2" + +PV = "1.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/qtquickcontrols2-agl-style;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "c02692a3c20d9aed1192137a67d5be882c60e71f" + +S = "${WORKDIR}/git" + +inherit qmake5 + +FILES:${PN} += "${OE_QMAKE_PATH_QML}/QtQuick/Controls.2/AGL/*" + +RDEPENDS:${PN} += " \ + qtquickcontrols-qmlplugins \ + qtquickcontrols2-qmlplugins \ + qtsvg-plugins \ +" diff --git a/recipes-demo-hmi/qtquickcontrols2-agl/qtquickcontrols2-agl_git.bb b/recipes-demo/qtquickcontrols2-agl/qtquickcontrols2-agl_git.bb index 0a432db0..79dac686 100644 --- a/recipes-demo-hmi/qtquickcontrols2-agl/qtquickcontrols2-agl_git.bb +++ b/recipes-demo/qtquickcontrols2-agl/qtquickcontrols2-agl_git.bb @@ -1,5 +1,5 @@ SUMMARY = "AGL demo custom QtQuickControls2 widgets" -HOMEPAGE = "https://git.automotivelinux.org/gerrit/#/admin/projects/src/qtquickcontrols2-agl" +HOMEPAGE = "https://git.automotivelinux.org/src/qtquickcontrols2-agl" LICENSE = "MPL-2.0" LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=815ca599c9df247a0c7f619bab123dad" @@ -10,14 +10,14 @@ PV = "1.0+git${SRCPV}" SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/qtquickcontrols2-agl;protocol=https;branch=${AGL_BRANCH}" SRCREV = "22b538aae1f69de5273f1e42a854cfab23a32b60" -S = "${WORKDIR}/git/" +S = "${WORKDIR}/git" inherit qmake5 -FILES_${PN} += "${OE_QMAKE_PATH_QML}/AGL/Demo/Controls/*" +FILES:${PN} += "${OE_QMAKE_PATH_QML}/AGL/Demo/Controls/*" -RDEPENDS_${PN} += " \ - qtquickcontrols-qmlplugins \ - qtquickcontrols2-qmlplugins \ - qtsvg-plugins \ +RDEPENDS:${PN} += " \ + qtquickcontrols-qmlplugins \ + qtquickcontrols2-qmlplugins \ + qtsvg-plugins \ " diff --git a/recipes-demo-hmi/radio/files/presets-ALS.conf b/recipes-demo/radio/files/presets-ALS.conf index ff559227..ff559227 100644 --- a/recipes-demo-hmi/radio/files/presets-ALS.conf +++ b/recipes-demo/radio/files/presets-ALS.conf diff --git a/recipes-demo-hmi/radio/files/presets-CES.conf b/recipes-demo/radio/files/presets-CES.conf index 83caeffe..83caeffe 100644 --- a/recipes-demo-hmi/radio/files/presets-CES.conf +++ b/recipes-demo/radio/files/presets-CES.conf diff --git a/recipes-demo-hmi/radio/files/presets-FOSDEM.conf b/recipes-demo/radio/files/presets-FOSDEM.conf index b88364f7..b88364f7 100644 --- a/recipes-demo-hmi/radio/files/presets-FOSDEM.conf +++ b/recipes-demo/radio/files/presets-FOSDEM.conf diff --git a/recipes-demo-hmi/radio/radio_git.bb b/recipes-demo/radio/radio_git.bb index 52a981f2..c9d8ed7a 100644 --- a/recipes-demo-hmi/radio/radio_git.bb +++ b/recipes-demo/radio/radio_git.bb @@ -1,31 +1,31 @@ -SUMMARY = "Radio for CES2017 AGL Demonstration" -DESCRIPTION = "AGL HMI Application for demonstrating Radio on AGL Distribution" +SUMMARY = "Radio application" +DESCRIPTION = "AGL demonstration Radio application" HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/radio" SECTION = "apps" -LICENSE = "Apache-2.0 & GPLv2+" -LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984 \ - file://COPYING;md5=751419260aa954499f7abaabaa882bbe" +LICENSE = "Apache-2.0 & GPL-2.0-or-later" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = "qtquickcontrols2 libqtappfw" + +PV = "1.0+git${SRCPV}" SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/radio;protocol=https;branch=${AGL_BRANCH} \ file://presets-ALS.conf \ file://presets-CES.conf \ file://presets-FOSDEM.conf \ " -SRCREV = "${AGL_APP_REVISION}" +SRCREV = "aef392d9df8bb5e4ada4b3f8f44016e8a839d154" -PV = "1.0+git${SRCPV}" S = "${WORKDIR}/git" -# build-time dependencies -DEPENDS = "qtquickcontrols2 rtl-sdr" -DEPENDS += "libhomescreen qlibwindowmanager libqtappfw" +inherit qmake5 pkgconfig agl-app -inherit qmake5 aglwgt +AGL_APP_NAME = "Radio" # ALS, CES, FOSDEM available AGL_RADIO_PRESETS_LOCALE ?= "CES" -do_install_append() { +do_install:append() { install -d ${D}${sysconfdir}/xdg/AGL install -m 0644 ${WORKDIR}/presets-CES.conf ${D}${sysconfdir}/xdg/AGL/radio-presets-CES.conf install -m 0644 ${WORKDIR}/presets-ALS.conf ${D}${sysconfdir}/xdg/AGL/radio-presets-ALS.conf @@ -33,6 +33,6 @@ do_install_append() { install -m 0644 ${WORKDIR}/presets-${AGL_RADIO_PRESETS_LOCALE}.conf ${D}${sysconfdir}/xdg/AGL/radio-presets.conf } -FILES_${PN} += "${sysconfdir}/xdg/AGL/*" +FILES:${PN} += "${sysconfdir}/xdg/AGL/*" -RDEPENDS_${PN} += "agl-service-radio" +RDEPENDS:${PN} += "libqtappfw" diff --git a/recipes-demo/settings/settings_git.bb b/recipes-demo/settings/settings_git.bb new file mode 100644 index 00000000..c090ec7f --- /dev/null +++ b/recipes-demo/settings/settings_git.bb @@ -0,0 +1,34 @@ +SUMMARY = "Settings application" +DESCRIPTION = "AGL demonstration Settings application" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/settings" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = " \ + qtbase \ + qtdeclarative \ + qtquickcontrols2 \ + qtvirtualkeyboard \ + libqtappfw \ +" + +PV = "2.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/settings;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "26dc6a8c8847248450bf902124b7cd867e027274" + +S = "${WORKDIR}/git" + +inherit qmake5 pkgconfig agl-app + +AGL_APP_NAME = "Settings" + +RDEPENDS:${PN} += " \ + qtwayland \ + qtbase-qmlplugins \ + qtgraphicaleffects-qmlplugins \ + qtquickcontrols2-agl-style \ + libqtappfw \ +" diff --git a/recipes-config/cluster-demo-simulator/files/simple_can_simulator.py b/recipes-demo/simple-can-simulator/files/simple_can_simulator.py index 83f88706..3d6c85d5 100755 --- a/recipes-config/cluster-demo-simulator/files/simple_can_simulator.py +++ b/recipes-demo/simple-can-simulator/files/simple_can_simulator.py @@ -350,13 +350,18 @@ class StatusMessageSender(object): def main(): parser = argparse.ArgumentParser(description='Simple CAN vehicle simulator.') parser.add_argument('interface', type=str, help='interface name (e.g. vcan0)') + parser.add_argument('--lin-interface', help='Separate LIN interface name (e.g. sllin0)') parser.add_argument('-v', '--verbose', help='increase output verbosity', action='store_true') args = parser.parse_args() + lin_interface = args.lin_interface + if lin_interface == None: + lin_interface = args.interface + try: can_sock = CANSocket(args.interface) diag_can_sock = CANSocket(args.interface) - steeringwheel_can_sock = CANSocket(args.interface) + steeringwheel_can_sock = CANSocket(lin_interface) except OSError as e: sys.stderr.write('Could not listen on interface {0}\n'.format(args.interface)) sys.exit(e.errno) diff --git a/recipes-demo/simple-can-simulator/simple-can-simulator.bb b/recipes-demo/simple-can-simulator/simple-can-simulator.bb new file mode 100644 index 00000000..947e0c6a --- /dev/null +++ b/recipes-demo/simple-can-simulator/simple-can-simulator.bb @@ -0,0 +1,15 @@ +DESCRIPTION = "Simulator that generates CAN messages of a driving car" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${WORKDIR}/simple_can_simulator.py;beginline=2;endline=22;md5=9bb9c582301261d21460d2bc5bb8c225" + +SRC_URI = "file://simple_can_simulator.py" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + install -d ${D}${sbindir} + install -m 0755 ${WORKDIR}/simple_can_simulator.py ${D}${sbindir} +} + +RDEPENDS:${PN} = "python3" diff --git a/recipes-demo/videoplayer/videoplayer_git.bb b/recipes-demo/videoplayer/videoplayer_git.bb new file mode 100644 index 00000000..36c83758 --- /dev/null +++ b/recipes-demo/videoplayer/videoplayer_git.bb @@ -0,0 +1,31 @@ +SUMMARY = "Video Player for AGL Demonstration" +DESCRIPTION = "AGL HMI Application for demonstrating Media Player on AGL Distribution" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/videoplayer" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/videoplayer;protocol=https;nobranch=1" +SRCREV = "2f4d09aec6531c64356a52255bcfaf8df7c4f3e4" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" + +# build-time dependencies +DEPENDS += " \ + qtquickcontrols2 \ + libqtappfw \ + qtmultimedia \ +" + +inherit qmake5 agl-app + +AGL_APP_NAME = "Video" + +RDEPENDS:${PN} += " \ + qtmultimedia \ + qtmultimedia-qmlplugins \ +" + +FILES:${PN} += "${datadir}/icons" diff --git a/recipes-demo/webapp-samples/files/appinfo-aquarium.json b/recipes-demo/webapp-samples/files/appinfo-aquarium.json new file mode 100644 index 00000000..76fdd9e3 --- /dev/null +++ b/recipes-demo/webapp-samples/files/appinfo-aquarium.json @@ -0,0 +1,11 @@ +{ + "id": "webapps-aquarium", + "title": "Aquarium", + "description": "HTML5 WebGL Aquarium sample", + "version": "0.0.0", + "vendor": "Igalia, S.L.", + "type": "web", + "main": "aquarium.html", + "uiRevision": "2", + "icon": "icon.svg" +} diff --git a/recipes-demo/webapp-samples/files/appinfo-examples.json b/recipes-demo/webapp-samples/files/appinfo-examples.json new file mode 100644 index 00000000..c1c960db --- /dev/null +++ b/recipes-demo/webapp-samples/files/appinfo-examples.json @@ -0,0 +1,11 @@ +{ + "id": "webapps-examples", + "title": "Examples", + "description": "HTML5 examples", + "version": "0.0.0", + "vendor": "Igalia, S.L.", + "type": "web", + "main": "index.html", + "uiRevision": "2", + "icon": "icon.svg" +} diff --git a/recipes-demo/webapp-samples/files/appinfo-jitsi.json b/recipes-demo/webapp-samples/files/appinfo-jitsi.json new file mode 100644 index 00000000..f5e1d808 --- /dev/null +++ b/recipes-demo/webapp-samples/files/appinfo-jitsi.json @@ -0,0 +1,11 @@ +{ + "id": "webapps-jitsi", + "title": "Jitsi", + "description": "HTML5 Jitsi sample", + "version": "0.0.0", + "vendor": "Igalia, S.L.", + "type": "web", + "main": "index.html", + "uiRevision": "2", + "icon": "icon.svg" +} diff --git a/recipes-demo/webapp-samples/files/appinfo-youtube.json b/recipes-demo/webapp-samples/files/appinfo-youtube.json new file mode 100644 index 00000000..f844bf7a --- /dev/null +++ b/recipes-demo/webapp-samples/files/appinfo-youtube.json @@ -0,0 +1,11 @@ +{ + "id": "webapps-youtube", + "title": "Youtube", + "description": "HTML5 Youtube sample", + "version": "0.0.0", + "vendor": "Igalia, S.L.", + "type": "web", + "main": "index.html", + "uiRevision": "2", + "icon": "icon.svg" +} diff --git a/recipes-demo/webapp-samples/html5-aquarium_git.bb b/recipes-demo/webapp-samples/html5-aquarium_git.bb new file mode 100644 index 00000000..0afc8514 --- /dev/null +++ b/recipes-demo/webapp-samples/html5-aquarium_git.bb @@ -0,0 +1,17 @@ +SUMMARY = "AGL HTML5 Aquarium Demo" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://aquarium/LICENSE;md5=9f0d95e61aa217eacd61ee6833cf411c" +APPINFO_FILE = "appinfo-aquarium.json" + +require webapp-samples.inc + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-aquarium" +AGL_APP_NAME = "Aquarium" + +do_install:append() { + cp -R --no-dereference --preserve=mode,links ${S}/aquarium/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + diff --git a/recipes-demo/webapp-samples/html5-examples_git.bb b/recipes-demo/webapp-samples/html5-examples_git.bb new file mode 100644 index 00000000..c2b131af --- /dev/null +++ b/recipes-demo/webapp-samples/html5-examples_git.bb @@ -0,0 +1,17 @@ +SUMMARY = "AGL HTML5 Examples" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=7ea5dd8751060d9f04d2748030c547ed" +APPINFO_FILE = "appinfo-examples.json" + +require webapp-samples.inc + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-examples" +AGL_APP_NAME = "Examples" + +do_install:append() { + cp -R --no-dereference --preserve=mode,links ${S}/examples/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + diff --git a/recipes-demo/webapp-samples/html5-jitsi_git.bb b/recipes-demo/webapp-samples/html5-jitsi_git.bb new file mode 100644 index 00000000..e382cb03 --- /dev/null +++ b/recipes-demo/webapp-samples/html5-jitsi_git.bb @@ -0,0 +1,17 @@ +SUMMARY = "AGL HTML5 Jitsi" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=7ea5dd8751060d9f04d2748030c547ed" +APPINFO_FILE = "appinfo-jitsi.json" + +require webapp-samples.inc + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-jitsi" +AGL_APP_NAME = "Jitsi" + +do_install:append() { + cp -R --no-dereference --preserve=mode,links ${S}/jitsi/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + diff --git a/recipes-demo/webapp-samples/html5-youtube_git.bb b/recipes-demo/webapp-samples/html5-youtube_git.bb new file mode 100644 index 00000000..44a96440 --- /dev/null +++ b/recipes-demo/webapp-samples/html5-youtube_git.bb @@ -0,0 +1,17 @@ +SUMMARY = "AGL HTML5 Youtube" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=7ea5dd8751060d9f04d2748030c547ed" +APPINFO_FILE = "appinfo-youtube.json" + +require webapp-samples.inc + +inherit agl-app + +AGL_APP_TEMPLATE = "agl-app-web" +AGL_APP_ID = "webapps-youtube" +AGL_APP_NAME = "Youtube" + +do_install:append() { + cp -R --no-dereference --preserve=mode,links ${S}/youtube/* ${D}${WAM_APPLICATIONS_DIR}/${PN} +} + diff --git a/recipes-demo/webapp-samples/webapp-samples.inc b/recipes-demo/webapp-samples/webapp-samples.inc new file mode 100644 index 00000000..1a74a46c --- /dev/null +++ b/recipes-demo/webapp-samples/webapp-samples.inc @@ -0,0 +1,23 @@ +HOMEPAGE = "https://github.com/AGL-web-applications/webapp-samples" +SECTION = "apps" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git" +B = "${WORKDIR}/build" + +SRC_URI = " \ + git://github.com/AGL-web-applications/webapp-samples.git;protocol=https;branch=master \ + file://${APPINFO_FILE} \ +" +SRCREV = "b24a62cc524bdec98a61acc03fc53cbab24c1571" + +WAM_APPLICATIONS_DIR="${libdir}/wam_apps" + +do_install() { + install -d ${D}${WAM_APPLICATIONS_DIR}/${PN} + install ${WORKDIR}/${APPINFO_FILE} ${D}${WAM_APPLICATIONS_DIR}/${PN}/appinfo.json +} + +FILES:${PN} = " \ + ${WAM_APPLICATIONS_DIR}/${PN} \ +" diff --git a/recipes-demo/window-management-client-grpc/window-management-client-grpc_git.bb b/recipes-demo/window-management-client-grpc/window-management-client-grpc_git.bb new file mode 100644 index 00000000..769a56f6 --- /dev/null +++ b/recipes-demo/window-management-client-grpc/window-management-client-grpc_git.bb @@ -0,0 +1,28 @@ +SUMMARY = "Window management gRPC application" +DESCRIPTION = "AGL demonstration of window management using gRPC" +HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/src/window-management-client-grpc.git" +SECTION = "apps" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984" + +DEPENDS = "qtbase qtdeclarative qtquickcontrols2 qtwayland \ + qtwayland-native libqtappfw grpc grpc-native \ + " + +PV = "2.0+git${SRCPV}" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/window-management-client-grpc.git;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "cb7aa009ef9873967152e716fb01fecc30d401f7" + +S = "${WORKDIR}/git" + +inherit meson pkgconfig + +AGL_APP_NAME = "window-management-client-grpc" + +do_install:append() { + install -d ${D}${sysconfdir}/xdg/AGL/window-management-client-grpc +} + +RDEPENDS:${PN} += "libqtappfw qtbase-qmlplugins" diff --git a/recipes-devtools/gn/gn.inc b/recipes-devtools/gn/gn.inc deleted file mode 100644 index 2728bc1e..00000000 --- a/recipes-devtools/gn/gn.inc +++ /dev/null @@ -1,21 +0,0 @@ -SUMMARY = "Meta-build system from Google" -LICENSE = "BSD" -LIC_FILES_CHKSUM = "file://LICENSE;md5=0fca02217a5d49a14dfe2d11837bb34d" - -DEPENDS = "python-native ninja-native" - -SRC_URI = "http://gsdview.appspot.com/chromium-browser-official/chromium-${PV}.tar.xz" - -S ?= "${WORKDIR}/chromium-${PV}" - -do_compile () { - cd ${S}/tools/gn - ./bootstrap/bootstrap.py -s -} - -do_install () { - install -d ${D}${bindir} - install -m 0755 out/Release/gn ${D}${bindir}/gn -} - -BBCLASSEXTEND = "native nativesdk" diff --git a/recipes-devtools/gn/gn_66.0.3340.0.r534306.bb b/recipes-devtools/gn/gn_66.0.3340.0.r534306.bb deleted file mode 100644 index d3959f23..00000000 --- a/recipes-devtools/gn/gn_66.0.3340.0.r534306.bb +++ /dev/null @@ -1,8 +0,0 @@ -require gn.inc - -S = "${WORKDIR}/chromium-ozone-wayland-dev-${PV}.igalia.1" - -SRC_URI = "https://tmp.igalia.com/chromium-tarballs/chromium-ozone-wayland-dev-${PV}.igalia.1.tar.xz" - -SRC_URI[md5sum] = "f418f4df5261cfdcf39e7901924876a2" -SRC_URI[sha256sum] = "2679c89f09394bf2df86a090958a599303562746ce9296b07c263eb16f8d9148" diff --git a/recipes-devtools/python/python3-anytree_2.8.0.bb b/recipes-devtools/python/python3-anytree_2.8.0.bb new file mode 100644 index 00000000..1b4628a9 --- /dev/null +++ b/recipes-devtools/python/python3-anytree_2.8.0.bb @@ -0,0 +1,16 @@ +SUMMARY = "Powerful and Lightweight Python Tree Data Structure" +HOMEPAGE = "https://github.com/c0fec0de/anytree" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" + +PYPI_PACKAGE = "anytree" + +SRC_URI[sha256sum] = "3f0f93f355a91bc3e6245319bf4c1d50e3416cc7a35cc1133c1ff38306bbccab" + +inherit pypi setuptools3 + +do_install:append () { + rm -f ${D}${prefix}/LICENSE +} + +BBCLASSEXTEND += "native nativesdk" diff --git a/recipes-devtools/python/python3-argparse-addons_0.7.0.bb b/recipes-devtools/python/python3-argparse-addons_0.7.0.bb new file mode 100644 index 00000000..e0ff0c3f --- /dev/null +++ b/recipes-devtools/python/python3-argparse-addons_0.7.0.bb @@ -0,0 +1,10 @@ +SUMMARY = "Additional Python argparse types and actions." +HOMEPAGE = "https://github.com/eerimoq/argparse_addons" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=515e9da3e929c7b40dd13458363110a7" + +PYPI_PACKAGE = "argparse_addons" + +SRC_URI[sha256sum] = "f5da0fe676953e39bee7a6d0a9b2f5ccdcbf9d6a6b9929997caf8f6c6b23a5fb" + +inherit pypi setuptools3 diff --git a/recipes-devtools/python/python3-can-j1939_2.0.6.bb b/recipes-devtools/python/python3-can-j1939_2.0.6.bb new file mode 100644 index 00000000..b479340a --- /dev/null +++ b/recipes-devtools/python/python3-can-j1939_2.0.6.bb @@ -0,0 +1,13 @@ +SUMMARY = "An implementation of the CAN SAE J1939 standard for Python." +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=32e7309a8200a5f4b7aec6efcfb8e77e" +PYPI_PACKAGE = "can-j1939" + +SRC_URI[sha256sum] = "beda5bf2e2502c4a7d97a989075c56b98e33e49b619ef8054ed13aca911be3d3" + +inherit pypi setuptools3 + +RDEPENDS:${PN} += " \ + python3-can \ + python3-numpy \ +" diff --git a/recipes-devtools/python/python3-cantools_39.%.bbappend b/recipes-devtools/python/python3-cantools_39.%.bbappend new file mode 100644 index 00000000..17531c73 --- /dev/null +++ b/recipes-devtools/python/python3-cantools_39.%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'python3-cantools_agldemo.inc', '', d)} diff --git a/recipes-devtools/python/python3-cantools_agldemo.inc b/recipes-devtools/python/python3-cantools_agldemo.inc new file mode 100644 index 00000000..a4c6aa3a --- /dev/null +++ b/recipes-devtools/python/python3-cantools_agldemo.inc @@ -0,0 +1,3 @@ +RDEPENDS:${PN} += "\ + python3-argparse-addons \ +" diff --git a/recipes-devtools/python/python3-deprecation_2.1.0.bb b/recipes-devtools/python/python3-deprecation_2.1.0.bb new file mode 100644 index 00000000..c4b3a1cf --- /dev/null +++ b/recipes-devtools/python/python3-deprecation_2.1.0.bb @@ -0,0 +1,12 @@ +SUMMARY = "A library to handle automated deprecations" +HOMEPAGE = "https://github.com/briancurtin/deprecation" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" + +PYPI_PACKAGE = "deprecation" + +SRC_URI[sha256sum] = "72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff" + +inherit pypi setuptools3 + +BBCLASSEXTEND += "native nativesdk" diff --git a/recipes-devtools/python/python3-graphql-core_3.2.3.bb b/recipes-devtools/python/python3-graphql-core_3.2.3.bb new file mode 100644 index 00000000..b12957a4 --- /dev/null +++ b/recipes-devtools/python/python3-graphql-core_3.2.3.bb @@ -0,0 +1,12 @@ +SUMMARY = "GraphQL implementation for Python" +HOMEPAGE = "https://github.com/graphql-python/graphql-core" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=73706fb002de2debc52328afd1688817" + +PYPI_PACKAGE = "graphql-core" + +SRC_URI[sha256sum] = "06d2aad0ac723e35b1cb47885d3e5c45e956a53bc1b209a9fc5369007fe46676" + +inherit pypi setuptools3 + +BBCLASSEXTEND += "native nativesdk" diff --git a/recipes-devtools/python/python3-grpcio_1.62.1.bbappend b/recipes-devtools/python/python3-grpcio_1.62.1.bbappend new file mode 100644 index 00000000..26036fc8 --- /dev/null +++ b/recipes-devtools/python/python3-grpcio_1.62.1.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'python3-grpcio_agldemo.inc', '', d)} diff --git a/recipes-devtools/python/python3-grpcio_agldemo.inc b/recipes-devtools/python/python3-grpcio_agldemo.inc new file mode 100644 index 00000000..8236a341 --- /dev/null +++ b/recipes-devtools/python/python3-grpcio_agldemo.inc @@ -0,0 +1,17 @@ +# For some reason the atomics presence test in the grpc build +# passes on RISC-V even though linking with libatomic is actually +# needed. There are some mentions on the web of some atomics +# support incorrectly being in the libc stub on RISC-V, so a +# fix could be tracking down if that is the case and if it has +# been fixed in newer libc. Otherwise, the compile test in grpc +# will need to be changed to some other function that is known to +# only be in libatomic on RISC-V. +# +# The next problem is that setting GRPC_PYTHON_LDFLAGS to any value +# ends up not adding linking with pthread due to the way the logic +# is set up, so we need to actually add it explicitly. The upstream +# recipe seems slightly broken in this respect. + +GRPC_LDFLAGS ?= " -lpthread" +GRPC_LDFLAGS:append:riscv64 = " -latomic" +export GRPC_PYTHON_LDFLAGS = "${GRPC_LDFLAGS}" diff --git a/recipes-devtools/python/python3-jsonpath-ng_1.5.3.bb b/recipes-devtools/python/python3-jsonpath-ng_1.5.3.bb new file mode 100644 index 00000000..4c3dfaa9 --- /dev/null +++ b/recipes-devtools/python/python3-jsonpath-ng_1.5.3.bb @@ -0,0 +1,15 @@ +SUMMARY = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." +HOMEPAGE = "https://github.com/h2non/jsonpath-ng" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +PYPI_PACKAGE = "jsonpath-ng" + +SRC_URI[sha256sum] = "a273b182a82c1256daab86a313b937059261b5c5f8c4fa3fc38b882b344dd567" + +inherit pypi setuptools3 + +RDEPENDS:${PN} += " \ + python3-ply \ + python3-six \ +" diff --git a/recipes-devtools/python/python3-py-expression-eval_0.3.14.bb b/recipes-devtools/python/python3-py-expression-eval_0.3.14.bb new file mode 100644 index 00000000..15a295f1 --- /dev/null +++ b/recipes-devtools/python/python3-py-expression-eval_0.3.14.bb @@ -0,0 +1,14 @@ +SUMMARY = "Python Mathematical Expression Evaluator" +HOMEPAGE = "https://github.com/AxiaCore/py-expression-eval" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=5a9126e7f56a0cf3247050de7f10d0f4" + +# NOTE: Pulling from github.com instead of pypi.org as the tarfiles on +# the latter do not include the LICENSE file. + +SRC_URI = "git://github.com/axiacore/py-expression-eval.git;protocol=https;branch=master" +SRCREV = "e7cfbedb3cdb1c428ae3dfbc967fe43deffa5e64" + +S = "${WORKDIR}/git" + +inherit setuptools3 diff --git a/recipes-devtools/python/python3-pyqt5_5.15.9.bbappend b/recipes-devtools/python/python3-pyqt5_5.15.9.bbappend new file mode 100644 index 00000000..408c48b3 --- /dev/null +++ b/recipes-devtools/python/python3-pyqt5_5.15.9.bbappend @@ -0,0 +1,9 @@ +# Enable SVG support +DEPENDS:append = " qtsvg" +PYQT_MODULES:append = " QtSvg" + +# Fix python interpreter paths in pyrcc5, etc., adapted from newer upstream +# recipe +do_install:append() { + sed -i "s,^exec .*python${PYTHON_BASEVERSION},exec ${bindir}/python3," ${D}/${bindir}/* +} diff --git a/recipes-devtools/python/python3-qtpy_2.4.0.bb b/recipes-devtools/python/python3-qtpy_2.4.0.bb new file mode 100644 index 00000000..8e454cb3 --- /dev/null +++ b/recipes-devtools/python/python3-qtpy_2.4.0.bb @@ -0,0 +1,14 @@ +SUMMARY = "Abstraction layer for PyQt5/PySide2/PyQt6/PySide6" +HOMEPAGE = "https://github.com/spyder-ide/qtpy" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=b2830f54500be1314b9ec6096989f983" + +PYPI_PACKAGE = "QtPy" + +SRC_URI[sha256sum] = "db2d508167aa6106781565c8da5c6f1487debacba33519cedc35fa8997d424d4" + +inherit pypi setuptools3 + +RDEPENDS:${PN} += " \ + python3-pyqt5 \ +" diff --git a/recipes-devtools/python/python3-qtwidgets_1.1.bb b/recipes-devtools/python/python3-qtwidgets_1.1.bb new file mode 100644 index 00000000..677d4fa2 --- /dev/null +++ b/recipes-devtools/python/python3-qtwidgets_1.1.bb @@ -0,0 +1,12 @@ +SUMMARY = "Custom Qt5 Python Widgets" +HOMEPAGE = "https://github.com/pythonguis/python-qtwidgets" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=dc687cb5e5291e09b4f52b0b182106fe" + +SRC_URI[sha256sum] = "97b8373844788a22c836f5a16a1e60c9ef1469bfc4aedc09ae786fc9aa0b49df" + +inherit pypi setuptools3 + +RDEPENDS:${PN} += " \ + python3-qtpy \ +" diff --git a/recipes-devtools/python/python3-setuptools-git-versioning_1.7.4.bb b/recipes-devtools/python/python3-setuptools-git-versioning_1.7.4.bb new file mode 100644 index 00000000..698a3bb6 --- /dev/null +++ b/recipes-devtools/python/python3-setuptools-git-versioning_1.7.4.bb @@ -0,0 +1,17 @@ +SUMMARY = "Use git repo data for building a version number according PEP-440" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=f22e7cb81b49604c2450680982bdc067" +PYPI_PACKAGE = "setuptools-git-versioning" + +DEPENDS = "python3-six-native" + +SRC_URI[sha256sum] = "be2901afcb7c865e3b500a38183598657fd029a1a72c8d1dfc7fbffb5c227dac" + +inherit pypi setuptools3 + +RDEPENDS:${PN} += " \ + python3-setuptools \ + python3-six \ +" + +BBCLASSEXTEND = "native" diff --git a/recipes-extended/agl-qemu-runner/agl-qemu-runner.bb b/recipes-extended/agl-qemu-runner/agl-qemu-runner.bb new file mode 100644 index 00000000..b3e3a67d --- /dev/null +++ b/recipes-extended/agl-qemu-runner/agl-qemu-runner.bb @@ -0,0 +1,25 @@ +SUMMARY = "AGL simple QEMU runner script" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd allarch + +SRC_URI = "file://agl-qemu-runner.sh \ + file://agl-qemu-runner@.service \ +" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + # Install template unit + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/agl-qemu-runner@.service ${D}${systemd_system_unitdir}/ + + # Install script + install -D -m 0755 ${WORKDIR}/agl-qemu-runner.sh ${D}${sbindir}/agl-qemu-runner.sh +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "bash qemu" diff --git a/recipes-extended/agl-qemu-runner/files/agl-qemu-runner.sh b/recipes-extended/agl-qemu-runner/files/agl-qemu-runner.sh new file mode 100755 index 00000000..ab3a02c9 --- /dev/null +++ b/recipes-extended/agl-qemu-runner/files/agl-qemu-runner.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# SPDX-License-Identifier: Apache-2.0 + +if [ -z "$1" ]; then + echo "Usage: ${basename $0} <image name>" + exit 1 +fi +image="$1" + +conf="/etc/agl-qemu-runner/${image}.conf" +if [ ! -f "$conf" ]; then + echo "No configuration file $conf" + exit 1 +fi + +. $conf + +arch="$(uname -m)" +if [ -z "$QEMU_IMAGE_ARCH" ]; then + QEMU_IMAGE_ARCH="virtio-${arch}" +fi + +disk="/var/lib/machines/${image}/${image}-${QEMU_IMAGE_ARCH}.ext4" +if [ ! -f "$disk" ]; then + echo "No disk image for $image" + exit 1 +fi +kernel="/var/lib/machines/${image}/Image-${QEMU_IMAGE_ARCH}.bin" +if [ ! -f "$kernel" ]; then + echo "No kernel for $image" + exit 1 +fi + +TASKSET_CMD="" +if [ -n "$QEMU_TASKSET_CPUS" ]; then + TASKSET_CMD="taskset -c ${QEMU_TASKSET_CPUS}" +fi + +export SDL_VIDEODRIVER=wayland +export XDG_RUNTIME_DIR=/run/user/1001 +# The following may be needed if the socket is not wayland-0, as SDL +# seems to lack detection logic for that case. +#export WAYLAND_DISPLAY=wayland-1 + +# This sets the XDG app id, which we need for setting outputs with +# agl-compositor +export SDL_VIDEO_WAYLAND_WMCLASS="${image}" + +${TASKSET_CMD} \ +qemu-system-${arch} \ + -enable-kvm \ + -machine virt,gic-version=max,iommu=smmuv3 \ + -cpu host \ + ${QEMU_SMP_OPT} \ + ${QEMU_MEM_OPT} \ + -kernel $kernel \ + -append "${QEMU_KERNEL_CMDLINE_APPEND}" \ + -drive id=disk0,file=${disk},format=raw,if=none \ + -serial mon:pty \ + -object rng-random,filename=/dev/urandom,id=rng0 \ + -device virtio-blk-device,drive=disk0 \ + -device virtio-rng-device,rng=rng0 \ + ${QEMU_NET_OPT} \ + ${QEMU_INPUT_OPT} \ + -global virtio-mmio.force-legacy=false \ + -device virtio-gpu-gl-device \ + -display sdl,gl=on -vga std \ + ${QEMU_AUDIO_OPT} \ + ${QEMU_CAN_OPT} \ + ${QEMU_EXTRA_OPT} \ + -full-screen diff --git a/recipes-extended/agl-qemu-runner/files/agl-qemu-runner@.service b/recipes-extended/agl-qemu-runner/files/agl-qemu-runner@.service new file mode 100644 index 00000000..d19c529f --- /dev/null +++ b/recipes-extended/agl-qemu-runner/files/agl-qemu-runner@.service @@ -0,0 +1,12 @@ +[Unit] +Requires=native-shell-client.service +After=native-shell-client.service + +[Service] +Type=simple +ExecStart=/usr/sbin/agl-qemu-runner.sh %i +#Restart=on-failure +Restart=no + +[Install] +WantedBy=multi-user.target diff --git a/recipes-graphics/kms-conf/kms-conf/kms.conf b/recipes-graphics/kms-conf/kms-conf/kms.conf new file mode 100644 index 00000000..7fa9686e --- /dev/null +++ b/recipes-graphics/kms-conf/kms-conf/kms.conf @@ -0,0 +1,8 @@ +{ + "device": "/dev/dri/card0", + "outputs": [ + { + "name":"HDMI-A-1" + } + ] +} diff --git a/recipes-graphics/kms-conf/kms-conf/m3ulcb/kms.conf b/recipes-graphics/kms-conf/kms-conf/m3ulcb/kms.conf new file mode 100644 index 00000000..16ea328f --- /dev/null +++ b/recipes-graphics/kms-conf/kms-conf/m3ulcb/kms.conf @@ -0,0 +1,12 @@ +{ + "device": "/dev/dri/card0", + "outputs": [ + { + "name":"HDMI-A-1" + }, + { + "name":"LVDS1", + "mode":"off" + } + ] +} diff --git a/recipes-graphics/kms-conf/kms-conf_1.0.bb b/recipes-graphics/kms-conf/kms-conf_1.0.bb new file mode 100644 index 00000000..4a665a49 --- /dev/null +++ b/recipes-graphics/kms-conf/kms-conf_1.0.bb @@ -0,0 +1,12 @@ +SUMMARY = "kms configuration file for the qt eglfs platform" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +SRC_URI = " \ + file://kms.conf \ +" + +do_install:append() { + install -d ${D}${sysconfdir} + install -m 644 ${WORKDIR}/kms.conf ${D}${sysconfdir} +} diff --git a/recipes-graphics/ttf-fonts/files/cleaner.py b/recipes-graphics/ttf-fonts/files/cleaner.py index 9b926133..e19ed1d9 100644 --- a/recipes-graphics/ttf-fonts/files/cleaner.py +++ b/recipes-graphics/ttf-fonts/files/cleaner.py @@ -1,10 +1,11 @@ -from json import load from sys import argv +emoji_list = [ 9725, 9726, 9748, 9749, 9800, 9801, 9802, 9803, 9804, 9805, 9806, 9807, 9808, 9809, 9810, 9811, 9855, 9875, 9889, 9898, 9899, 10175, 127183, 127761, 127762, 127763, 127764, 127765, 127766, 127767, 127768, 128045, 128046, 128049, 128053, 128512, 128513, 128514, 128515, 128516, 128517, 128518, 128519, 128520, 128521, 128522, 128523, 128524, 128525, 128526, 128527, 128528, 128529, 128530, 128531, 128532, 128533, 128534, 128535, 128536, 128537, 128538, 128539, 128540, 128541, 128542, 128543, 128544, 128545, 128546, 128547, 128549, 128550, 128551, 128552, 128553, 128554, 128555, 128557, 128558, 128559, 128560, 128561, 128562, 128563, 128564, 128565, 128566, 128567, 128568, 128569, 128570, 128571, 128572, 128573, 128574, 128575, 128576, 128579 ] + ttf = fontforge.open(argv[1]) -for emoji in load(open('../../emoji.json')): +for emoji in emoji_list: try: - ttf.removeGlyph(int(emoji['unified'], 16)) + ttf.removeGlyph(emoji) except ValueError: pass ttf.generate(argv[1]) diff --git a/recipes-graphics/ttf-fonts/files/emoji.json b/recipes-graphics/ttf-fonts/files/emoji.json deleted file mode 100644 index 3cff22e3..00000000 --- a/recipes-graphics/ttf-fonts/files/emoji.json +++ /dev/null @@ -1 +0,0 @@ -[{"name":"HASH KEY","unified":"0023-FE0F-20E3","non_qualified":"0023-20E3","docomo":"E6E0","au":"EB84","softbank":"E210","google":"FE82C","image":"0023-fe0f-20e3.png","sheet_x":0,"sheet_y":0,"short_name":"hash","short_names":["hash"],"text":null,"texts":null,"category":"Symbols","sort_order":132,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":null,"unified":"002A-FE0F-20E3","non_qualified":"002A-20E3","docomo":null,"au":null,"softbank":null,"google":null,"image":"002a-fe0f-20e3.png","sheet_x":0,"sheet_y":1,"short_name":"keycap_star","short_names":["keycap_star"],"text":null,"texts":null,"category":"Symbols","sort_order":133,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 0","unified":"0030-FE0F-20E3","non_qualified":"0030-20E3","docomo":"E6EB","au":"E5AC","softbank":"E225","google":"FE837","image":"0030-fe0f-20e3.png","sheet_x":0,"sheet_y":2,"short_name":"zero","short_names":["zero"],"text":null,"texts":null,"category":"Symbols","sort_order":134,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 1","unified":"0031-FE0F-20E3","non_qualified":"0031-20E3","docomo":"E6E2","au":"E522","softbank":"E21C","google":"FE82E","image":"0031-fe0f-20e3.png","sheet_x":0,"sheet_y":3,"short_name":"one","short_names":["one"],"text":null,"texts":null,"category":"Symbols","sort_order":135,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 2","unified":"0032-FE0F-20E3","non_qualified":"0032-20E3","docomo":"E6E3","au":"E523","softbank":"E21D","google":"FE82F","image":"0032-fe0f-20e3.png","sheet_x":0,"sheet_y":4,"short_name":"two","short_names":["two"],"text":null,"texts":null,"category":"Symbols","sort_order":136,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 3","unified":"0033-FE0F-20E3","non_qualified":"0033-20E3","docomo":"E6E4","au":"E524","softbank":"E21E","google":"FE830","image":"0033-fe0f-20e3.png","sheet_x":0,"sheet_y":5,"short_name":"three","short_names":["three"],"text":null,"texts":null,"category":"Symbols","sort_order":137,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 4","unified":"0034-FE0F-20E3","non_qualified":"0034-20E3","docomo":"E6E5","au":"E525","softbank":"E21F","google":"FE831","image":"0034-fe0f-20e3.png","sheet_x":0,"sheet_y":6,"short_name":"four","short_names":["four"],"text":null,"texts":null,"category":"Symbols","sort_order":138,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 5","unified":"0035-FE0F-20E3","non_qualified":"0035-20E3","docomo":"E6E6","au":"E526","softbank":"E220","google":"FE832","image":"0035-fe0f-20e3.png","sheet_x":0,"sheet_y":7,"short_name":"five","short_names":["five"],"text":null,"texts":null,"category":"Symbols","sort_order":139,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 6","unified":"0036-FE0F-20E3","non_qualified":"0036-20E3","docomo":"E6E7","au":"E527","softbank":"E221","google":"FE833","image":"0036-fe0f-20e3.png","sheet_x":0,"sheet_y":8,"short_name":"six","short_names":["six"],"text":null,"texts":null,"category":"Symbols","sort_order":140,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 7","unified":"0037-FE0F-20E3","non_qualified":"0037-20E3","docomo":"E6E8","au":"E528","softbank":"E222","google":"FE834","image":"0037-fe0f-20e3.png","sheet_x":0,"sheet_y":9,"short_name":"seven","short_names":["seven"],"text":null,"texts":null,"category":"Symbols","sort_order":141,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 8","unified":"0038-FE0F-20E3","non_qualified":"0038-20E3","docomo":"E6E9","au":"E529","softbank":"E223","google":"FE835","image":"0038-fe0f-20e3.png","sheet_x":0,"sheet_y":10,"short_name":"eight","short_names":["eight"],"text":null,"texts":null,"category":"Symbols","sort_order":142,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"KEYCAP 9","unified":"0039-FE0F-20E3","non_qualified":"0039-20E3","docomo":"E6EA","au":"E52A","softbank":"E224","google":"FE836","image":"0039-fe0f-20e3.png","sheet_x":0,"sheet_y":11,"short_name":"nine","short_names":["nine"],"text":null,"texts":null,"category":"Symbols","sort_order":143,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":"COPYRIGHT SIGN","unified":"00A9-FE0F","non_qualified":"00A9","docomo":"E731","au":"E558","softbank":"E24E","google":"FEB29","image":"00a9-fe0f.png","sheet_x":0,"sheet_y":12,"short_name":"copyright","short_names":["copyright"],"text":null,"texts":null,"category":"Symbols","sort_order":129,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"REGISTERED SIGN","unified":"00AE-FE0F","non_qualified":"00AE","docomo":"E736","au":"E559","softbank":"E24F","google":"FEB2D","image":"00ae-fe0f.png","sheet_x":0,"sheet_y":13,"short_name":"registered","short_names":["registered"],"text":null,"texts":null,"category":"Symbols","sort_order":130,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"MAHJONG TILE RED DRAGON","unified":"1F004","non_qualified":null,"docomo":null,"au":"E5D1","softbank":"E12D","google":"FE80B","image":"1f004.png","sheet_x":0,"sheet_y":14,"short_name":"mahjong","short_names":["mahjong"],"text":null,"texts":null,"category":"Activities","sort_order":70,"added_in":"5.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PLAYING CARD BLACK JOKER","unified":"1F0CF","non_qualified":null,"docomo":null,"au":"EB6F","softbank":null,"google":"FE812","image":"1f0cf.png","sheet_x":0,"sheet_y":15,"short_name":"black_joker","short_names":["black_joker"],"text":null,"texts":null,"category":"Activities","sort_order":69,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEGATIVE SQUARED LATIN CAPITAL LETTER A","unified":"1F170-FE0F","non_qualified":"1F170","docomo":null,"au":"EB26","softbank":"E532","google":"FE50B","image":"1f170-fe0f.png","sheet_x":0,"sheet_y":16,"short_name":"a","short_names":["a"],"text":null,"texts":null,"category":"Symbols","sort_order":151,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEGATIVE SQUARED LATIN CAPITAL LETTER B","unified":"1F171-FE0F","non_qualified":"1F171","docomo":null,"au":"EB27","softbank":"E533","google":"FE50C","image":"1f171-fe0f.png","sheet_x":0,"sheet_y":17,"short_name":"b","short_names":["b"],"text":null,"texts":null,"category":"Symbols","sort_order":153,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEGATIVE SQUARED LATIN CAPITAL LETTER O","unified":"1F17E-FE0F","non_qualified":"1F17E","docomo":null,"au":"EB28","softbank":"E535","google":"FE50E","image":"1f17e-fe0f.png","sheet_x":0,"sheet_y":18,"short_name":"o2","short_names":["o2"],"text":null,"texts":null,"category":"Symbols","sort_order":162,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEGATIVE SQUARED LATIN CAPITAL LETTER P","unified":"1F17F-FE0F","non_qualified":"1F17F","docomo":"E66C","au":"E4A6","softbank":"E14F","google":"FE7F6","image":"1f17f-fe0f.png","sheet_x":0,"sheet_y":19,"short_name":"parking","short_names":["parking"],"text":null,"texts":null,"category":"Symbols","sort_order":164,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEGATIVE SQUARED AB","unified":"1F18E","non_qualified":null,"docomo":null,"au":"EB29","softbank":"E534","google":"FE50D","image":"1f18e.png","sheet_x":0,"sheet_y":20,"short_name":"ab","short_names":["ab"],"text":null,"texts":null,"category":"Symbols","sort_order":152,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CL","unified":"1F191","non_qualified":null,"docomo":"E6DB","au":"E5AB","softbank":null,"google":"FEB84","image":"1f191.png","sheet_x":0,"sheet_y":21,"short_name":"cl","short_names":["cl"],"text":null,"texts":null,"category":"Symbols","sort_order":154,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED COOL","unified":"1F192","non_qualified":null,"docomo":null,"au":"EA85","softbank":"E214","google":"FEB38","image":"1f192.png","sheet_x":0,"sheet_y":22,"short_name":"cool","short_names":["cool"],"text":null,"texts":null,"category":"Symbols","sort_order":155,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED FREE","unified":"1F193","non_qualified":null,"docomo":"E6D7","au":"E578","softbank":null,"google":"FEB21","image":"1f193.png","sheet_x":0,"sheet_y":23,"short_name":"free","short_names":["free"],"text":null,"texts":null,"category":"Symbols","sort_order":156,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED ID","unified":"1F194","non_qualified":null,"docomo":"E6D8","au":"EA88","softbank":"E229","google":"FEB81","image":"1f194.png","sheet_x":0,"sheet_y":24,"short_name":"id","short_names":["id"],"text":null,"texts":null,"category":"Symbols","sort_order":158,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED NEW","unified":"1F195","non_qualified":null,"docomo":"E6DD","au":"E5B5","softbank":"E212","google":"FEB36","image":"1f195.png","sheet_x":0,"sheet_y":25,"short_name":"new","short_names":["new"],"text":null,"texts":null,"category":"Symbols","sort_order":160,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED NG","unified":"1F196","non_qualified":null,"docomo":"E72F","au":null,"softbank":null,"google":"FEB28","image":"1f196.png","sheet_x":0,"sheet_y":26,"short_name":"ng","short_names":["ng"],"text":null,"texts":null,"category":"Symbols","sort_order":161,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED OK","unified":"1F197","non_qualified":null,"docomo":"E70B","au":"E5AD","softbank":"E24D","google":"FEB27","image":"1f197.png","sheet_x":0,"sheet_y":27,"short_name":"ok","short_names":["ok"],"text":null,"texts":null,"category":"Symbols","sort_order":163,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED SOS","unified":"1F198","non_qualified":null,"docomo":null,"au":"E4E8","softbank":null,"google":"FEB4F","image":"1f198.png","sheet_x":0,"sheet_y":28,"short_name":"sos","short_names":["sos"],"text":null,"texts":null,"category":"Symbols","sort_order":165,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED UP WITH EXCLAMATION MARK","unified":"1F199","non_qualified":null,"docomo":null,"au":"E50F","softbank":"E213","google":"FEB37","image":"1f199.png","sheet_x":0,"sheet_y":29,"short_name":"up","short_names":["up"],"text":null,"texts":null,"category":"Symbols","sort_order":166,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED VS","unified":"1F19A","non_qualified":null,"docomo":null,"au":"E5D2","softbank":"E12E","google":"FEB32","image":"1f19a.png","sheet_x":0,"sheet_y":30,"short_name":"vs","short_names":["vs"],"text":null,"texts":null,"category":"Symbols","sort_order":167,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Ascension Island Flag","unified":"1F1E6-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1e8.png","sheet_x":0,"sheet_y":31,"short_name":"flag-ac","short_names":["flag-ac"],"text":null,"texts":null,"category":"Flags","sort_order":8,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Andorra Flag","unified":"1F1E6-1F1E9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1e9.png","sheet_x":0,"sheet_y":32,"short_name":"flag-ad","short_names":["flag-ad"],"text":null,"texts":null,"category":"Flags","sort_order":9,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"United Arab Emirates Flag","unified":"1F1E6-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1ea.png","sheet_x":0,"sheet_y":33,"short_name":"flag-ae","short_names":["flag-ae"],"text":null,"texts":null,"category":"Flags","sort_order":10,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Afghanistan Flag","unified":"1F1E6-1F1EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1eb.png","sheet_x":0,"sheet_y":34,"short_name":"flag-af","short_names":["flag-af"],"text":null,"texts":null,"category":"Flags","sort_order":11,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Antigua & Barbuda Flag","unified":"1F1E6-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1ec.png","sheet_x":0,"sheet_y":35,"short_name":"flag-ag","short_names":["flag-ag"],"text":null,"texts":null,"category":"Flags","sort_order":12,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Anguilla Flag","unified":"1F1E6-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1ee.png","sheet_x":0,"sheet_y":36,"short_name":"flag-ai","short_names":["flag-ai"],"text":null,"texts":null,"category":"Flags","sort_order":13,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Albania Flag","unified":"1F1E6-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1f1.png","sheet_x":0,"sheet_y":37,"short_name":"flag-al","short_names":["flag-al"],"text":null,"texts":null,"category":"Flags","sort_order":14,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Armenia Flag","unified":"1F1E6-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1f2.png","sheet_x":0,"sheet_y":38,"short_name":"flag-am","short_names":["flag-am"],"text":null,"texts":null,"category":"Flags","sort_order":15,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Angola Flag","unified":"1F1E6-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1f4.png","sheet_x":0,"sheet_y":39,"short_name":"flag-ao","short_names":["flag-ao"],"text":null,"texts":null,"category":"Flags","sort_order":16,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Antarctica Flag","unified":"1F1E6-1F1F6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1f6.png","sheet_x":0,"sheet_y":40,"short_name":"flag-aq","short_names":["flag-aq"],"text":null,"texts":null,"category":"Flags","sort_order":17,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Argentina Flag","unified":"1F1E6-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1f7.png","sheet_x":0,"sheet_y":41,"short_name":"flag-ar","short_names":["flag-ar"],"text":null,"texts":null,"category":"Flags","sort_order":18,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"American Samoa Flag","unified":"1F1E6-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1f8.png","sheet_x":0,"sheet_y":42,"short_name":"flag-as","short_names":["flag-as"],"text":null,"texts":null,"category":"Flags","sort_order":19,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Austria Flag","unified":"1F1E6-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1f9.png","sheet_x":0,"sheet_y":43,"short_name":"flag-at","short_names":["flag-at"],"text":null,"texts":null,"category":"Flags","sort_order":20,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Australia Flag","unified":"1F1E6-1F1FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1fa.png","sheet_x":0,"sheet_y":44,"short_name":"flag-au","short_names":["flag-au"],"text":null,"texts":null,"category":"Flags","sort_order":21,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Aruba Flag","unified":"1F1E6-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1fc.png","sheet_x":0,"sheet_y":45,"short_name":"flag-aw","short_names":["flag-aw"],"text":null,"texts":null,"category":"Flags","sort_order":22,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"\u00c5land Islands Flag","unified":"1F1E6-1F1FD","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1fd.png","sheet_x":0,"sheet_y":46,"short_name":"flag-ax","short_names":["flag-ax"],"text":null,"texts":null,"category":"Flags","sort_order":23,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Azerbaijan Flag","unified":"1F1E6-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e6-1f1ff.png","sheet_x":0,"sheet_y":47,"short_name":"flag-az","short_names":["flag-az"],"text":null,"texts":null,"category":"Flags","sort_order":24,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Bosnia & Herzegovina Flag","unified":"1F1E7-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1e6.png","sheet_x":0,"sheet_y":48,"short_name":"flag-ba","short_names":["flag-ba"],"text":null,"texts":null,"category":"Flags","sort_order":25,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"Barbados Flag","unified":"1F1E7-1F1E7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1e7.png","sheet_x":0,"sheet_y":49,"short_name":"flag-bb","short_names":["flag-bb"],"text":null,"texts":null,"category":"Flags","sort_order":26,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Bangladesh Flag","unified":"1F1E7-1F1E9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1e9.png","sheet_x":0,"sheet_y":50,"short_name":"flag-bd","short_names":["flag-bd"],"text":null,"texts":null,"category":"Flags","sort_order":27,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Belgium Flag","unified":"1F1E7-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1ea.png","sheet_x":0,"sheet_y":51,"short_name":"flag-be","short_names":["flag-be"],"text":null,"texts":null,"category":"Flags","sort_order":28,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Burkina Faso Flag","unified":"1F1E7-1F1EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1eb.png","sheet_x":0,"sheet_y":52,"short_name":"flag-bf","short_names":["flag-bf"],"text":null,"texts":null,"category":"Flags","sort_order":29,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Bulgaria Flag","unified":"1F1E7-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1ec.png","sheet_x":1,"sheet_y":0,"short_name":"flag-bg","short_names":["flag-bg"],"text":null,"texts":null,"category":"Flags","sort_order":30,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Bahrain Flag","unified":"1F1E7-1F1ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1ed.png","sheet_x":1,"sheet_y":1,"short_name":"flag-bh","short_names":["flag-bh"],"text":null,"texts":null,"category":"Flags","sort_order":31,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Burundi Flag","unified":"1F1E7-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1ee.png","sheet_x":1,"sheet_y":2,"short_name":"flag-bi","short_names":["flag-bi"],"text":null,"texts":null,"category":"Flags","sort_order":32,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Benin Flag","unified":"1F1E7-1F1EF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1ef.png","sheet_x":1,"sheet_y":3,"short_name":"flag-bj","short_names":["flag-bj"],"text":null,"texts":null,"category":"Flags","sort_order":33,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"St. Barth\u00e9lemy Flag","unified":"1F1E7-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1f1.png","sheet_x":1,"sheet_y":4,"short_name":"flag-bl","short_names":["flag-bl"],"text":null,"texts":null,"category":"Flags","sort_order":34,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Bermuda Flag","unified":"1F1E7-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1f2.png","sheet_x":1,"sheet_y":5,"short_name":"flag-bm","short_names":["flag-bm"],"text":null,"texts":null,"category":"Flags","sort_order":35,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Brunei Flag","unified":"1F1E7-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1f3.png","sheet_x":1,"sheet_y":6,"short_name":"flag-bn","short_names":["flag-bn"],"text":null,"texts":null,"category":"Flags","sort_order":36,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"Bolivia Flag","unified":"1F1E7-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1f4.png","sheet_x":1,"sheet_y":7,"short_name":"flag-bo","short_names":["flag-bo"],"text":null,"texts":null,"category":"Flags","sort_order":37,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Caribbean Netherlands Flag","unified":"1F1E7-1F1F6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1f6.png","sheet_x":1,"sheet_y":8,"short_name":"flag-bq","short_names":["flag-bq"],"text":null,"texts":null,"category":"Flags","sort_order":38,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Brazil Flag","unified":"1F1E7-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1f7.png","sheet_x":1,"sheet_y":9,"short_name":"flag-br","short_names":["flag-br"],"text":null,"texts":null,"category":"Flags","sort_order":39,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Bahamas Flag","unified":"1F1E7-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1f8.png","sheet_x":1,"sheet_y":10,"short_name":"flag-bs","short_names":["flag-bs"],"text":null,"texts":null,"category":"Flags","sort_order":40,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Bhutan Flag","unified":"1F1E7-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1f9.png","sheet_x":1,"sheet_y":11,"short_name":"flag-bt","short_names":["flag-bt"],"text":null,"texts":null,"category":"Flags","sort_order":41,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Bouvet Island Flag","unified":"1F1E7-1F1FB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1fb.png","sheet_x":1,"sheet_y":12,"short_name":"flag-bv","short_names":["flag-bv"],"text":null,"texts":null,"category":"Flags","sort_order":42,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Botswana Flag","unified":"1F1E7-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1fc.png","sheet_x":1,"sheet_y":13,"short_name":"flag-bw","short_names":["flag-bw"],"text":null,"texts":null,"category":"Flags","sort_order":43,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Belarus Flag","unified":"1F1E7-1F1FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1fe.png","sheet_x":1,"sheet_y":14,"short_name":"flag-by","short_names":["flag-by"],"text":null,"texts":null,"category":"Flags","sort_order":44,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Belize Flag","unified":"1F1E7-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e7-1f1ff.png","sheet_x":1,"sheet_y":15,"short_name":"flag-bz","short_names":["flag-bz"],"text":null,"texts":null,"category":"Flags","sort_order":45,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Canada Flag","unified":"1F1E8-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1e6.png","sheet_x":1,"sheet_y":16,"short_name":"flag-ca","short_names":["flag-ca"],"text":null,"texts":null,"category":"Flags","sort_order":46,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Cocos (Keeling) Islands Flag","unified":"1F1E8-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1e8.png","sheet_x":1,"sheet_y":17,"short_name":"flag-cc","short_names":["flag-cc"],"text":null,"texts":null,"category":"Flags","sort_order":47,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Congo - Kinshasa Flag","unified":"1F1E8-1F1E9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1e9.png","sheet_x":1,"sheet_y":18,"short_name":"flag-cd","short_names":["flag-cd"],"text":null,"texts":null,"category":"Flags","sort_order":48,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Central African Republic Flag","unified":"1F1E8-1F1EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1eb.png","sheet_x":1,"sheet_y":19,"short_name":"flag-cf","short_names":["flag-cf"],"text":null,"texts":null,"category":"Flags","sort_order":49,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Congo - Brazzaville Flag","unified":"1F1E8-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1ec.png","sheet_x":1,"sheet_y":20,"short_name":"flag-cg","short_names":["flag-cg"],"text":null,"texts":null,"category":"Flags","sort_order":50,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Switzerland Flag","unified":"1F1E8-1F1ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1ed.png","sheet_x":1,"sheet_y":21,"short_name":"flag-ch","short_names":["flag-ch"],"text":null,"texts":null,"category":"Flags","sort_order":51,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"C\u00f4te d\u2019Ivoire Flag","unified":"1F1E8-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1ee.png","sheet_x":1,"sheet_y":22,"short_name":"flag-ci","short_names":["flag-ci"],"text":null,"texts":null,"category":"Flags","sort_order":52,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Cook Islands Flag","unified":"1F1E8-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1f0.png","sheet_x":1,"sheet_y":23,"short_name":"flag-ck","short_names":["flag-ck"],"text":null,"texts":null,"category":"Flags","sort_order":53,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Chile Flag","unified":"1F1E8-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1f1.png","sheet_x":1,"sheet_y":24,"short_name":"flag-cl","short_names":["flag-cl"],"text":null,"texts":null,"category":"Flags","sort_order":54,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Cameroon Flag","unified":"1F1E8-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1f2.png","sheet_x":1,"sheet_y":25,"short_name":"flag-cm","short_names":["flag-cm"],"text":null,"texts":null,"category":"Flags","sort_order":55,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"China Flag","unified":"1F1E8-1F1F3","non_qualified":null,"docomo":null,"au":"EB11","softbank":"E513","google":"FE4ED","image":"1f1e8-1f1f3.png","sheet_x":1,"sheet_y":26,"short_name":"cn","short_names":["cn","flag-cn"],"text":null,"texts":null,"category":"Flags","sort_order":56,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Colombia Flag","unified":"1F1E8-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1f4.png","sheet_x":1,"sheet_y":27,"short_name":"flag-co","short_names":["flag-co"],"text":null,"texts":null,"category":"Flags","sort_order":57,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Clipperton Island Flag","unified":"1F1E8-1F1F5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1f5.png","sheet_x":1,"sheet_y":28,"short_name":"flag-cp","short_names":["flag-cp"],"text":null,"texts":null,"category":"Flags","sort_order":58,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"Costa Rica Flag","unified":"1F1E8-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1f7.png","sheet_x":1,"sheet_y":29,"short_name":"flag-cr","short_names":["flag-cr"],"text":null,"texts":null,"category":"Flags","sort_order":59,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Cuba Flag","unified":"1F1E8-1F1FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1fa.png","sheet_x":1,"sheet_y":30,"short_name":"flag-cu","short_names":["flag-cu"],"text":null,"texts":null,"category":"Flags","sort_order":60,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Cape Verde Flag","unified":"1F1E8-1F1FB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1fb.png","sheet_x":1,"sheet_y":31,"short_name":"flag-cv","short_names":["flag-cv"],"text":null,"texts":null,"category":"Flags","sort_order":61,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Cura\u00e7ao Flag","unified":"1F1E8-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1fc.png","sheet_x":1,"sheet_y":32,"short_name":"flag-cw","short_names":["flag-cw"],"text":null,"texts":null,"category":"Flags","sort_order":62,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Christmas Island Flag","unified":"1F1E8-1F1FD","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1fd.png","sheet_x":1,"sheet_y":33,"short_name":"flag-cx","short_names":["flag-cx"],"text":null,"texts":null,"category":"Flags","sort_order":63,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Cyprus Flag","unified":"1F1E8-1F1FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1fe.png","sheet_x":1,"sheet_y":34,"short_name":"flag-cy","short_names":["flag-cy"],"text":null,"texts":null,"category":"Flags","sort_order":64,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Czechia Flag","unified":"1F1E8-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e8-1f1ff.png","sheet_x":1,"sheet_y":35,"short_name":"flag-cz","short_names":["flag-cz"],"text":null,"texts":null,"category":"Flags","sort_order":65,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Germany Flag","unified":"1F1E9-1F1EA","non_qualified":null,"docomo":null,"au":"EB0E","softbank":"E50E","google":"FE4E8","image":"1f1e9-1f1ea.png","sheet_x":1,"sheet_y":36,"short_name":"de","short_names":["de","flag-de"],"text":null,"texts":null,"category":"Flags","sort_order":66,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Diego Garcia Flag","unified":"1F1E9-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e9-1f1ec.png","sheet_x":1,"sheet_y":37,"short_name":"flag-dg","short_names":["flag-dg"],"text":null,"texts":null,"category":"Flags","sort_order":67,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Djibouti Flag","unified":"1F1E9-1F1EF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e9-1f1ef.png","sheet_x":1,"sheet_y":38,"short_name":"flag-dj","short_names":["flag-dj"],"text":null,"texts":null,"category":"Flags","sort_order":68,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Denmark Flag","unified":"1F1E9-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e9-1f1f0.png","sheet_x":1,"sheet_y":39,"short_name":"flag-dk","short_names":["flag-dk"],"text":null,"texts":null,"category":"Flags","sort_order":69,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Dominica Flag","unified":"1F1E9-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e9-1f1f2.png","sheet_x":1,"sheet_y":40,"short_name":"flag-dm","short_names":["flag-dm"],"text":null,"texts":null,"category":"Flags","sort_order":70,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Dominican Republic Flag","unified":"1F1E9-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e9-1f1f4.png","sheet_x":1,"sheet_y":41,"short_name":"flag-do","short_names":["flag-do"],"text":null,"texts":null,"category":"Flags","sort_order":71,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Algeria Flag","unified":"1F1E9-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1e9-1f1ff.png","sheet_x":1,"sheet_y":42,"short_name":"flag-dz","short_names":["flag-dz"],"text":null,"texts":null,"category":"Flags","sort_order":72,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Ceuta & Melilla Flag","unified":"1F1EA-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ea-1f1e6.png","sheet_x":1,"sheet_y":43,"short_name":"flag-ea","short_names":["flag-ea"],"text":null,"texts":null,"category":"Flags","sort_order":73,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Ecuador Flag","unified":"1F1EA-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ea-1f1e8.png","sheet_x":1,"sheet_y":44,"short_name":"flag-ec","short_names":["flag-ec"],"text":null,"texts":null,"category":"Flags","sort_order":74,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Estonia Flag","unified":"1F1EA-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ea-1f1ea.png","sheet_x":1,"sheet_y":45,"short_name":"flag-ee","short_names":["flag-ee"],"text":null,"texts":null,"category":"Flags","sort_order":75,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Egypt Flag","unified":"1F1EA-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ea-1f1ec.png","sheet_x":1,"sheet_y":46,"short_name":"flag-eg","short_names":["flag-eg"],"text":null,"texts":null,"category":"Flags","sort_order":76,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Western Sahara Flag","unified":"1F1EA-1F1ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ea-1f1ed.png","sheet_x":1,"sheet_y":47,"short_name":"flag-eh","short_names":["flag-eh"],"text":null,"texts":null,"category":"Flags","sort_order":77,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Eritrea Flag","unified":"1F1EA-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ea-1f1f7.png","sheet_x":1,"sheet_y":48,"short_name":"flag-er","short_names":["flag-er"],"text":null,"texts":null,"category":"Flags","sort_order":78,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Spain Flag","unified":"1F1EA-1F1F8","non_qualified":null,"docomo":null,"au":"E5D5","softbank":"E511","google":"FE4EB","image":"1f1ea-1f1f8.png","sheet_x":1,"sheet_y":49,"short_name":"es","short_names":["es","flag-es"],"text":null,"texts":null,"category":"Flags","sort_order":79,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Ethiopia Flag","unified":"1F1EA-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ea-1f1f9.png","sheet_x":1,"sheet_y":50,"short_name":"flag-et","short_names":["flag-et"],"text":null,"texts":null,"category":"Flags","sort_order":80,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"European Union Flag","unified":"1F1EA-1F1FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ea-1f1fa.png","sheet_x":1,"sheet_y":51,"short_name":"flag-eu","short_names":["flag-eu"],"text":null,"texts":null,"category":"Flags","sort_order":81,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Finland Flag","unified":"1F1EB-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1eb-1f1ee.png","sheet_x":1,"sheet_y":52,"short_name":"flag-fi","short_names":["flag-fi"],"text":null,"texts":null,"category":"Flags","sort_order":82,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Fiji Flag","unified":"1F1EB-1F1EF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1eb-1f1ef.png","sheet_x":2,"sheet_y":0,"short_name":"flag-fj","short_names":["flag-fj"],"text":null,"texts":null,"category":"Flags","sort_order":83,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Falkland Islands Flag","unified":"1F1EB-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1eb-1f1f0.png","sheet_x":2,"sheet_y":1,"short_name":"flag-fk","short_names":["flag-fk"],"text":null,"texts":null,"category":"Flags","sort_order":84,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Micronesia Flag","unified":"1F1EB-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1eb-1f1f2.png","sheet_x":2,"sheet_y":2,"short_name":"flag-fm","short_names":["flag-fm"],"text":null,"texts":null,"category":"Flags","sort_order":85,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Faroe Islands Flag","unified":"1F1EB-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1eb-1f1f4.png","sheet_x":2,"sheet_y":3,"short_name":"flag-fo","short_names":["flag-fo"],"text":null,"texts":null,"category":"Flags","sort_order":86,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"France Flag","unified":"1F1EB-1F1F7","non_qualified":null,"docomo":null,"au":"EAFA","softbank":"E50D","google":"FE4E7","image":"1f1eb-1f1f7.png","sheet_x":2,"sheet_y":4,"short_name":"fr","short_names":["fr","flag-fr"],"text":null,"texts":null,"category":"Flags","sort_order":87,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Gabon Flag","unified":"1F1EC-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1e6.png","sheet_x":2,"sheet_y":5,"short_name":"flag-ga","short_names":["flag-ga"],"text":null,"texts":null,"category":"Flags","sort_order":88,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"United Kingdom Flag","unified":"1F1EC-1F1E7","non_qualified":null,"docomo":null,"au":"EB10","softbank":"E510","google":"FE4EA","image":"1f1ec-1f1e7.png","sheet_x":2,"sheet_y":6,"short_name":"gb","short_names":["gb","uk","flag-gb"],"text":null,"texts":null,"category":"Flags","sort_order":89,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Grenada Flag","unified":"1F1EC-1F1E9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1e9.png","sheet_x":2,"sheet_y":7,"short_name":"flag-gd","short_names":["flag-gd"],"text":null,"texts":null,"category":"Flags","sort_order":90,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Georgia Flag","unified":"1F1EC-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1ea.png","sheet_x":2,"sheet_y":8,"short_name":"flag-ge","short_names":["flag-ge"],"text":null,"texts":null,"category":"Flags","sort_order":91,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"French Guiana Flag","unified":"1F1EC-1F1EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1eb.png","sheet_x":2,"sheet_y":9,"short_name":"flag-gf","short_names":["flag-gf"],"text":null,"texts":null,"category":"Flags","sort_order":92,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Guernsey Flag","unified":"1F1EC-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1ec.png","sheet_x":2,"sheet_y":10,"short_name":"flag-gg","short_names":["flag-gg"],"text":null,"texts":null,"category":"Flags","sort_order":93,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Ghana Flag","unified":"1F1EC-1F1ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1ed.png","sheet_x":2,"sheet_y":11,"short_name":"flag-gh","short_names":["flag-gh"],"text":null,"texts":null,"category":"Flags","sort_order":94,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Gibraltar Flag","unified":"1F1EC-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1ee.png","sheet_x":2,"sheet_y":12,"short_name":"flag-gi","short_names":["flag-gi"],"text":null,"texts":null,"category":"Flags","sort_order":95,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Greenland Flag","unified":"1F1EC-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1f1.png","sheet_x":2,"sheet_y":13,"short_name":"flag-gl","short_names":["flag-gl"],"text":null,"texts":null,"category":"Flags","sort_order":96,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Gambia Flag","unified":"1F1EC-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1f2.png","sheet_x":2,"sheet_y":14,"short_name":"flag-gm","short_names":["flag-gm"],"text":null,"texts":null,"category":"Flags","sort_order":97,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Guinea Flag","unified":"1F1EC-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1f3.png","sheet_x":2,"sheet_y":15,"short_name":"flag-gn","short_names":["flag-gn"],"text":null,"texts":null,"category":"Flags","sort_order":98,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Guadeloupe Flag","unified":"1F1EC-1F1F5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1f5.png","sheet_x":2,"sheet_y":16,"short_name":"flag-gp","short_names":["flag-gp"],"text":null,"texts":null,"category":"Flags","sort_order":99,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Equatorial Guinea Flag","unified":"1F1EC-1F1F6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1f6.png","sheet_x":2,"sheet_y":17,"short_name":"flag-gq","short_names":["flag-gq"],"text":null,"texts":null,"category":"Flags","sort_order":100,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Greece Flag","unified":"1F1EC-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1f7.png","sheet_x":2,"sheet_y":18,"short_name":"flag-gr","short_names":["flag-gr"],"text":null,"texts":null,"category":"Flags","sort_order":101,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"South Georgia & South Sandwich Islands Flag","unified":"1F1EC-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1f8.png","sheet_x":2,"sheet_y":19,"short_name":"flag-gs","short_names":["flag-gs"],"text":null,"texts":null,"category":"Flags","sort_order":102,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Guatemala Flag","unified":"1F1EC-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1f9.png","sheet_x":2,"sheet_y":20,"short_name":"flag-gt","short_names":["flag-gt"],"text":null,"texts":null,"category":"Flags","sort_order":103,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Guam Flag","unified":"1F1EC-1F1FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1fa.png","sheet_x":2,"sheet_y":21,"short_name":"flag-gu","short_names":["flag-gu"],"text":null,"texts":null,"category":"Flags","sort_order":104,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Guinea-Bissau Flag","unified":"1F1EC-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1fc.png","sheet_x":2,"sheet_y":22,"short_name":"flag-gw","short_names":["flag-gw"],"text":null,"texts":null,"category":"Flags","sort_order":105,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Guyana Flag","unified":"1F1EC-1F1FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ec-1f1fe.png","sheet_x":2,"sheet_y":23,"short_name":"flag-gy","short_names":["flag-gy"],"text":null,"texts":null,"category":"Flags","sort_order":106,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Hong Kong SAR China Flag","unified":"1F1ED-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ed-1f1f0.png","sheet_x":2,"sheet_y":24,"short_name":"flag-hk","short_names":["flag-hk"],"text":null,"texts":null,"category":"Flags","sort_order":107,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Heard & McDonald Islands Flag","unified":"1F1ED-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ed-1f1f2.png","sheet_x":2,"sheet_y":25,"short_name":"flag-hm","short_names":["flag-hm"],"text":null,"texts":null,"category":"Flags","sort_order":108,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Honduras Flag","unified":"1F1ED-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ed-1f1f3.png","sheet_x":2,"sheet_y":26,"short_name":"flag-hn","short_names":["flag-hn"],"text":null,"texts":null,"category":"Flags","sort_order":109,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Croatia Flag","unified":"1F1ED-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ed-1f1f7.png","sheet_x":2,"sheet_y":27,"short_name":"flag-hr","short_names":["flag-hr"],"text":null,"texts":null,"category":"Flags","sort_order":110,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Haiti Flag","unified":"1F1ED-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ed-1f1f9.png","sheet_x":2,"sheet_y":28,"short_name":"flag-ht","short_names":["flag-ht"],"text":null,"texts":null,"category":"Flags","sort_order":111,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Hungary Flag","unified":"1F1ED-1F1FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ed-1f1fa.png","sheet_x":2,"sheet_y":29,"short_name":"flag-hu","short_names":["flag-hu"],"text":null,"texts":null,"category":"Flags","sort_order":112,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Canary Islands Flag","unified":"1F1EE-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1e8.png","sheet_x":2,"sheet_y":30,"short_name":"flag-ic","short_names":["flag-ic"],"text":null,"texts":null,"category":"Flags","sort_order":113,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Indonesia Flag","unified":"1F1EE-1F1E9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1e9.png","sheet_x":2,"sheet_y":31,"short_name":"flag-id","short_names":["flag-id"],"text":null,"texts":null,"category":"Flags","sort_order":114,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Ireland Flag","unified":"1F1EE-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1ea.png","sheet_x":2,"sheet_y":32,"short_name":"flag-ie","short_names":["flag-ie"],"text":null,"texts":null,"category":"Flags","sort_order":115,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Israel Flag","unified":"1F1EE-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1f1.png","sheet_x":2,"sheet_y":33,"short_name":"flag-il","short_names":["flag-il"],"text":null,"texts":null,"category":"Flags","sort_order":116,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Isle of Man Flag","unified":"1F1EE-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1f2.png","sheet_x":2,"sheet_y":34,"short_name":"flag-im","short_names":["flag-im"],"text":null,"texts":null,"category":"Flags","sort_order":117,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"India Flag","unified":"1F1EE-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1f3.png","sheet_x":2,"sheet_y":35,"short_name":"flag-in","short_names":["flag-in"],"text":null,"texts":null,"category":"Flags","sort_order":118,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"British Indian Ocean Territory Flag","unified":"1F1EE-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1f4.png","sheet_x":2,"sheet_y":36,"short_name":"flag-io","short_names":["flag-io"],"text":null,"texts":null,"category":"Flags","sort_order":119,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Iraq Flag","unified":"1F1EE-1F1F6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1f6.png","sheet_x":2,"sheet_y":37,"short_name":"flag-iq","short_names":["flag-iq"],"text":null,"texts":null,"category":"Flags","sort_order":120,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Iran Flag","unified":"1F1EE-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1f7.png","sheet_x":2,"sheet_y":38,"short_name":"flag-ir","short_names":["flag-ir"],"text":null,"texts":null,"category":"Flags","sort_order":121,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Iceland Flag","unified":"1F1EE-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ee-1f1f8.png","sheet_x":2,"sheet_y":39,"short_name":"flag-is","short_names":["flag-is"],"text":null,"texts":null,"category":"Flags","sort_order":122,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Italy Flag","unified":"1F1EE-1F1F9","non_qualified":null,"docomo":null,"au":"EB0F","softbank":"E50F","google":"FE4E9","image":"1f1ee-1f1f9.png","sheet_x":2,"sheet_y":40,"short_name":"it","short_names":["it","flag-it"],"text":null,"texts":null,"category":"Flags","sort_order":123,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Jersey Flag","unified":"1F1EF-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ef-1f1ea.png","sheet_x":2,"sheet_y":41,"short_name":"flag-je","short_names":["flag-je"],"text":null,"texts":null,"category":"Flags","sort_order":124,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Jamaica Flag","unified":"1F1EF-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ef-1f1f2.png","sheet_x":2,"sheet_y":42,"short_name":"flag-jm","short_names":["flag-jm"],"text":null,"texts":null,"category":"Flags","sort_order":125,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Jordan Flag","unified":"1F1EF-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ef-1f1f4.png","sheet_x":2,"sheet_y":43,"short_name":"flag-jo","short_names":["flag-jo"],"text":null,"texts":null,"category":"Flags","sort_order":126,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Japan Flag","unified":"1F1EF-1F1F5","non_qualified":null,"docomo":null,"au":"E4CC","softbank":"E50B","google":"FE4E5","image":"1f1ef-1f1f5.png","sheet_x":2,"sheet_y":44,"short_name":"jp","short_names":["jp","flag-jp"],"text":null,"texts":null,"category":"Flags","sort_order":127,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Kenya Flag","unified":"1F1F0-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1ea.png","sheet_x":2,"sheet_y":45,"short_name":"flag-ke","short_names":["flag-ke"],"text":null,"texts":null,"category":"Flags","sort_order":128,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Kyrgyzstan Flag","unified":"1F1F0-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1ec.png","sheet_x":2,"sheet_y":46,"short_name":"flag-kg","short_names":["flag-kg"],"text":null,"texts":null,"category":"Flags","sort_order":129,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Cambodia Flag","unified":"1F1F0-1F1ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1ed.png","sheet_x":2,"sheet_y":47,"short_name":"flag-kh","short_names":["flag-kh"],"text":null,"texts":null,"category":"Flags","sort_order":130,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Kiribati Flag","unified":"1F1F0-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1ee.png","sheet_x":2,"sheet_y":48,"short_name":"flag-ki","short_names":["flag-ki"],"text":null,"texts":null,"category":"Flags","sort_order":131,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Comoros Flag","unified":"1F1F0-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1f2.png","sheet_x":2,"sheet_y":49,"short_name":"flag-km","short_names":["flag-km"],"text":null,"texts":null,"category":"Flags","sort_order":132,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"St. Kitts & Nevis Flag","unified":"1F1F0-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1f3.png","sheet_x":2,"sheet_y":50,"short_name":"flag-kn","short_names":["flag-kn"],"text":null,"texts":null,"category":"Flags","sort_order":133,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"North Korea Flag","unified":"1F1F0-1F1F5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1f5.png","sheet_x":2,"sheet_y":51,"short_name":"flag-kp","short_names":["flag-kp"],"text":null,"texts":null,"category":"Flags","sort_order":134,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"South Korea Flag","unified":"1F1F0-1F1F7","non_qualified":null,"docomo":null,"au":"EB12","softbank":"E514","google":"FE4EE","image":"1f1f0-1f1f7.png","sheet_x":2,"sheet_y":52,"short_name":"kr","short_names":["kr","flag-kr"],"text":null,"texts":null,"category":"Flags","sort_order":135,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Kuwait Flag","unified":"1F1F0-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1fc.png","sheet_x":3,"sheet_y":0,"short_name":"flag-kw","short_names":["flag-kw"],"text":null,"texts":null,"category":"Flags","sort_order":136,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Cayman Islands Flag","unified":"1F1F0-1F1FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1fe.png","sheet_x":3,"sheet_y":1,"short_name":"flag-ky","short_names":["flag-ky"],"text":null,"texts":null,"category":"Flags","sort_order":137,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Kazakhstan Flag","unified":"1F1F0-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f0-1f1ff.png","sheet_x":3,"sheet_y":2,"short_name":"flag-kz","short_names":["flag-kz"],"text":null,"texts":null,"category":"Flags","sort_order":138,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Laos Flag","unified":"1F1F1-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1e6.png","sheet_x":3,"sheet_y":3,"short_name":"flag-la","short_names":["flag-la"],"text":null,"texts":null,"category":"Flags","sort_order":139,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Lebanon Flag","unified":"1F1F1-1F1E7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1e7.png","sheet_x":3,"sheet_y":4,"short_name":"flag-lb","short_names":["flag-lb"],"text":null,"texts":null,"category":"Flags","sort_order":140,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"St. Lucia Flag","unified":"1F1F1-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1e8.png","sheet_x":3,"sheet_y":5,"short_name":"flag-lc","short_names":["flag-lc"],"text":null,"texts":null,"category":"Flags","sort_order":141,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Liechtenstein Flag","unified":"1F1F1-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1ee.png","sheet_x":3,"sheet_y":6,"short_name":"flag-li","short_names":["flag-li"],"text":null,"texts":null,"category":"Flags","sort_order":142,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Sri Lanka Flag","unified":"1F1F1-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1f0.png","sheet_x":3,"sheet_y":7,"short_name":"flag-lk","short_names":["flag-lk"],"text":null,"texts":null,"category":"Flags","sort_order":143,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Liberia Flag","unified":"1F1F1-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1f7.png","sheet_x":3,"sheet_y":8,"short_name":"flag-lr","short_names":["flag-lr"],"text":null,"texts":null,"category":"Flags","sort_order":144,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Lesotho Flag","unified":"1F1F1-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1f8.png","sheet_x":3,"sheet_y":9,"short_name":"flag-ls","short_names":["flag-ls"],"text":null,"texts":null,"category":"Flags","sort_order":145,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Lithuania Flag","unified":"1F1F1-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1f9.png","sheet_x":3,"sheet_y":10,"short_name":"flag-lt","short_names":["flag-lt"],"text":null,"texts":null,"category":"Flags","sort_order":146,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Luxembourg Flag","unified":"1F1F1-1F1FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1fa.png","sheet_x":3,"sheet_y":11,"short_name":"flag-lu","short_names":["flag-lu"],"text":null,"texts":null,"category":"Flags","sort_order":147,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Latvia Flag","unified":"1F1F1-1F1FB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1fb.png","sheet_x":3,"sheet_y":12,"short_name":"flag-lv","short_names":["flag-lv"],"text":null,"texts":null,"category":"Flags","sort_order":148,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Libya Flag","unified":"1F1F1-1F1FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f1-1f1fe.png","sheet_x":3,"sheet_y":13,"short_name":"flag-ly","short_names":["flag-ly"],"text":null,"texts":null,"category":"Flags","sort_order":149,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Morocco Flag","unified":"1F1F2-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1e6.png","sheet_x":3,"sheet_y":14,"short_name":"flag-ma","short_names":["flag-ma"],"text":null,"texts":null,"category":"Flags","sort_order":150,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Monaco Flag","unified":"1F1F2-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1e8.png","sheet_x":3,"sheet_y":15,"short_name":"flag-mc","short_names":["flag-mc"],"text":null,"texts":null,"category":"Flags","sort_order":151,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Moldova Flag","unified":"1F1F2-1F1E9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1e9.png","sheet_x":3,"sheet_y":16,"short_name":"flag-md","short_names":["flag-md"],"text":null,"texts":null,"category":"Flags","sort_order":152,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Montenegro Flag","unified":"1F1F2-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1ea.png","sheet_x":3,"sheet_y":17,"short_name":"flag-me","short_names":["flag-me"],"text":null,"texts":null,"category":"Flags","sort_order":153,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"St. Martin Flag","unified":"1F1F2-1F1EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1eb.png","sheet_x":3,"sheet_y":18,"short_name":"flag-mf","short_names":["flag-mf"],"text":null,"texts":null,"category":"Flags","sort_order":154,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Madagascar Flag","unified":"1F1F2-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1ec.png","sheet_x":3,"sheet_y":19,"short_name":"flag-mg","short_names":["flag-mg"],"text":null,"texts":null,"category":"Flags","sort_order":155,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Marshall Islands Flag","unified":"1F1F2-1F1ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1ed.png","sheet_x":3,"sheet_y":20,"short_name":"flag-mh","short_names":["flag-mh"],"text":null,"texts":null,"category":"Flags","sort_order":156,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Macedonia Flag","unified":"1F1F2-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f0.png","sheet_x":3,"sheet_y":21,"short_name":"flag-mk","short_names":["flag-mk"],"text":null,"texts":null,"category":"Flags","sort_order":157,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Mali Flag","unified":"1F1F2-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f1.png","sheet_x":3,"sheet_y":22,"short_name":"flag-ml","short_names":["flag-ml"],"text":null,"texts":null,"category":"Flags","sort_order":158,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Myanmar (Burma) Flag","unified":"1F1F2-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f2.png","sheet_x":3,"sheet_y":23,"short_name":"flag-mm","short_names":["flag-mm"],"text":null,"texts":null,"category":"Flags","sort_order":159,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Mongolia Flag","unified":"1F1F2-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f3.png","sheet_x":3,"sheet_y":24,"short_name":"flag-mn","short_names":["flag-mn"],"text":null,"texts":null,"category":"Flags","sort_order":160,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Macau SAR China Flag","unified":"1F1F2-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f4.png","sheet_x":3,"sheet_y":25,"short_name":"flag-mo","short_names":["flag-mo"],"text":null,"texts":null,"category":"Flags","sort_order":161,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Northern Mariana Islands Flag","unified":"1F1F2-1F1F5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f5.png","sheet_x":3,"sheet_y":26,"short_name":"flag-mp","short_names":["flag-mp"],"text":null,"texts":null,"category":"Flags","sort_order":162,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Martinique Flag","unified":"1F1F2-1F1F6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f6.png","sheet_x":3,"sheet_y":27,"short_name":"flag-mq","short_names":["flag-mq"],"text":null,"texts":null,"category":"Flags","sort_order":163,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Mauritania Flag","unified":"1F1F2-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f7.png","sheet_x":3,"sheet_y":28,"short_name":"flag-mr","short_names":["flag-mr"],"text":null,"texts":null,"category":"Flags","sort_order":164,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Montserrat Flag","unified":"1F1F2-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f8.png","sheet_x":3,"sheet_y":29,"short_name":"flag-ms","short_names":["flag-ms"],"text":null,"texts":null,"category":"Flags","sort_order":165,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Malta Flag","unified":"1F1F2-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1f9.png","sheet_x":3,"sheet_y":30,"short_name":"flag-mt","short_names":["flag-mt"],"text":null,"texts":null,"category":"Flags","sort_order":166,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Mauritius Flag","unified":"1F1F2-1F1FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1fa.png","sheet_x":3,"sheet_y":31,"short_name":"flag-mu","short_names":["flag-mu"],"text":null,"texts":null,"category":"Flags","sort_order":167,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Maldives Flag","unified":"1F1F2-1F1FB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1fb.png","sheet_x":3,"sheet_y":32,"short_name":"flag-mv","short_names":["flag-mv"],"text":null,"texts":null,"category":"Flags","sort_order":168,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Malawi Flag","unified":"1F1F2-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1fc.png","sheet_x":3,"sheet_y":33,"short_name":"flag-mw","short_names":["flag-mw"],"text":null,"texts":null,"category":"Flags","sort_order":169,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Mexico Flag","unified":"1F1F2-1F1FD","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1fd.png","sheet_x":3,"sheet_y":34,"short_name":"flag-mx","short_names":["flag-mx"],"text":null,"texts":null,"category":"Flags","sort_order":170,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Malaysia Flag","unified":"1F1F2-1F1FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1fe.png","sheet_x":3,"sheet_y":35,"short_name":"flag-my","short_names":["flag-my"],"text":null,"texts":null,"category":"Flags","sort_order":171,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Mozambique Flag","unified":"1F1F2-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f2-1f1ff.png","sheet_x":3,"sheet_y":36,"short_name":"flag-mz","short_names":["flag-mz"],"text":null,"texts":null,"category":"Flags","sort_order":172,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Namibia Flag","unified":"1F1F3-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1e6.png","sheet_x":3,"sheet_y":37,"short_name":"flag-na","short_names":["flag-na"],"text":null,"texts":null,"category":"Flags","sort_order":173,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"New Caledonia Flag","unified":"1F1F3-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1e8.png","sheet_x":3,"sheet_y":38,"short_name":"flag-nc","short_names":["flag-nc"],"text":null,"texts":null,"category":"Flags","sort_order":174,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Niger Flag","unified":"1F1F3-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1ea.png","sheet_x":3,"sheet_y":39,"short_name":"flag-ne","short_names":["flag-ne"],"text":null,"texts":null,"category":"Flags","sort_order":175,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Norfolk Island Flag","unified":"1F1F3-1F1EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1eb.png","sheet_x":3,"sheet_y":40,"short_name":"flag-nf","short_names":["flag-nf"],"text":null,"texts":null,"category":"Flags","sort_order":176,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Nigeria Flag","unified":"1F1F3-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1ec.png","sheet_x":3,"sheet_y":41,"short_name":"flag-ng","short_names":["flag-ng"],"text":null,"texts":null,"category":"Flags","sort_order":177,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Nicaragua Flag","unified":"1F1F3-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1ee.png","sheet_x":3,"sheet_y":42,"short_name":"flag-ni","short_names":["flag-ni"],"text":null,"texts":null,"category":"Flags","sort_order":178,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Netherlands Flag","unified":"1F1F3-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1f1.png","sheet_x":3,"sheet_y":43,"short_name":"flag-nl","short_names":["flag-nl"],"text":null,"texts":null,"category":"Flags","sort_order":179,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Norway Flag","unified":"1F1F3-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1f4.png","sheet_x":3,"sheet_y":44,"short_name":"flag-no","short_names":["flag-no"],"text":null,"texts":null,"category":"Flags","sort_order":180,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Nepal Flag","unified":"1F1F3-1F1F5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1f5.png","sheet_x":3,"sheet_y":45,"short_name":"flag-np","short_names":["flag-np"],"text":null,"texts":null,"category":"Flags","sort_order":181,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Nauru Flag","unified":"1F1F3-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1f7.png","sheet_x":3,"sheet_y":46,"short_name":"flag-nr","short_names":["flag-nr"],"text":null,"texts":null,"category":"Flags","sort_order":182,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Niue Flag","unified":"1F1F3-1F1FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1fa.png","sheet_x":3,"sheet_y":47,"short_name":"flag-nu","short_names":["flag-nu"],"text":null,"texts":null,"category":"Flags","sort_order":183,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"New Zealand Flag","unified":"1F1F3-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f3-1f1ff.png","sheet_x":3,"sheet_y":48,"short_name":"flag-nz","short_names":["flag-nz"],"text":null,"texts":null,"category":"Flags","sort_order":184,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Oman Flag","unified":"1F1F4-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f4-1f1f2.png","sheet_x":3,"sheet_y":49,"short_name":"flag-om","short_names":["flag-om"],"text":null,"texts":null,"category":"Flags","sort_order":185,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Panama Flag","unified":"1F1F5-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1e6.png","sheet_x":3,"sheet_y":50,"short_name":"flag-pa","short_names":["flag-pa"],"text":null,"texts":null,"category":"Flags","sort_order":186,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Peru Flag","unified":"1F1F5-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1ea.png","sheet_x":3,"sheet_y":51,"short_name":"flag-pe","short_names":["flag-pe"],"text":null,"texts":null,"category":"Flags","sort_order":187,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"French Polynesia Flag","unified":"1F1F5-1F1EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1eb.png","sheet_x":3,"sheet_y":52,"short_name":"flag-pf","short_names":["flag-pf"],"text":null,"texts":null,"category":"Flags","sort_order":188,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Papua New Guinea Flag","unified":"1F1F5-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1ec.png","sheet_x":4,"sheet_y":0,"short_name":"flag-pg","short_names":["flag-pg"],"text":null,"texts":null,"category":"Flags","sort_order":189,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Philippines Flag","unified":"1F1F5-1F1ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1ed.png","sheet_x":4,"sheet_y":1,"short_name":"flag-ph","short_names":["flag-ph"],"text":null,"texts":null,"category":"Flags","sort_order":190,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Pakistan Flag","unified":"1F1F5-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1f0.png","sheet_x":4,"sheet_y":2,"short_name":"flag-pk","short_names":["flag-pk"],"text":null,"texts":null,"category":"Flags","sort_order":191,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Poland Flag","unified":"1F1F5-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1f1.png","sheet_x":4,"sheet_y":3,"short_name":"flag-pl","short_names":["flag-pl"],"text":null,"texts":null,"category":"Flags","sort_order":192,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"St. Pierre & Miquelon Flag","unified":"1F1F5-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1f2.png","sheet_x":4,"sheet_y":4,"short_name":"flag-pm","short_names":["flag-pm"],"text":null,"texts":null,"category":"Flags","sort_order":193,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Pitcairn Islands Flag","unified":"1F1F5-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1f3.png","sheet_x":4,"sheet_y":5,"short_name":"flag-pn","short_names":["flag-pn"],"text":null,"texts":null,"category":"Flags","sort_order":194,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Puerto Rico Flag","unified":"1F1F5-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1f7.png","sheet_x":4,"sheet_y":6,"short_name":"flag-pr","short_names":["flag-pr"],"text":null,"texts":null,"category":"Flags","sort_order":195,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Palestinian Territories Flag","unified":"1F1F5-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1f8.png","sheet_x":4,"sheet_y":7,"short_name":"flag-ps","short_names":["flag-ps"],"text":null,"texts":null,"category":"Flags","sort_order":196,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Portugal Flag","unified":"1F1F5-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1f9.png","sheet_x":4,"sheet_y":8,"short_name":"flag-pt","short_names":["flag-pt"],"text":null,"texts":null,"category":"Flags","sort_order":197,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Palau Flag","unified":"1F1F5-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1fc.png","sheet_x":4,"sheet_y":9,"short_name":"flag-pw","short_names":["flag-pw"],"text":null,"texts":null,"category":"Flags","sort_order":198,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Paraguay Flag","unified":"1F1F5-1F1FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f5-1f1fe.png","sheet_x":4,"sheet_y":10,"short_name":"flag-py","short_names":["flag-py"],"text":null,"texts":null,"category":"Flags","sort_order":199,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Qatar Flag","unified":"1F1F6-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f6-1f1e6.png","sheet_x":4,"sheet_y":11,"short_name":"flag-qa","short_names":["flag-qa"],"text":null,"texts":null,"category":"Flags","sort_order":200,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"R\u00e9union Flag","unified":"1F1F7-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f7-1f1ea.png","sheet_x":4,"sheet_y":12,"short_name":"flag-re","short_names":["flag-re"],"text":null,"texts":null,"category":"Flags","sort_order":201,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Romania Flag","unified":"1F1F7-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f7-1f1f4.png","sheet_x":4,"sheet_y":13,"short_name":"flag-ro","short_names":["flag-ro"],"text":null,"texts":null,"category":"Flags","sort_order":202,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Serbia Flag","unified":"1F1F7-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f7-1f1f8.png","sheet_x":4,"sheet_y":14,"short_name":"flag-rs","short_names":["flag-rs"],"text":null,"texts":null,"category":"Flags","sort_order":203,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Russia Flag","unified":"1F1F7-1F1FA","non_qualified":null,"docomo":null,"au":"E5D6","softbank":"E512","google":"FE4EC","image":"1f1f7-1f1fa.png","sheet_x":4,"sheet_y":15,"short_name":"ru","short_names":["ru","flag-ru"],"text":null,"texts":null,"category":"Flags","sort_order":204,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Rwanda Flag","unified":"1F1F7-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f7-1f1fc.png","sheet_x":4,"sheet_y":16,"short_name":"flag-rw","short_names":["flag-rw"],"text":null,"texts":null,"category":"Flags","sort_order":205,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Saudi Arabia Flag","unified":"1F1F8-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1e6.png","sheet_x":4,"sheet_y":17,"short_name":"flag-sa","short_names":["flag-sa"],"text":null,"texts":null,"category":"Flags","sort_order":206,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Solomon Islands Flag","unified":"1F1F8-1F1E7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1e7.png","sheet_x":4,"sheet_y":18,"short_name":"flag-sb","short_names":["flag-sb"],"text":null,"texts":null,"category":"Flags","sort_order":207,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Seychelles Flag","unified":"1F1F8-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1e8.png","sheet_x":4,"sheet_y":19,"short_name":"flag-sc","short_names":["flag-sc"],"text":null,"texts":null,"category":"Flags","sort_order":208,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Sudan Flag","unified":"1F1F8-1F1E9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1e9.png","sheet_x":4,"sheet_y":20,"short_name":"flag-sd","short_names":["flag-sd"],"text":null,"texts":null,"category":"Flags","sort_order":209,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Sweden Flag","unified":"1F1F8-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1ea.png","sheet_x":4,"sheet_y":21,"short_name":"flag-se","short_names":["flag-se"],"text":null,"texts":null,"category":"Flags","sort_order":210,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Singapore Flag","unified":"1F1F8-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1ec.png","sheet_x":4,"sheet_y":22,"short_name":"flag-sg","short_names":["flag-sg"],"text":null,"texts":null,"category":"Flags","sort_order":211,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"St. Helena Flag","unified":"1F1F8-1F1ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1ed.png","sheet_x":4,"sheet_y":23,"short_name":"flag-sh","short_names":["flag-sh"],"text":null,"texts":null,"category":"Flags","sort_order":212,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Slovenia Flag","unified":"1F1F8-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1ee.png","sheet_x":4,"sheet_y":24,"short_name":"flag-si","short_names":["flag-si"],"text":null,"texts":null,"category":"Flags","sort_order":213,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Svalbard & Jan Mayen Flag","unified":"1F1F8-1F1EF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1ef.png","sheet_x":4,"sheet_y":25,"short_name":"flag-sj","short_names":["flag-sj"],"text":null,"texts":null,"category":"Flags","sort_order":214,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Slovakia Flag","unified":"1F1F8-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1f0.png","sheet_x":4,"sheet_y":26,"short_name":"flag-sk","short_names":["flag-sk"],"text":null,"texts":null,"category":"Flags","sort_order":215,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Sierra Leone Flag","unified":"1F1F8-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1f1.png","sheet_x":4,"sheet_y":27,"short_name":"flag-sl","short_names":["flag-sl"],"text":null,"texts":null,"category":"Flags","sort_order":216,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"San Marino Flag","unified":"1F1F8-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1f2.png","sheet_x":4,"sheet_y":28,"short_name":"flag-sm","short_names":["flag-sm"],"text":null,"texts":null,"category":"Flags","sort_order":217,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Senegal Flag","unified":"1F1F8-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1f3.png","sheet_x":4,"sheet_y":29,"short_name":"flag-sn","short_names":["flag-sn"],"text":null,"texts":null,"category":"Flags","sort_order":218,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Somalia Flag","unified":"1F1F8-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1f4.png","sheet_x":4,"sheet_y":30,"short_name":"flag-so","short_names":["flag-so"],"text":null,"texts":null,"category":"Flags","sort_order":219,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Suriname Flag","unified":"1F1F8-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1f7.png","sheet_x":4,"sheet_y":31,"short_name":"flag-sr","short_names":["flag-sr"],"text":null,"texts":null,"category":"Flags","sort_order":220,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"South Sudan Flag","unified":"1F1F8-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1f8.png","sheet_x":4,"sheet_y":32,"short_name":"flag-ss","short_names":["flag-ss"],"text":null,"texts":null,"category":"Flags","sort_order":221,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"S\u00e3o Tom\u00e9 & Pr\u00edncipe Flag","unified":"1F1F8-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1f9.png","sheet_x":4,"sheet_y":33,"short_name":"flag-st","short_names":["flag-st"],"text":null,"texts":null,"category":"Flags","sort_order":222,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"El Salvador Flag","unified":"1F1F8-1F1FB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1fb.png","sheet_x":4,"sheet_y":34,"short_name":"flag-sv","short_names":["flag-sv"],"text":null,"texts":null,"category":"Flags","sort_order":223,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Sint Maarten Flag","unified":"1F1F8-1F1FD","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1fd.png","sheet_x":4,"sheet_y":35,"short_name":"flag-sx","short_names":["flag-sx"],"text":null,"texts":null,"category":"Flags","sort_order":224,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Syria Flag","unified":"1F1F8-1F1FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1fe.png","sheet_x":4,"sheet_y":36,"short_name":"flag-sy","short_names":["flag-sy"],"text":null,"texts":null,"category":"Flags","sort_order":225,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Swaziland Flag","unified":"1F1F8-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f8-1f1ff.png","sheet_x":4,"sheet_y":37,"short_name":"flag-sz","short_names":["flag-sz"],"text":null,"texts":null,"category":"Flags","sort_order":226,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Tristan da Cunha Flag","unified":"1F1F9-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1e6.png","sheet_x":4,"sheet_y":38,"short_name":"flag-ta","short_names":["flag-ta"],"text":null,"texts":null,"category":"Flags","sort_order":227,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Turks & Caicos Islands Flag","unified":"1F1F9-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1e8.png","sheet_x":4,"sheet_y":39,"short_name":"flag-tc","short_names":["flag-tc"],"text":null,"texts":null,"category":"Flags","sort_order":228,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Chad Flag","unified":"1F1F9-1F1E9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1e9.png","sheet_x":4,"sheet_y":40,"short_name":"flag-td","short_names":["flag-td"],"text":null,"texts":null,"category":"Flags","sort_order":229,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"French Southern Territories Flag","unified":"1F1F9-1F1EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1eb.png","sheet_x":4,"sheet_y":41,"short_name":"flag-tf","short_names":["flag-tf"],"text":null,"texts":null,"category":"Flags","sort_order":230,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Togo Flag","unified":"1F1F9-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1ec.png","sheet_x":4,"sheet_y":42,"short_name":"flag-tg","short_names":["flag-tg"],"text":null,"texts":null,"category":"Flags","sort_order":231,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Thailand Flag","unified":"1F1F9-1F1ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1ed.png","sheet_x":4,"sheet_y":43,"short_name":"flag-th","short_names":["flag-th"],"text":null,"texts":null,"category":"Flags","sort_order":232,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Tajikistan Flag","unified":"1F1F9-1F1EF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1ef.png","sheet_x":4,"sheet_y":44,"short_name":"flag-tj","short_names":["flag-tj"],"text":null,"texts":null,"category":"Flags","sort_order":233,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Tokelau Flag","unified":"1F1F9-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1f0.png","sheet_x":4,"sheet_y":45,"short_name":"flag-tk","short_names":["flag-tk"],"text":null,"texts":null,"category":"Flags","sort_order":234,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Timor-Leste Flag","unified":"1F1F9-1F1F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1f1.png","sheet_x":4,"sheet_y":46,"short_name":"flag-tl","short_names":["flag-tl"],"text":null,"texts":null,"category":"Flags","sort_order":235,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Turkmenistan Flag","unified":"1F1F9-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1f2.png","sheet_x":4,"sheet_y":47,"short_name":"flag-tm","short_names":["flag-tm"],"text":null,"texts":null,"category":"Flags","sort_order":236,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Tunisia Flag","unified":"1F1F9-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1f3.png","sheet_x":4,"sheet_y":48,"short_name":"flag-tn","short_names":["flag-tn"],"text":null,"texts":null,"category":"Flags","sort_order":237,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Tonga Flag","unified":"1F1F9-1F1F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1f4.png","sheet_x":4,"sheet_y":49,"short_name":"flag-to","short_names":["flag-to"],"text":null,"texts":null,"category":"Flags","sort_order":238,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Turkey Flag","unified":"1F1F9-1F1F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1f7.png","sheet_x":4,"sheet_y":50,"short_name":"flag-tr","short_names":["flag-tr"],"text":null,"texts":null,"category":"Flags","sort_order":239,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Trinidad & Tobago Flag","unified":"1F1F9-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1f9.png","sheet_x":4,"sheet_y":51,"short_name":"flag-tt","short_names":["flag-tt"],"text":null,"texts":null,"category":"Flags","sort_order":240,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Tuvalu Flag","unified":"1F1F9-1F1FB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1fb.png","sheet_x":4,"sheet_y":52,"short_name":"flag-tv","short_names":["flag-tv"],"text":null,"texts":null,"category":"Flags","sort_order":241,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Taiwan Flag","unified":"1F1F9-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1fc.png","sheet_x":5,"sheet_y":0,"short_name":"flag-tw","short_names":["flag-tw"],"text":null,"texts":null,"category":"Flags","sort_order":242,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Tanzania Flag","unified":"1F1F9-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1f9-1f1ff.png","sheet_x":5,"sheet_y":1,"short_name":"flag-tz","short_names":["flag-tz"],"text":null,"texts":null,"category":"Flags","sort_order":243,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Ukraine Flag","unified":"1F1FA-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fa-1f1e6.png","sheet_x":5,"sheet_y":2,"short_name":"flag-ua","short_names":["flag-ua"],"text":null,"texts":null,"category":"Flags","sort_order":244,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Uganda Flag","unified":"1F1FA-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fa-1f1ec.png","sheet_x":5,"sheet_y":3,"short_name":"flag-ug","short_names":["flag-ug"],"text":null,"texts":null,"category":"Flags","sort_order":245,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"U.S. Outlying Islands Flag","unified":"1F1FA-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fa-1f1f2.png","sheet_x":5,"sheet_y":4,"short_name":"flag-um","short_names":["flag-um"],"text":null,"texts":null,"category":"Flags","sort_order":246,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"United Nations Flag","unified":"1F1FA-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fa-1f1f3.png","sheet_x":5,"sheet_y":5,"short_name":"flag-un","short_names":["flag-un"],"text":null,"texts":null,"category":"Flags","sort_order":247,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"United States Flag","unified":"1F1FA-1F1F8","non_qualified":null,"docomo":null,"au":"E573","softbank":"E50C","google":"FE4E6","image":"1f1fa-1f1f8.png","sheet_x":5,"sheet_y":6,"short_name":"us","short_names":["us","flag-us"],"text":null,"texts":null,"category":"Flags","sort_order":248,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Uruguay Flag","unified":"1F1FA-1F1FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fa-1f1fe.png","sheet_x":5,"sheet_y":7,"short_name":"flag-uy","short_names":["flag-uy"],"text":null,"texts":null,"category":"Flags","sort_order":249,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Uzbekistan Flag","unified":"1F1FA-1F1FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fa-1f1ff.png","sheet_x":5,"sheet_y":8,"short_name":"flag-uz","short_names":["flag-uz"],"text":null,"texts":null,"category":"Flags","sort_order":250,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Vatican City Flag","unified":"1F1FB-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fb-1f1e6.png","sheet_x":5,"sheet_y":9,"short_name":"flag-va","short_names":["flag-va"],"text":null,"texts":null,"category":"Flags","sort_order":251,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"St. Vincent & Grenadines Flag","unified":"1F1FB-1F1E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fb-1f1e8.png","sheet_x":5,"sheet_y":10,"short_name":"flag-vc","short_names":["flag-vc"],"text":null,"texts":null,"category":"Flags","sort_order":252,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Venezuela Flag","unified":"1F1FB-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fb-1f1ea.png","sheet_x":5,"sheet_y":11,"short_name":"flag-ve","short_names":["flag-ve"],"text":null,"texts":null,"category":"Flags","sort_order":253,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"British Virgin Islands Flag","unified":"1F1FB-1F1EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fb-1f1ec.png","sheet_x":5,"sheet_y":12,"short_name":"flag-vg","short_names":["flag-vg"],"text":null,"texts":null,"category":"Flags","sort_order":254,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"U.S. Virgin Islands Flag","unified":"1F1FB-1F1EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fb-1f1ee.png","sheet_x":5,"sheet_y":13,"short_name":"flag-vi","short_names":["flag-vi"],"text":null,"texts":null,"category":"Flags","sort_order":255,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Vietnam Flag","unified":"1F1FB-1F1F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fb-1f1f3.png","sheet_x":5,"sheet_y":14,"short_name":"flag-vn","short_names":["flag-vn"],"text":null,"texts":null,"category":"Flags","sort_order":256,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Vanuatu Flag","unified":"1F1FB-1F1FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fb-1f1fa.png","sheet_x":5,"sheet_y":15,"short_name":"flag-vu","short_names":["flag-vu"],"text":null,"texts":null,"category":"Flags","sort_order":257,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Wallis & Futuna Flag","unified":"1F1FC-1F1EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fc-1f1eb.png","sheet_x":5,"sheet_y":16,"short_name":"flag-wf","short_names":["flag-wf"],"text":null,"texts":null,"category":"Flags","sort_order":258,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Samoa Flag","unified":"1F1FC-1F1F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fc-1f1f8.png","sheet_x":5,"sheet_y":17,"short_name":"flag-ws","short_names":["flag-ws"],"text":null,"texts":null,"category":"Flags","sort_order":259,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Kosovo Flag","unified":"1F1FD-1F1F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fd-1f1f0.png","sheet_x":5,"sheet_y":18,"short_name":"flag-xk","short_names":["flag-xk"],"text":null,"texts":null,"category":"Flags","sort_order":260,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Yemen Flag","unified":"1F1FE-1F1EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fe-1f1ea.png","sheet_x":5,"sheet_y":19,"short_name":"flag-ye","short_names":["flag-ye"],"text":null,"texts":null,"category":"Flags","sort_order":261,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Mayotte Flag","unified":"1F1FE-1F1F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1fe-1f1f9.png","sheet_x":5,"sheet_y":20,"short_name":"flag-yt","short_names":["flag-yt"],"text":null,"texts":null,"category":"Flags","sort_order":262,"added_in":"6.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"South Africa Flag","unified":"1F1FF-1F1E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ff-1f1e6.png","sheet_x":5,"sheet_y":21,"short_name":"flag-za","short_names":["flag-za"],"text":null,"texts":null,"category":"Flags","sort_order":263,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Zambia Flag","unified":"1F1FF-1F1F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ff-1f1f2.png","sheet_x":5,"sheet_y":22,"short_name":"flag-zm","short_names":["flag-zm"],"text":null,"texts":null,"category":"Flags","sort_order":264,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"Zimbabwe Flag","unified":"1F1FF-1F1FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f1ff-1f1fc.png","sheet_x":5,"sheet_y":23,"short_name":"flag-zw","short_names":["flag-zw"],"text":null,"texts":null,"category":"Flags","sort_order":265,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED KATAKANA KOKO","unified":"1F201","non_qualified":null,"docomo":null,"au":null,"softbank":"E203","google":"FEB24","image":"1f201.png","sheet_x":5,"sheet_y":24,"short_name":"koko","short_names":["koko"],"text":null,"texts":null,"category":"Symbols","sort_order":168,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED KATAKANA SA","unified":"1F202-FE0F","non_qualified":"1F202","docomo":null,"au":"EA87","softbank":"E228","google":"FEB3F","image":"1f202-fe0f.png","sheet_x":5,"sheet_y":25,"short_name":"sa","short_names":["sa"],"text":null,"texts":null,"category":"Symbols","sort_order":169,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-7121","unified":"1F21A","non_qualified":null,"docomo":null,"au":null,"softbank":"E216","google":"FEB3A","image":"1f21a.png","sheet_x":5,"sheet_y":26,"short_name":"u7121","short_names":["u7121"],"text":null,"texts":null,"category":"Symbols","sort_order":175,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-6307","unified":"1F22F","non_qualified":null,"docomo":null,"au":"EA8B","softbank":"E22C","google":"FEB40","image":"1f22f.png","sheet_x":5,"sheet_y":27,"short_name":"u6307","short_names":["u6307"],"text":null,"texts":null,"category":"Symbols","sort_order":172,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-7981","unified":"1F232","non_qualified":null,"docomo":"E738","au":null,"softbank":null,"google":"FEB2E","image":"1f232.png","sheet_x":5,"sheet_y":28,"short_name":"u7981","short_names":["u7981"],"text":null,"texts":null,"category":"Symbols","sort_order":176,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-7A7A","unified":"1F233","non_qualified":null,"docomo":"E739","au":"EA8A","softbank":"E22B","google":"FEB2F","image":"1f233.png","sheet_x":5,"sheet_y":29,"short_name":"u7a7a","short_names":["u7a7a"],"text":null,"texts":null,"category":"Symbols","sort_order":180,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-5408","unified":"1F234","non_qualified":null,"docomo":"E73A","au":null,"softbank":null,"google":"FEB30","image":"1f234.png","sheet_x":5,"sheet_y":30,"short_name":"u5408","short_names":["u5408"],"text":null,"texts":null,"category":"Symbols","sort_order":179,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-6E80","unified":"1F235","non_qualified":null,"docomo":"E73B","au":"EA89","softbank":"E22A","google":"FEB31","image":"1f235.png","sheet_x":5,"sheet_y":31,"short_name":"u6e80","short_names":["u6e80"],"text":null,"texts":null,"category":"Symbols","sort_order":184,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-6709","unified":"1F236","non_qualified":null,"docomo":null,"au":null,"softbank":"E215","google":"FEB39","image":"1f236.png","sheet_x":5,"sheet_y":32,"short_name":"u6709","short_names":["u6709"],"text":null,"texts":null,"category":"Symbols","sort_order":171,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-6708","unified":"1F237-FE0F","non_qualified":"1F237","docomo":null,"au":null,"softbank":"E217","google":"FEB3B","image":"1f237-fe0f.png","sheet_x":5,"sheet_y":33,"short_name":"u6708","short_names":["u6708"],"text":null,"texts":null,"category":"Symbols","sort_order":170,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-7533","unified":"1F238","non_qualified":null,"docomo":null,"au":null,"softbank":"E218","google":"FEB3C","image":"1f238.png","sheet_x":5,"sheet_y":34,"short_name":"u7533","short_names":["u7533"],"text":null,"texts":null,"category":"Symbols","sort_order":178,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-5272","unified":"1F239","non_qualified":null,"docomo":null,"au":"EA86","softbank":"E227","google":"FEB3E","image":"1f239.png","sheet_x":5,"sheet_y":35,"short_name":"u5272","short_names":["u5272"],"text":null,"texts":null,"category":"Symbols","sort_order":174,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SQUARED CJK UNIFIED IDEOGRAPH-55B6","unified":"1F23A","non_qualified":null,"docomo":null,"au":"EA8C","softbank":"E22D","google":"FEB41","image":"1f23a.png","sheet_x":5,"sheet_y":36,"short_name":"u55b6","short_names":["u55b6"],"text":null,"texts":null,"category":"Symbols","sort_order":183,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CIRCLED IDEOGRAPH ADVANTAGE","unified":"1F250","non_qualified":null,"docomo":null,"au":"E4F7","softbank":"E226","google":"FEB3D","image":"1f250.png","sheet_x":5,"sheet_y":37,"short_name":"ideograph_advantage","short_names":["ideograph_advantage"],"text":null,"texts":null,"category":"Symbols","sort_order":173,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CIRCLED IDEOGRAPH ACCEPT","unified":"1F251","non_qualified":null,"docomo":null,"au":"EB01","softbank":null,"google":"FEB50","image":"1f251.png","sheet_x":5,"sheet_y":38,"short_name":"accept","short_names":["accept"],"text":null,"texts":null,"category":"Symbols","sort_order":177,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CYCLONE","unified":"1F300","non_qualified":null,"docomo":"E643","au":"E469","softbank":"E443","google":"FE005","image":"1f300.png","sheet_x":5,"sheet_y":39,"short_name":"cyclone","short_names":["cyclone"],"text":null,"texts":null,"category":"Travel & Places","sort_order":189,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FOGGY","unified":"1F301","non_qualified":null,"docomo":"E644","au":"E598","softbank":null,"google":"FE006","image":"1f301.png","sheet_x":5,"sheet_y":40,"short_name":"foggy","short_names":["foggy"],"text":null,"texts":null,"category":"Travel & Places","sort_order":48,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOSED UMBRELLA","unified":"1F302","non_qualified":null,"docomo":"E645","au":"EAE8","softbank":"E43C","google":"FE007","image":"1f302.png","sheet_x":5,"sheet_y":41,"short_name":"closed_umbrella","short_names":["closed_umbrella"],"text":null,"texts":null,"category":"Travel & Places","sort_order":191,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NIGHT WITH STARS","unified":"1F303","non_qualified":null,"docomo":"E6B3","au":"EAF1","softbank":"E44B","google":"FE008","image":"1f303.png","sheet_x":5,"sheet_y":42,"short_name":"night_with_stars","short_names":["night_with_stars"],"text":null,"texts":null,"category":"Travel & Places","sort_order":49,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SUNRISE OVER MOUNTAINS","unified":"1F304","non_qualified":null,"docomo":"E63E","au":"EAF4","softbank":"E04D","google":"FE009","image":"1f304.png","sheet_x":5,"sheet_y":43,"short_name":"sunrise_over_mountains","short_names":["sunrise_over_mountains"],"text":null,"texts":null,"category":"Travel & Places","sort_order":51,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SUNRISE","unified":"1F305","non_qualified":null,"docomo":"E63E","au":"EAF4","softbank":"E449","google":"FE00A","image":"1f305.png","sheet_x":5,"sheet_y":44,"short_name":"sunrise","short_names":["sunrise"],"text":null,"texts":null,"category":"Travel & Places","sort_order":52,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CITYSCAPE AT DUSK","unified":"1F306","non_qualified":null,"docomo":null,"au":"E5DA","softbank":"E146","google":"FE00B","image":"1f306.png","sheet_x":5,"sheet_y":45,"short_name":"city_sunset","short_names":["city_sunset"],"text":null,"texts":null,"category":"Travel & Places","sort_order":53,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SUNSET OVER BUILDINGS","unified":"1F307","non_qualified":null,"docomo":"E63E","au":"E5DA","softbank":"E44A","google":"FE00C","image":"1f307.png","sheet_x":5,"sheet_y":46,"short_name":"city_sunrise","short_names":["city_sunrise"],"text":null,"texts":null,"category":"Travel & Places","sort_order":54,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RAINBOW","unified":"1F308","non_qualified":null,"docomo":null,"au":"EAF2","softbank":"E44C","google":"FE00D","image":"1f308.png","sheet_x":5,"sheet_y":47,"short_name":"rainbow","short_names":["rainbow"],"text":null,"texts":null,"category":"Travel & Places","sort_order":190,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BRIDGE AT NIGHT","unified":"1F309","non_qualified":null,"docomo":"E6B3","au":"E4BF","softbank":null,"google":"FE010","image":"1f309.png","sheet_x":5,"sheet_y":48,"short_name":"bridge_at_night","short_names":["bridge_at_night"],"text":null,"texts":null,"category":"Travel & Places","sort_order":55,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WATER WAVE","unified":"1F30A","non_qualified":null,"docomo":"E73F","au":"EB7C","softbank":"E43E","google":"FE038","image":"1f30a.png","sheet_x":5,"sheet_y":49,"short_name":"ocean","short_names":["ocean"],"text":null,"texts":null,"category":"Travel & Places","sort_order":202,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"VOLCANO","unified":"1F30B","non_qualified":null,"docomo":null,"au":"EB53","softbank":null,"google":"FE03A","image":"1f30b.png","sheet_x":5,"sheet_y":50,"short_name":"volcano","short_names":["volcano"],"text":null,"texts":null,"category":"Travel & Places","sort_order":10,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MILKY WAY","unified":"1F30C","non_qualified":null,"docomo":"E6B3","au":"EB5F","softbank":null,"google":"FE03B","image":"1f30c.png","sheet_x":5,"sheet_y":51,"short_name":"milky_way","short_names":["milky_way"],"text":null,"texts":null,"category":"Travel & Places","sort_order":57,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EARTH GLOBE EUROPE-AFRICA","unified":"1F30D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f30d.png","sheet_x":5,"sheet_y":52,"short_name":"earth_africa","short_names":["earth_africa"],"text":null,"texts":null,"category":"Travel & Places","sort_order":1,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EARTH GLOBE AMERICAS","unified":"1F30E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f30e.png","sheet_x":6,"sheet_y":0,"short_name":"earth_americas","short_names":["earth_americas"],"text":null,"texts":null,"category":"Travel & Places","sort_order":2,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EARTH GLOBE ASIA-AUSTRALIA","unified":"1F30F","non_qualified":null,"docomo":null,"au":"E5B3","softbank":null,"google":"FE039","image":"1f30f.png","sheet_x":6,"sheet_y":1,"short_name":"earth_asia","short_names":["earth_asia"],"text":null,"texts":null,"category":"Travel & Places","sort_order":3,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GLOBE WITH MERIDIANS","unified":"1F310","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f310.png","sheet_x":6,"sheet_y":2,"short_name":"globe_with_meridians","short_names":["globe_with_meridians"],"text":null,"texts":null,"category":"Travel & Places","sort_order":4,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEW MOON SYMBOL","unified":"1F311","non_qualified":null,"docomo":"E69C","au":"E5A8","softbank":null,"google":"FE011","image":"1f311.png","sheet_x":6,"sheet_y":3,"short_name":"new_moon","short_names":["new_moon"],"text":null,"texts":null,"category":"Travel & Places","sort_order":158,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WAXING CRESCENT MOON SYMBOL","unified":"1F312","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f312.png","sheet_x":6,"sheet_y":4,"short_name":"waxing_crescent_moon","short_names":["waxing_crescent_moon"],"text":null,"texts":null,"category":"Travel & Places","sort_order":159,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FIRST QUARTER MOON SYMBOL","unified":"1F313","non_qualified":null,"docomo":"E69E","au":"E5AA","softbank":null,"google":"FE013","image":"1f313.png","sheet_x":6,"sheet_y":5,"short_name":"first_quarter_moon","short_names":["first_quarter_moon"],"text":null,"texts":null,"category":"Travel & Places","sort_order":160,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WAXING GIBBOUS MOON SYMBOL","unified":"1F314","non_qualified":null,"docomo":"E69D","au":"E5A9","softbank":null,"google":"FE012","image":"1f314.png","sheet_x":6,"sheet_y":6,"short_name":"moon","short_names":["moon","waxing_gibbous_moon"],"text":null,"texts":null,"category":"Travel & Places","sort_order":161,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FULL MOON SYMBOL","unified":"1F315","non_qualified":null,"docomo":"E6A0","au":null,"softbank":null,"google":"FE015","image":"1f315.png","sheet_x":6,"sheet_y":7,"short_name":"full_moon","short_names":["full_moon"],"text":null,"texts":null,"category":"Travel & Places","sort_order":162,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WANING GIBBOUS MOON SYMBOL","unified":"1F316","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f316.png","sheet_x":6,"sheet_y":8,"short_name":"waning_gibbous_moon","short_names":["waning_gibbous_moon"],"text":null,"texts":null,"category":"Travel & Places","sort_order":163,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LAST QUARTER MOON SYMBOL","unified":"1F317","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f317.png","sheet_x":6,"sheet_y":9,"short_name":"last_quarter_moon","short_names":["last_quarter_moon"],"text":null,"texts":null,"category":"Travel & Places","sort_order":164,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WANING CRESCENT MOON SYMBOL","unified":"1F318","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f318.png","sheet_x":6,"sheet_y":10,"short_name":"waning_crescent_moon","short_names":["waning_crescent_moon"],"text":null,"texts":null,"category":"Travel & Places","sort_order":165,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CRESCENT MOON","unified":"1F319","non_qualified":null,"docomo":"E69F","au":"E486","softbank":"E04C","google":"FE014","image":"1f319.png","sheet_x":6,"sheet_y":11,"short_name":"crescent_moon","short_names":["crescent_moon"],"text":null,"texts":null,"category":"Travel & Places","sort_order":166,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEW MOON WITH FACE","unified":"1F31A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f31a.png","sheet_x":6,"sheet_y":12,"short_name":"new_moon_with_face","short_names":["new_moon_with_face"],"text":null,"texts":null,"category":"Travel & Places","sort_order":167,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FIRST QUARTER MOON WITH FACE","unified":"1F31B","non_qualified":null,"docomo":"E69E","au":"E489","softbank":null,"google":"FE016","image":"1f31b.png","sheet_x":6,"sheet_y":13,"short_name":"first_quarter_moon_with_face","short_names":["first_quarter_moon_with_face"],"text":null,"texts":null,"category":"Travel & Places","sort_order":168,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LAST QUARTER MOON WITH FACE","unified":"1F31C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f31c.png","sheet_x":6,"sheet_y":14,"short_name":"last_quarter_moon_with_face","short_names":["last_quarter_moon_with_face"],"text":null,"texts":null,"category":"Travel & Places","sort_order":169,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FULL MOON WITH FACE","unified":"1F31D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f31d.png","sheet_x":6,"sheet_y":15,"short_name":"full_moon_with_face","short_names":["full_moon_with_face"],"text":null,"texts":null,"category":"Travel & Places","sort_order":172,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SUN WITH FACE","unified":"1F31E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f31e.png","sheet_x":6,"sheet_y":16,"short_name":"sun_with_face","short_names":["sun_with_face"],"text":null,"texts":null,"category":"Travel & Places","sort_order":173,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GLOWING STAR","unified":"1F31F","non_qualified":null,"docomo":null,"au":"E48B","softbank":"E335","google":"FEB69","image":"1f31f.png","sheet_x":6,"sheet_y":17,"short_name":"star2","short_names":["star2"],"text":null,"texts":null,"category":"Travel & Places","sort_order":175,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SHOOTING STAR","unified":"1F320","non_qualified":null,"docomo":null,"au":"E468","softbank":null,"google":"FEB6A","image":"1f320.png","sheet_x":6,"sheet_y":18,"short_name":"stars","short_names":["stars"],"text":null,"texts":null,"category":"Travel & Places","sort_order":176,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F321-FE0F","non_qualified":"1F321","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f321-fe0f.png","sheet_x":6,"sheet_y":19,"short_name":"thermometer","short_names":["thermometer"],"text":null,"texts":null,"category":"Travel & Places","sort_order":170,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F324-FE0F","non_qualified":"1F324","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f324-fe0f.png","sheet_x":6,"sheet_y":20,"short_name":"mostly_sunny","short_names":["mostly_sunny","sun_small_cloud"],"text":null,"texts":null,"category":"Travel & Places","sort_order":180,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F325-FE0F","non_qualified":"1F325","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f325-fe0f.png","sheet_x":6,"sheet_y":21,"short_name":"barely_sunny","short_names":["barely_sunny","sun_behind_cloud"],"text":null,"texts":null,"category":"Travel & Places","sort_order":181,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F326-FE0F","non_qualified":"1F326","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f326-fe0f.png","sheet_x":6,"sheet_y":22,"short_name":"partly_sunny_rain","short_names":["partly_sunny_rain","sun_behind_rain_cloud"],"text":null,"texts":null,"category":"Travel & Places","sort_order":182,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F327-FE0F","non_qualified":"1F327","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f327-fe0f.png","sheet_x":6,"sheet_y":23,"short_name":"rain_cloud","short_names":["rain_cloud"],"text":null,"texts":null,"category":"Travel & Places","sort_order":183,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F328-FE0F","non_qualified":"1F328","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f328-fe0f.png","sheet_x":6,"sheet_y":24,"short_name":"snow_cloud","short_names":["snow_cloud"],"text":null,"texts":null,"category":"Travel & Places","sort_order":184,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F329-FE0F","non_qualified":"1F329","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f329-fe0f.png","sheet_x":6,"sheet_y":25,"short_name":"lightning","short_names":["lightning","lightning_cloud"],"text":null,"texts":null,"category":"Travel & Places","sort_order":185,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F32A-FE0F","non_qualified":"1F32A","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f32a-fe0f.png","sheet_x":6,"sheet_y":26,"short_name":"tornado","short_names":["tornado","tornado_cloud"],"text":null,"texts":null,"category":"Travel & Places","sort_order":186,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F32B-FE0F","non_qualified":"1F32B","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f32b-fe0f.png","sheet_x":6,"sheet_y":27,"short_name":"fog","short_names":["fog"],"text":null,"texts":null,"category":"Travel & Places","sort_order":187,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F32C-FE0F","non_qualified":"1F32C","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f32c-fe0f.png","sheet_x":6,"sheet_y":28,"short_name":"wind_blowing_face","short_names":["wind_blowing_face"],"text":null,"texts":null,"category":"Travel & Places","sort_order":188,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"HOT DOG","unified":"1F32D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f32d.png","sheet_x":6,"sheet_y":29,"short_name":"hotdog","short_names":["hotdog"],"text":null,"texts":null,"category":"Food & Drink","sort_order":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"TACO","unified":"1F32E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f32e.png","sheet_x":6,"sheet_y":30,"short_name":"taco","short_names":["taco"],"text":null,"texts":null,"category":"Food & Drink","sort_order":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BURRITO","unified":"1F32F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f32f.png","sheet_x":6,"sheet_y":31,"short_name":"burrito","short_names":["burrito"],"text":null,"texts":null,"category":"Food & Drink","sort_order":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CHESTNUT","unified":"1F330","non_qualified":null,"docomo":null,"au":"EB38","softbank":null,"google":"FE04C","image":"1f330.png","sheet_x":6,"sheet_y":32,"short_name":"chestnut","short_names":["chestnut"],"text":null,"texts":null,"category":"Food & Drink","sort_order":29,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SEEDLING","unified":"1F331","non_qualified":null,"docomo":"E746","au":"EB7D","softbank":null,"google":"FE03E","image":"1f331.png","sheet_x":6,"sheet_y":33,"short_name":"seedling","short_names":["seedling"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":113,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EVERGREEN TREE","unified":"1F332","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f332.png","sheet_x":6,"sheet_y":34,"short_name":"evergreen_tree","short_names":["evergreen_tree"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":114,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DECIDUOUS TREE","unified":"1F333","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f333.png","sheet_x":6,"sheet_y":35,"short_name":"deciduous_tree","short_names":["deciduous_tree"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":115,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PALM TREE","unified":"1F334","non_qualified":null,"docomo":null,"au":"E4E2","softbank":"E307","google":"FE047","image":"1f334.png","sheet_x":6,"sheet_y":36,"short_name":"palm_tree","short_names":["palm_tree"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":116,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CACTUS","unified":"1F335","non_qualified":null,"docomo":null,"au":"EA96","softbank":"E308","google":"FE048","image":"1f335.png","sheet_x":6,"sheet_y":37,"short_name":"cactus","short_names":["cactus"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":117,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F336-FE0F","non_qualified":"1F336","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f336-fe0f.png","sheet_x":6,"sheet_y":38,"short_name":"hot_pepper","short_names":["hot_pepper"],"text":null,"texts":null,"category":"Food & Drink","sort_order":23,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"TULIP","unified":"1F337","non_qualified":null,"docomo":"E743","au":"E4E4","softbank":"E304","google":"FE03D","image":"1f337.png","sheet_x":6,"sheet_y":39,"short_name":"tulip","short_names":["tulip"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":112,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHERRY BLOSSOM","unified":"1F338","non_qualified":null,"docomo":"E748","au":"E4CA","softbank":"E030","google":"FE040","image":"1f338.png","sheet_x":6,"sheet_y":40,"short_name":"cherry_blossom","short_names":["cherry_blossom"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":104,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ROSE","unified":"1F339","non_qualified":null,"docomo":null,"au":"E5BA","softbank":"E032","google":"FE041","image":"1f339.png","sheet_x":6,"sheet_y":41,"short_name":"rose","short_names":["rose"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":107,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HIBISCUS","unified":"1F33A","non_qualified":null,"docomo":null,"au":"EA94","softbank":"E303","google":"FE045","image":"1f33a.png","sheet_x":6,"sheet_y":42,"short_name":"hibiscus","short_names":["hibiscus"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":109,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SUNFLOWER","unified":"1F33B","non_qualified":null,"docomo":null,"au":"E4E3","softbank":"E305","google":"FE046","image":"1f33b.png","sheet_x":6,"sheet_y":43,"short_name":"sunflower","short_names":["sunflower"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":110,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLOSSOM","unified":"1F33C","non_qualified":null,"docomo":null,"au":"EB49","softbank":null,"google":"FE04D","image":"1f33c.png","sheet_x":6,"sheet_y":44,"short_name":"blossom","short_names":["blossom"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":111,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EAR OF MAIZE","unified":"1F33D","non_qualified":null,"docomo":null,"au":"EB36","softbank":null,"google":"FE04A","image":"1f33d.png","sheet_x":6,"sheet_y":45,"short_name":"corn","short_names":["corn"],"text":null,"texts":null,"category":"Food & Drink","sort_order":22,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EAR OF RICE","unified":"1F33E","non_qualified":null,"docomo":null,"au":null,"softbank":"E444","google":"FE049","image":"1f33e.png","sheet_x":6,"sheet_y":46,"short_name":"ear_of_rice","short_names":["ear_of_rice"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":118,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HERB","unified":"1F33F","non_qualified":null,"docomo":"E741","au":"EB82","softbank":null,"google":"FE04E","image":"1f33f.png","sheet_x":6,"sheet_y":47,"short_name":"herb","short_names":["herb"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":119,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FOUR LEAF CLOVER","unified":"1F340","non_qualified":null,"docomo":"E741","au":"E513","softbank":"E110","google":"FE03C","image":"1f340.png","sheet_x":6,"sheet_y":48,"short_name":"four_leaf_clover","short_names":["four_leaf_clover"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":121,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MAPLE LEAF","unified":"1F341","non_qualified":null,"docomo":"E747","au":"E4CE","softbank":"E118","google":"FE03F","image":"1f341.png","sheet_x":6,"sheet_y":49,"short_name":"maple_leaf","short_names":["maple_leaf"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":122,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FALLEN LEAF","unified":"1F342","non_qualified":null,"docomo":"E747","au":"E5CD","softbank":"E119","google":"FE042","image":"1f342.png","sheet_x":6,"sheet_y":50,"short_name":"fallen_leaf","short_names":["fallen_leaf"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":123,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEAF FLUTTERING IN WIND","unified":"1F343","non_qualified":null,"docomo":null,"au":"E5CD","softbank":"E447","google":"FE043","image":"1f343.png","sheet_x":6,"sheet_y":51,"short_name":"leaves","short_names":["leaves"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":124,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MUSHROOM","unified":"1F344","non_qualified":null,"docomo":null,"au":"EB37","softbank":null,"google":"FE04B","image":"1f344.png","sheet_x":6,"sheet_y":52,"short_name":"mushroom","short_names":["mushroom"],"text":null,"texts":null,"category":"Food & Drink","sort_order":27,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TOMATO","unified":"1F345","non_qualified":null,"docomo":null,"au":"EABB","softbank":"E349","google":"FE055","image":"1f345.png","sheet_x":7,"sheet_y":0,"short_name":"tomato","short_names":["tomato"],"text":null,"texts":null,"category":"Food & Drink","sort_order":16,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"AUBERGINE","unified":"1F346","non_qualified":null,"docomo":null,"au":"EABC","softbank":"E34A","google":"FE056","image":"1f346.png","sheet_x":7,"sheet_y":1,"short_name":"eggplant","short_names":["eggplant"],"text":null,"texts":null,"category":"Food & Drink","sort_order":19,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GRAPES","unified":"1F347","non_qualified":null,"docomo":null,"au":"EB34","softbank":null,"google":"FE059","image":"1f347.png","sheet_x":7,"sheet_y":2,"short_name":"grapes","short_names":["grapes"],"text":null,"texts":null,"category":"Food & Drink","sort_order":1,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MELON","unified":"1F348","non_qualified":null,"docomo":null,"au":"EB32","softbank":null,"google":"FE057","image":"1f348.png","sheet_x":7,"sheet_y":3,"short_name":"melon","short_names":["melon"],"text":null,"texts":null,"category":"Food & Drink","sort_order":2,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WATERMELON","unified":"1F349","non_qualified":null,"docomo":null,"au":"E4CD","softbank":"E348","google":"FE054","image":"1f349.png","sheet_x":7,"sheet_y":4,"short_name":"watermelon","short_names":["watermelon"],"text":null,"texts":null,"category":"Food & Drink","sort_order":3,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TANGERINE","unified":"1F34A","non_qualified":null,"docomo":null,"au":"EABA","softbank":"E346","google":"FE052","image":"1f34a.png","sheet_x":7,"sheet_y":5,"short_name":"tangerine","short_names":["tangerine"],"text":null,"texts":null,"category":"Food & Drink","sort_order":4,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEMON","unified":"1F34B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f34b.png","sheet_x":7,"sheet_y":6,"short_name":"lemon","short_names":["lemon"],"text":null,"texts":null,"category":"Food & Drink","sort_order":5,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BANANA","unified":"1F34C","non_qualified":null,"docomo":"E744","au":"EB35","softbank":null,"google":"FE050","image":"1f34c.png","sheet_x":7,"sheet_y":7,"short_name":"banana","short_names":["banana"],"text":null,"texts":null,"category":"Food & Drink","sort_order":6,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PINEAPPLE","unified":"1F34D","non_qualified":null,"docomo":null,"au":"EB33","softbank":null,"google":"FE058","image":"1f34d.png","sheet_x":7,"sheet_y":8,"short_name":"pineapple","short_names":["pineapple"],"text":null,"texts":null,"category":"Food & Drink","sort_order":7,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RED APPLE","unified":"1F34E","non_qualified":null,"docomo":"E745","au":"EAB9","softbank":"E345","google":"FE051","image":"1f34e.png","sheet_x":7,"sheet_y":9,"short_name":"apple","short_names":["apple"],"text":null,"texts":null,"category":"Food & Drink","sort_order":9,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GREEN APPLE","unified":"1F34F","non_qualified":null,"docomo":"E745","au":"EB5A","softbank":null,"google":"FE05B","image":"1f34f.png","sheet_x":7,"sheet_y":10,"short_name":"green_apple","short_names":["green_apple"],"text":null,"texts":null,"category":"Food & Drink","sort_order":10,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PEAR","unified":"1F350","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f350.png","sheet_x":7,"sheet_y":11,"short_name":"pear","short_names":["pear"],"text":null,"texts":null,"category":"Food & Drink","sort_order":11,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PEACH","unified":"1F351","non_qualified":null,"docomo":null,"au":"EB39","softbank":null,"google":"FE05A","image":"1f351.png","sheet_x":7,"sheet_y":12,"short_name":"peach","short_names":["peach"],"text":null,"texts":null,"category":"Food & Drink","sort_order":12,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHERRIES","unified":"1F352","non_qualified":null,"docomo":"E742","au":"E4D2","softbank":null,"google":"FE04F","image":"1f352.png","sheet_x":7,"sheet_y":13,"short_name":"cherries","short_names":["cherries"],"text":null,"texts":null,"category":"Food & Drink","sort_order":13,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"STRAWBERRY","unified":"1F353","non_qualified":null,"docomo":null,"au":"E4D4","softbank":"E347","google":"FE053","image":"1f353.png","sheet_x":7,"sheet_y":14,"short_name":"strawberry","short_names":["strawberry"],"text":null,"texts":null,"category":"Food & Drink","sort_order":14,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HAMBURGER","unified":"1F354","non_qualified":null,"docomo":"E673","au":"E4D6","softbank":"E120","google":"FE960","image":"1f354.png","sheet_x":7,"sheet_y":15,"short_name":"hamburger","short_names":["hamburger"],"text":null,"texts":null,"category":"Food & Drink","sort_order":41,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SLICE OF PIZZA","unified":"1F355","non_qualified":null,"docomo":null,"au":"EB3B","softbank":null,"google":"FE975","image":"1f355.png","sheet_x":7,"sheet_y":16,"short_name":"pizza","short_names":["pizza"],"text":null,"texts":null,"category":"Food & Drink","sort_order":43,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MEAT ON BONE","unified":"1F356","non_qualified":null,"docomo":null,"au":"E4C4","softbank":null,"google":"FE972","image":"1f356.png","sheet_x":7,"sheet_y":17,"short_name":"meat_on_bone","short_names":["meat_on_bone"],"text":null,"texts":null,"category":"Food & Drink","sort_order":37,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POULTRY LEG","unified":"1F357","non_qualified":null,"docomo":null,"au":"EB3C","softbank":null,"google":"FE976","image":"1f357.png","sheet_x":7,"sheet_y":18,"short_name":"poultry_leg","short_names":["poultry_leg"],"text":null,"texts":null,"category":"Food & Drink","sort_order":38,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RICE CRACKER","unified":"1F358","non_qualified":null,"docomo":null,"au":"EAB3","softbank":"E33D","google":"FE969","image":"1f358.png","sheet_x":7,"sheet_y":19,"short_name":"rice_cracker","short_names":["rice_cracker"],"text":null,"texts":null,"category":"Food & Drink","sort_order":59,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RICE BALL","unified":"1F359","non_qualified":null,"docomo":"E749","au":"E4D5","softbank":"E342","google":"FE961","image":"1f359.png","sheet_x":7,"sheet_y":20,"short_name":"rice_ball","short_names":["rice_ball"],"text":null,"texts":null,"category":"Food & Drink","sort_order":60,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"COOKED RICE","unified":"1F35A","non_qualified":null,"docomo":"E74C","au":"EAB4","softbank":"E33E","google":"FE96A","image":"1f35a.png","sheet_x":7,"sheet_y":21,"short_name":"rice","short_names":["rice"],"text":null,"texts":null,"category":"Food & Drink","sort_order":61,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CURRY AND RICE","unified":"1F35B","non_qualified":null,"docomo":null,"au":"EAB6","softbank":"E341","google":"FE96C","image":"1f35b.png","sheet_x":7,"sheet_y":22,"short_name":"curry","short_names":["curry"],"text":null,"texts":null,"category":"Food & Drink","sort_order":62,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"STEAMING BOWL","unified":"1F35C","non_qualified":null,"docomo":"E74C","au":"E5B4","softbank":"E340","google":"FE963","image":"1f35c.png","sheet_x":7,"sheet_y":23,"short_name":"ramen","short_names":["ramen"],"text":null,"texts":null,"category":"Food & Drink","sort_order":63,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPAGHETTI","unified":"1F35D","non_qualified":null,"docomo":null,"au":"EAB5","softbank":"E33F","google":"FE96B","image":"1f35d.png","sheet_x":7,"sheet_y":24,"short_name":"spaghetti","short_names":["spaghetti"],"text":null,"texts":null,"category":"Food & Drink","sort_order":64,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BREAD","unified":"1F35E","non_qualified":null,"docomo":"E74D","au":"EAAF","softbank":"E339","google":"FE964","image":"1f35e.png","sheet_x":7,"sheet_y":25,"short_name":"bread","short_names":["bread"],"text":null,"texts":null,"category":"Food & Drink","sort_order":30,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FRENCH FRIES","unified":"1F35F","non_qualified":null,"docomo":null,"au":"EAB1","softbank":"E33B","google":"FE967","image":"1f35f.png","sheet_x":7,"sheet_y":26,"short_name":"fries","short_names":["fries"],"text":null,"texts":null,"category":"Food & Drink","sort_order":42,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ROASTED SWEET POTATO","unified":"1F360","non_qualified":null,"docomo":null,"au":"EB3A","softbank":null,"google":"FE974","image":"1f360.png","sheet_x":7,"sheet_y":27,"short_name":"sweet_potato","short_names":["sweet_potato"],"text":null,"texts":null,"category":"Food & Drink","sort_order":65,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DANGO","unified":"1F361","non_qualified":null,"docomo":null,"au":"EAB2","softbank":"E33C","google":"FE968","image":"1f361.png","sheet_x":7,"sheet_y":28,"short_name":"dango","short_names":["dango"],"text":null,"texts":null,"category":"Food & Drink","sort_order":71,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ODEN","unified":"1F362","non_qualified":null,"docomo":null,"au":"EAB7","softbank":"E343","google":"FE96D","image":"1f362.png","sheet_x":7,"sheet_y":29,"short_name":"oden","short_names":["oden"],"text":null,"texts":null,"category":"Food & Drink","sort_order":66,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SUSHI","unified":"1F363","non_qualified":null,"docomo":null,"au":"EAB8","softbank":"E344","google":"FE96E","image":"1f363.png","sheet_x":7,"sheet_y":30,"short_name":"sushi","short_names":["sushi"],"text":null,"texts":null,"category":"Food & Drink","sort_order":67,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FRIED SHRIMP","unified":"1F364","non_qualified":null,"docomo":null,"au":"EB70","softbank":null,"google":"FE97F","image":"1f364.png","sheet_x":7,"sheet_y":31,"short_name":"fried_shrimp","short_names":["fried_shrimp"],"text":null,"texts":null,"category":"Food & Drink","sort_order":68,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FISH CAKE WITH SWIRL DESIGN","unified":"1F365","non_qualified":null,"docomo":"E643","au":"E4ED","softbank":null,"google":"FE973","image":"1f365.png","sheet_x":7,"sheet_y":32,"short_name":"fish_cake","short_names":["fish_cake"],"text":null,"texts":null,"category":"Food & Drink","sort_order":69,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SOFT ICE CREAM","unified":"1F366","non_qualified":null,"docomo":null,"au":"EAB0","softbank":"E33A","google":"FE966","image":"1f366.png","sheet_x":7,"sheet_y":33,"short_name":"icecream","short_names":["icecream"],"text":null,"texts":null,"category":"Food & Drink","sort_order":75,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SHAVED ICE","unified":"1F367","non_qualified":null,"docomo":null,"au":"EAEA","softbank":"E43F","google":"FE971","image":"1f367.png","sheet_x":7,"sheet_y":34,"short_name":"shaved_ice","short_names":["shaved_ice"],"text":null,"texts":null,"category":"Food & Drink","sort_order":76,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ICE CREAM","unified":"1F368","non_qualified":null,"docomo":null,"au":"EB4A","softbank":null,"google":"FE977","image":"1f368.png","sheet_x":7,"sheet_y":35,"short_name":"ice_cream","short_names":["ice_cream"],"text":null,"texts":null,"category":"Food & Drink","sort_order":77,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DOUGHNUT","unified":"1F369","non_qualified":null,"docomo":null,"au":"EB4B","softbank":null,"google":"FE978","image":"1f369.png","sheet_x":7,"sheet_y":36,"short_name":"doughnut","short_names":["doughnut"],"text":null,"texts":null,"category":"Food & Drink","sort_order":78,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"COOKIE","unified":"1F36A","non_qualified":null,"docomo":null,"au":"EB4C","softbank":null,"google":"FE979","image":"1f36a.png","sheet_x":7,"sheet_y":37,"short_name":"cookie","short_names":["cookie"],"text":null,"texts":null,"category":"Food & Drink","sort_order":79,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHOCOLATE BAR","unified":"1F36B","non_qualified":null,"docomo":null,"au":"EB4D","softbank":null,"google":"FE97A","image":"1f36b.png","sheet_x":7,"sheet_y":38,"short_name":"chocolate_bar","short_names":["chocolate_bar"],"text":null,"texts":null,"category":"Food & Drink","sort_order":84,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CANDY","unified":"1F36C","non_qualified":null,"docomo":null,"au":"EB4E","softbank":null,"google":"FE97B","image":"1f36c.png","sheet_x":7,"sheet_y":39,"short_name":"candy","short_names":["candy"],"text":null,"texts":null,"category":"Food & Drink","sort_order":85,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LOLLIPOP","unified":"1F36D","non_qualified":null,"docomo":null,"au":"EB4F","softbank":null,"google":"FE97C","image":"1f36d.png","sheet_x":7,"sheet_y":40,"short_name":"lollipop","short_names":["lollipop"],"text":null,"texts":null,"category":"Food & Drink","sort_order":86,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CUSTARD","unified":"1F36E","non_qualified":null,"docomo":null,"au":"EB56","softbank":null,"google":"FE97D","image":"1f36e.png","sheet_x":7,"sheet_y":41,"short_name":"custard","short_names":["custard"],"text":null,"texts":null,"category":"Food & Drink","sort_order":87,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HONEY POT","unified":"1F36F","non_qualified":null,"docomo":null,"au":"EB59","softbank":null,"google":"FE97E","image":"1f36f.png","sheet_x":7,"sheet_y":42,"short_name":"honey_pot","short_names":["honey_pot"],"text":null,"texts":null,"category":"Food & Drink","sort_order":88,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SHORTCAKE","unified":"1F370","non_qualified":null,"docomo":"E74A","au":"E4D0","softbank":"E046","google":"FE962","image":"1f370.png","sheet_x":7,"sheet_y":43,"short_name":"cake","short_names":["cake"],"text":null,"texts":null,"category":"Food & Drink","sort_order":81,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BENTO BOX","unified":"1F371","non_qualified":null,"docomo":null,"au":"EABD","softbank":"E34C","google":"FE96F","image":"1f371.png","sheet_x":7,"sheet_y":44,"short_name":"bento","short_names":["bento"],"text":null,"texts":null,"category":"Food & Drink","sort_order":58,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POT OF FOOD","unified":"1F372","non_qualified":null,"docomo":null,"au":"EABE","softbank":"E34D","google":"FE970","image":"1f372.png","sheet_x":7,"sheet_y":45,"short_name":"stew","short_names":["stew"],"text":null,"texts":null,"category":"Food & Drink","sort_order":52,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"COOKING","unified":"1F373","non_qualified":null,"docomo":null,"au":"E4D1","softbank":"E147","google":"FE965","image":"1f373.png","sheet_x":7,"sheet_y":46,"short_name":"fried_egg","short_names":["fried_egg","cooking"],"text":null,"texts":null,"category":"Food & Drink","sort_order":50,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FORK AND KNIFE","unified":"1F374","non_qualified":null,"docomo":"E66F","au":"E4AC","softbank":"E043","google":"FE980","image":"1f374.png","sheet_x":7,"sheet_y":47,"short_name":"fork_and_knife","short_names":["fork_and_knife"],"text":null,"texts":null,"category":"Food & Drink","sort_order":105,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TEACUP WITHOUT HANDLE","unified":"1F375","non_qualified":null,"docomo":"E71E","au":"EAAE","softbank":"E338","google":"FE984","image":"1f375.png","sheet_x":7,"sheet_y":48,"short_name":"tea","short_names":["tea"],"text":null,"texts":null,"category":"Food & Drink","sort_order":92,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SAKE BOTTLE AND CUP","unified":"1F376","non_qualified":null,"docomo":"E74B","au":"EA97","softbank":"E30B","google":"FE985","image":"1f376.png","sheet_x":7,"sheet_y":49,"short_name":"sake","short_names":["sake"],"text":null,"texts":null,"category":"Food & Drink","sort_order":93,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WINE GLASS","unified":"1F377","non_qualified":null,"docomo":"E756","au":"E4C1","softbank":null,"google":"FE986","image":"1f377.png","sheet_x":7,"sheet_y":50,"short_name":"wine_glass","short_names":["wine_glass"],"text":null,"texts":null,"category":"Food & Drink","sort_order":95,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"COCKTAIL GLASS","unified":"1F378","non_qualified":null,"docomo":"E671","au":"E4C2","softbank":"E044","google":"FE982","image":"1f378.png","sheet_x":7,"sheet_y":51,"short_name":"cocktail","short_names":["cocktail"],"text":null,"texts":null,"category":"Food & Drink","sort_order":96,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TROPICAL DRINK","unified":"1F379","non_qualified":null,"docomo":"E671","au":"EB3E","softbank":null,"google":"FE988","image":"1f379.png","sheet_x":7,"sheet_y":52,"short_name":"tropical_drink","short_names":["tropical_drink"],"text":null,"texts":null,"category":"Food & Drink","sort_order":97,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BEER MUG","unified":"1F37A","non_qualified":null,"docomo":"E672","au":"E4C3","softbank":"E047","google":"FE983","image":"1f37a.png","sheet_x":8,"sheet_y":0,"short_name":"beer","short_names":["beer"],"text":null,"texts":null,"category":"Food & Drink","sort_order":98,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLINKING BEER MUGS","unified":"1F37B","non_qualified":null,"docomo":"E672","au":"EA98","softbank":"E30C","google":"FE987","image":"1f37b.png","sheet_x":8,"sheet_y":1,"short_name":"beers","short_names":["beers"],"text":null,"texts":null,"category":"Food & Drink","sort_order":99,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BABY BOTTLE","unified":"1F37C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f37c.png","sheet_x":8,"sheet_y":2,"short_name":"baby_bottle","short_names":["baby_bottle"],"text":null,"texts":null,"category":"Food & Drink","sort_order":89,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F37D-FE0F","non_qualified":"1F37D","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f37d-fe0f.png","sheet_x":8,"sheet_y":3,"short_name":"knife_fork_plate","short_names":["knife_fork_plate"],"text":null,"texts":null,"category":"Food & Drink","sort_order":104,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BOTTLE WITH POPPING CORK","unified":"1F37E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f37e.png","sheet_x":8,"sheet_y":4,"short_name":"champagne","short_names":["champagne"],"text":null,"texts":null,"category":"Food & Drink","sort_order":94,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"POPCORN","unified":"1F37F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f37f.png","sheet_x":8,"sheet_y":5,"short_name":"popcorn","short_names":["popcorn"],"text":null,"texts":null,"category":"Food & Drink","sort_order":55,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"RIBBON","unified":"1F380","non_qualified":null,"docomo":"E684","au":"E59F","softbank":"E314","google":"FE50F","image":"1f380.png","sheet_x":8,"sheet_y":6,"short_name":"ribbon","short_names":["ribbon"],"text":null,"texts":null,"category":"Activities","sort_order":17,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WRAPPED PRESENT","unified":"1F381","non_qualified":null,"docomo":"E685","au":"E4CF","softbank":"E112","google":"FE510","image":"1f381.png","sheet_x":8,"sheet_y":7,"short_name":"gift","short_names":["gift"],"text":null,"texts":null,"category":"Activities","sort_order":18,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BIRTHDAY CAKE","unified":"1F382","non_qualified":null,"docomo":"E686","au":"E5A0","softbank":"E34B","google":"FE511","image":"1f382.png","sheet_x":8,"sheet_y":8,"short_name":"birthday","short_names":["birthday"],"text":null,"texts":null,"category":"Food & Drink","sort_order":80,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"JACK-O-LANTERN","unified":"1F383","non_qualified":null,"docomo":null,"au":"EAEE","softbank":"E445","google":"FE51F","image":"1f383.png","sheet_x":8,"sheet_y":9,"short_name":"jack_o_lantern","short_names":["jack_o_lantern"],"text":null,"texts":null,"category":"Activities","sort_order":1,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHRISTMAS TREE","unified":"1F384","non_qualified":null,"docomo":"E6A4","au":"E4C9","softbank":"E033","google":"FE512","image":"1f384.png","sheet_x":8,"sheet_y":10,"short_name":"christmas_tree","short_names":["christmas_tree"],"text":null,"texts":null,"category":"Activities","sort_order":2,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FATHER CHRISTMAS","unified":"1F385","non_qualified":null,"docomo":null,"au":"EAF0","softbank":"E448","google":"FE513","image":"1f385.png","sheet_x":8,"sheet_y":11,"short_name":"santa","short_names":["santa"],"text":null,"texts":null,"category":"Smileys & People","sort_order":192,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F385-1F3FB","non_qualified":null,"image":"1f385-1f3fb.png","sheet_x":8,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F385-1F3FC","non_qualified":null,"image":"1f385-1f3fc.png","sheet_x":8,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F385-1F3FD","non_qualified":null,"image":"1f385-1f3fd.png","sheet_x":8,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F385-1F3FE","non_qualified":null,"image":"1f385-1f3fe.png","sheet_x":8,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F385-1F3FF","non_qualified":null,"image":"1f385-1f3ff.png","sheet_x":8,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"FIREWORKS","unified":"1F386","non_qualified":null,"docomo":null,"au":"E5CC","softbank":"E117","google":"FE515","image":"1f386.png","sheet_x":8,"sheet_y":17,"short_name":"fireworks","short_names":["fireworks"],"text":null,"texts":null,"category":"Activities","sort_order":3,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FIREWORK SPARKLER","unified":"1F387","non_qualified":null,"docomo":null,"au":"EAEB","softbank":"E440","google":"FE51D","image":"1f387.png","sheet_x":8,"sheet_y":18,"short_name":"sparkler","short_names":["sparkler"],"text":null,"texts":null,"category":"Activities","sort_order":4,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BALLOON","unified":"1F388","non_qualified":null,"docomo":null,"au":"EA9B","softbank":"E310","google":"FE516","image":"1f388.png","sheet_x":8,"sheet_y":19,"short_name":"balloon","short_names":["balloon"],"text":null,"texts":null,"category":"Activities","sort_order":7,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PARTY POPPER","unified":"1F389","non_qualified":null,"docomo":null,"au":"EA9C","softbank":"E312","google":"FE517","image":"1f389.png","sheet_x":8,"sheet_y":20,"short_name":"tada","short_names":["tada"],"text":null,"texts":null,"category":"Activities","sort_order":8,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CONFETTI BALL","unified":"1F38A","non_qualified":null,"docomo":null,"au":"E46F","softbank":null,"google":"FE520","image":"1f38a.png","sheet_x":8,"sheet_y":21,"short_name":"confetti_ball","short_names":["confetti_ball"],"text":null,"texts":null,"category":"Activities","sort_order":9,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TANABATA TREE","unified":"1F38B","non_qualified":null,"docomo":null,"au":"EB3D","softbank":null,"google":"FE521","image":"1f38b.png","sheet_x":8,"sheet_y":22,"short_name":"tanabata_tree","short_names":["tanabata_tree"],"text":null,"texts":null,"category":"Activities","sort_order":10,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CROSSED FLAGS","unified":"1F38C","non_qualified":null,"docomo":null,"au":"E5D9","softbank":"E143","google":"FE514","image":"1f38c.png","sheet_x":8,"sheet_y":23,"short_name":"crossed_flags","short_names":["crossed_flags"],"text":null,"texts":null,"category":"Flags","sort_order":3,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PINE DECORATION","unified":"1F38D","non_qualified":null,"docomo":null,"au":"EAE3","softbank":"E436","google":"FE518","image":"1f38d.png","sheet_x":8,"sheet_y":24,"short_name":"bamboo","short_names":["bamboo"],"text":null,"texts":null,"category":"Activities","sort_order":11,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"JAPANESE DOLLS","unified":"1F38E","non_qualified":null,"docomo":null,"au":"EAE4","softbank":"E438","google":"FE519","image":"1f38e.png","sheet_x":8,"sheet_y":25,"short_name":"dolls","short_names":["dolls"],"text":null,"texts":null,"category":"Activities","sort_order":12,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CARP STREAMER","unified":"1F38F","non_qualified":null,"docomo":null,"au":"EAE7","softbank":"E43B","google":"FE51C","image":"1f38f.png","sheet_x":8,"sheet_y":26,"short_name":"flags","short_names":["flags"],"text":null,"texts":null,"category":"Activities","sort_order":13,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WIND CHIME","unified":"1F390","non_qualified":null,"docomo":null,"au":"EAED","softbank":"E442","google":"FE51E","image":"1f390.png","sheet_x":8,"sheet_y":27,"short_name":"wind_chime","short_names":["wind_chime"],"text":null,"texts":null,"category":"Activities","sort_order":14,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOON VIEWING CEREMONY","unified":"1F391","non_qualified":null,"docomo":null,"au":"EAEF","softbank":"E446","google":"FE017","image":"1f391.png","sheet_x":8,"sheet_y":28,"short_name":"rice_scene","short_names":["rice_scene"],"text":null,"texts":null,"category":"Activities","sort_order":15,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SCHOOL SATCHEL","unified":"1F392","non_qualified":null,"docomo":null,"au":"EAE6","softbank":"E43A","google":"FE51B","image":"1f392.png","sheet_x":8,"sheet_y":29,"short_name":"school_satchel","short_names":["school_satchel"],"text":null,"texts":null,"category":"Smileys & People","sort_order":456,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GRADUATION CAP","unified":"1F393","non_qualified":null,"docomo":null,"au":"EAE5","softbank":"E439","google":"FE51A","image":"1f393.png","sheet_x":8,"sheet_y":30,"short_name":"mortar_board","short_names":["mortar_board"],"text":null,"texts":null,"category":"Smileys & People","sort_order":467,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F396-FE0F","non_qualified":"1F396","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f396-fe0f.png","sheet_x":8,"sheet_y":31,"short_name":"medal","short_names":["medal"],"text":null,"texts":null,"category":"Activities","sort_order":22,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F397-FE0F","non_qualified":"1F397","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f397-fe0f.png","sheet_x":8,"sheet_y":32,"short_name":"reminder_ribbon","short_names":["reminder_ribbon"],"text":null,"texts":null,"category":"Activities","sort_order":19,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F399-FE0F","non_qualified":"1F399","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f399-fe0f.png","sheet_x":8,"sheet_y":33,"short_name":"studio_microphone","short_names":["studio_microphone"],"text":null,"texts":null,"category":"Objects","sort_order":13,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F39A-FE0F","non_qualified":"1F39A","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f39a-fe0f.png","sheet_x":8,"sheet_y":34,"short_name":"level_slider","short_names":["level_slider"],"text":null,"texts":null,"category":"Objects","sort_order":14,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F39B-FE0F","non_qualified":"1F39B","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f39b-fe0f.png","sheet_x":8,"sheet_y":35,"short_name":"control_knobs","short_names":["control_knobs"],"text":null,"texts":null,"category":"Objects","sort_order":15,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F39E-FE0F","non_qualified":"1F39E","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f39e-fe0f.png","sheet_x":8,"sheet_y":36,"short_name":"film_frames","short_names":["film_frames"],"text":null,"texts":null,"category":"Objects","sort_order":45,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F39F-FE0F","non_qualified":"1F39F","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f39f-fe0f.png","sheet_x":8,"sheet_y":37,"short_name":"admission_tickets","short_names":["admission_tickets"],"text":null,"texts":null,"category":"Activities","sort_order":20,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CAROUSEL HORSE","unified":"1F3A0","non_qualified":null,"docomo":"E679","au":null,"softbank":null,"google":"FE7FC","image":"1f3a0.png","sheet_x":8,"sheet_y":38,"short_name":"carousel_horse","short_names":["carousel_horse"],"text":null,"texts":null,"category":"Travel & Places","sort_order":58,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FERRIS WHEEL","unified":"1F3A1","non_qualified":null,"docomo":null,"au":"E46D","softbank":"E124","google":"FE7FD","image":"1f3a1.png","sheet_x":8,"sheet_y":39,"short_name":"ferris_wheel","short_names":["ferris_wheel"],"text":null,"texts":null,"category":"Travel & Places","sort_order":59,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ROLLER COASTER","unified":"1F3A2","non_qualified":null,"docomo":null,"au":"EAE2","softbank":"E433","google":"FE7FE","image":"1f3a2.png","sheet_x":8,"sheet_y":40,"short_name":"roller_coaster","short_names":["roller_coaster"],"text":null,"texts":null,"category":"Travel & Places","sort_order":60,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FISHING POLE AND FISH","unified":"1F3A3","non_qualified":null,"docomo":"E751","au":"EB42","softbank":null,"google":"FE7FF","image":"1f3a3.png","sheet_x":8,"sheet_y":41,"short_name":"fishing_pole_and_fish","short_names":["fishing_pole_and_fish"],"text":null,"texts":null,"category":"Activities","sort_order":49,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MICROPHONE","unified":"1F3A4","non_qualified":null,"docomo":"E676","au":"E503","softbank":"E03C","google":"FE800","image":"1f3a4.png","sheet_x":8,"sheet_y":42,"short_name":"microphone","short_names":["microphone"],"text":null,"texts":null,"category":"Objects","sort_order":16,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOVIE CAMERA","unified":"1F3A5","non_qualified":null,"docomo":"E677","au":"E517","softbank":"E03D","google":"FE801","image":"1f3a5.png","sheet_x":8,"sheet_y":43,"short_name":"movie_camera","short_names":["movie_camera"],"text":null,"texts":null,"category":"Objects","sort_order":44,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CINEMA","unified":"1F3A6","non_qualified":null,"docomo":"E677","au":"E517","softbank":"E507","google":"FE802","image":"1f3a6.png","sheet_x":8,"sheet_y":44,"short_name":"cinema","short_names":["cinema"],"text":null,"texts":null,"category":"Symbols","sort_order":91,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEADPHONE","unified":"1F3A7","non_qualified":null,"docomo":"E67A","au":"E508","softbank":"E30A","google":"FE803","image":"1f3a7.png","sheet_x":8,"sheet_y":45,"short_name":"headphones","short_names":["headphones"],"text":null,"texts":null,"category":"Objects","sort_order":17,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ARTIST PALETTE","unified":"1F3A8","non_qualified":null,"docomo":"E67B","au":"E59C","softbank":"E502","google":"FE804","image":"1f3a8.png","sheet_x":8,"sheet_y":46,"short_name":"art","short_names":["art"],"text":null,"texts":null,"category":"Activities","sort_order":74,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TOP HAT","unified":"1F3A9","non_qualified":null,"docomo":"E67C","au":"EAF5","softbank":"E503","google":"FE805","image":"1f3a9.png","sheet_x":8,"sheet_y":47,"short_name":"tophat","short_names":["tophat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":466,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CIRCUS TENT","unified":"1F3AA","non_qualified":null,"docomo":"E67D","au":"E59E","softbank":null,"google":"FE806","image":"1f3aa.png","sheet_x":8,"sheet_y":48,"short_name":"circus_tent","short_names":["circus_tent"],"text":null,"texts":null,"category":"Travel & Places","sort_order":62,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TICKET","unified":"1F3AB","non_qualified":null,"docomo":"E67E","au":"E49E","softbank":"E125","google":"FE807","image":"1f3ab.png","sheet_x":8,"sheet_y":49,"short_name":"ticket","short_names":["ticket"],"text":null,"texts":null,"category":"Activities","sort_order":21,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLAPPER BOARD","unified":"1F3AC","non_qualified":null,"docomo":"E6AC","au":"E4BE","softbank":"E324","google":"FE808","image":"1f3ac.png","sheet_x":8,"sheet_y":50,"short_name":"clapper","short_names":["clapper"],"text":null,"texts":null,"category":"Objects","sort_order":47,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PERFORMING ARTS","unified":"1F3AD","non_qualified":null,"docomo":null,"au":"E59D","softbank":null,"google":"FE809","image":"1f3ad.png","sheet_x":8,"sheet_y":51,"short_name":"performing_arts","short_names":["performing_arts"],"text":null,"texts":null,"category":"Activities","sort_order":72,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"VIDEO GAME","unified":"1F3AE","non_qualified":null,"docomo":"E68B","au":"E4C6","softbank":null,"google":"FE80A","image":"1f3ae.png","sheet_x":8,"sheet_y":52,"short_name":"video_game","short_names":["video_game"],"text":null,"texts":null,"category":"Activities","sort_order":58,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DIRECT HIT","unified":"1F3AF","non_qualified":null,"docomo":null,"au":"E4C5","softbank":"E130","google":"FE80C","image":"1f3af.png","sheet_x":9,"sheet_y":0,"short_name":"dart","short_names":["dart"],"text":null,"texts":null,"category":"Activities","sort_order":54,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SLOT MACHINE","unified":"1F3B0","non_qualified":null,"docomo":null,"au":"E46E","softbank":"E133","google":"FE80D","image":"1f3b0.png","sheet_x":9,"sheet_y":1,"short_name":"slot_machine","short_names":["slot_machine"],"text":null,"texts":null,"category":"Activities","sort_order":60,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BILLIARDS","unified":"1F3B1","non_qualified":null,"docomo":null,"au":"EADD","softbank":"E42C","google":"FE80E","image":"1f3b1.png","sheet_x":9,"sheet_y":2,"short_name":"8ball","short_names":["8ball"],"text":null,"texts":null,"category":"Activities","sort_order":55,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GAME DIE","unified":"1F3B2","non_qualified":null,"docomo":null,"au":"E4C8","softbank":null,"google":"FE80F","image":"1f3b2.png","sheet_x":9,"sheet_y":3,"short_name":"game_die","short_names":["game_die"],"text":null,"texts":null,"category":"Activities","sort_order":61,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BOWLING","unified":"1F3B3","non_qualified":null,"docomo":null,"au":"EB43","softbank":null,"google":"FE810","image":"1f3b3.png","sheet_x":9,"sheet_y":4,"short_name":"bowling","short_names":["bowling"],"text":null,"texts":null,"category":"Activities","sort_order":37,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FLOWER PLAYING CARDS","unified":"1F3B4","non_qualified":null,"docomo":null,"au":"EB6E","softbank":null,"google":"FE811","image":"1f3b4.png","sheet_x":9,"sheet_y":5,"short_name":"flower_playing_cards","short_names":["flower_playing_cards"],"text":null,"texts":null,"category":"Activities","sort_order":71,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MUSICAL NOTE","unified":"1F3B5","non_qualified":null,"docomo":"E6F6","au":"E5BE","softbank":"E03E","google":"FE813","image":"1f3b5.png","sheet_x":9,"sheet_y":6,"short_name":"musical_note","short_names":["musical_note"],"text":null,"texts":null,"category":"Objects","sort_order":11,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MULTIPLE MUSICAL NOTES","unified":"1F3B6","non_qualified":null,"docomo":"E6FF","au":"E505","softbank":"E326","google":"FE814","image":"1f3b6.png","sheet_x":9,"sheet_y":7,"short_name":"notes","short_names":["notes"],"text":null,"texts":null,"category":"Objects","sort_order":12,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SAXOPHONE","unified":"1F3B7","non_qualified":null,"docomo":null,"au":null,"softbank":"E040","google":"FE815","image":"1f3b7.png","sheet_x":9,"sheet_y":8,"short_name":"saxophone","short_names":["saxophone"],"text":null,"texts":null,"category":"Objects","sort_order":19,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GUITAR","unified":"1F3B8","non_qualified":null,"docomo":null,"au":"E506","softbank":"E041","google":"FE816","image":"1f3b8.png","sheet_x":9,"sheet_y":9,"short_name":"guitar","short_names":["guitar"],"text":null,"texts":null,"category":"Objects","sort_order":20,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MUSICAL KEYBOARD","unified":"1F3B9","non_qualified":null,"docomo":null,"au":"EB40","softbank":null,"google":"FE817","image":"1f3b9.png","sheet_x":9,"sheet_y":10,"short_name":"musical_keyboard","short_names":["musical_keyboard"],"text":null,"texts":null,"category":"Objects","sort_order":21,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TRUMPET","unified":"1F3BA","non_qualified":null,"docomo":null,"au":"EADC","softbank":"E042","google":"FE818","image":"1f3ba.png","sheet_x":9,"sheet_y":11,"short_name":"trumpet","short_names":["trumpet"],"text":null,"texts":null,"category":"Objects","sort_order":22,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"VIOLIN","unified":"1F3BB","non_qualified":null,"docomo":null,"au":"E507","softbank":null,"google":"FE819","image":"1f3bb.png","sheet_x":9,"sheet_y":12,"short_name":"violin","short_names":["violin"],"text":null,"texts":null,"category":"Objects","sort_order":23,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MUSICAL SCORE","unified":"1F3BC","non_qualified":null,"docomo":"E6FF","au":"EACC","softbank":null,"google":"FE81A","image":"1f3bc.png","sheet_x":9,"sheet_y":13,"short_name":"musical_score","short_names":["musical_score"],"text":null,"texts":null,"category":"Objects","sort_order":10,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RUNNING SHIRT WITH SASH","unified":"1F3BD","non_qualified":null,"docomo":"E652","au":null,"softbank":null,"google":"FE7D0","image":"1f3bd.png","sheet_x":9,"sheet_y":14,"short_name":"running_shirt_with_sash","short_names":["running_shirt_with_sash"],"text":null,"texts":null,"category":"Activities","sort_order":50,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TENNIS RACQUET AND BALL","unified":"1F3BE","non_qualified":null,"docomo":"E655","au":"E4B7","softbank":"E015","google":"FE7D3","image":"1f3be.png","sheet_x":9,"sheet_y":15,"short_name":"tennis","short_names":["tennis"],"text":null,"texts":null,"category":"Activities","sort_order":35,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SKI AND SKI BOOT","unified":"1F3BF","non_qualified":null,"docomo":"E657","au":"EAAC","softbank":"E013","google":"FE7D5","image":"1f3bf.png","sheet_x":9,"sheet_y":16,"short_name":"ski","short_names":["ski"],"text":null,"texts":null,"category":"Activities","sort_order":51,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BASKETBALL AND HOOP","unified":"1F3C0","non_qualified":null,"docomo":"E658","au":"E59A","softbank":"E42A","google":"FE7D6","image":"1f3c0.png","sheet_x":9,"sheet_y":17,"short_name":"basketball","short_names":["basketball"],"text":null,"texts":null,"category":"Activities","sort_order":31,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHEQUERED FLAG","unified":"1F3C1","non_qualified":null,"docomo":"E659","au":"E4B9","softbank":"E132","google":"FE7D7","image":"1f3c1.png","sheet_x":9,"sheet_y":18,"short_name":"checkered_flag","short_names":["checkered_flag"],"text":null,"texts":null,"category":"Flags","sort_order":1,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SNOWBOARDER","unified":"1F3C2","non_qualified":null,"docomo":"E712","au":"E4B8","softbank":null,"google":"FE7D8","image":"1f3c2.png","sheet_x":9,"sheet_y":19,"short_name":"snowboarder","short_names":["snowboarder"],"text":null,"texts":null,"category":"Smileys & People","sort_order":281,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F3C2-1F3FB","non_qualified":null,"image":"1f3c2-1f3fb.png","sheet_x":9,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F3C2-1F3FC","non_qualified":null,"image":"1f3c2-1f3fc.png","sheet_x":9,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F3C2-1F3FD","non_qualified":null,"image":"1f3c2-1f3fd.png","sheet_x":9,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F3C2-1F3FE","non_qualified":null,"image":"1f3c2-1f3fe.png","sheet_x":9,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F3C2-1F3FF","non_qualified":null,"image":"1f3c2-1f3ff.png","sheet_x":9,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"1F3C3-200D-2640-FE0F","non_qualified":"1F3C3-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3c3-200d-2640-fe0f.png","sheet_x":9,"sheet_y":25,"short_name":"woman-running","short_names":["woman-running"],"text":null,"texts":null,"category":"Smileys & People","sort_order":257,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3C3-1F3FB-200D-2640-FE0F","non_qualified":"1F3C3-1F3FB-200D-2640","image":"1f3c3-1f3fb-200d-2640-fe0f.png","sheet_x":9,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3C3-1F3FC-200D-2640-FE0F","non_qualified":"1F3C3-1F3FC-200D-2640","image":"1f3c3-1f3fc-200d-2640-fe0f.png","sheet_x":9,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3C3-1F3FD-200D-2640-FE0F","non_qualified":"1F3C3-1F3FD-200D-2640","image":"1f3c3-1f3fd-200d-2640-fe0f.png","sheet_x":9,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3C3-1F3FE-200D-2640-FE0F","non_qualified":"1F3C3-1F3FE-200D-2640","image":"1f3c3-1f3fe-200d-2640-fe0f.png","sheet_x":9,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3C3-1F3FF-200D-2640-FE0F","non_qualified":"1F3C3-1F3FF-200D-2640","image":"1f3c3-1f3ff-200d-2640-fe0f.png","sheet_x":9,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F3C3-200D-2642-FE0F","non_qualified":"1F3C3-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3c3-200d-2642-fe0f.png","sheet_x":9,"sheet_y":31,"short_name":"man-running","short_names":["man-running"],"text":null,"texts":null,"category":"Smileys & People","sort_order":256,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3C3-1F3FB-200D-2642-FE0F","non_qualified":"1F3C3-1F3FB-200D-2642","image":"1f3c3-1f3fb-200d-2642-fe0f.png","sheet_x":9,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3C3-1F3FC-200D-2642-FE0F","non_qualified":"1F3C3-1F3FC-200D-2642","image":"1f3c3-1f3fc-200d-2642-fe0f.png","sheet_x":9,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3C3-1F3FD-200D-2642-FE0F","non_qualified":"1F3C3-1F3FD-200D-2642","image":"1f3c3-1f3fd-200d-2642-fe0f.png","sheet_x":9,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3C3-1F3FE-200D-2642-FE0F","non_qualified":"1F3C3-1F3FE-200D-2642","image":"1f3c3-1f3fe-200d-2642-fe0f.png","sheet_x":9,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3C3-1F3FF-200D-2642-FE0F","non_qualified":"1F3C3-1F3FF-200D-2642","image":"1f3c3-1f3ff-200d-2642-fe0f.png","sheet_x":9,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F3C3"},{"name":"RUNNER","unified":"1F3C3","non_qualified":null,"docomo":"E733","au":"E46B","softbank":"E115","google":"FE7D9","image":"1f3c3.png","sheet_x":9,"sheet_y":37,"short_name":"runner","short_names":["runner","running"],"text":null,"texts":null,"category":"Smileys & People","sort_order":255,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F3C3-1F3FB","non_qualified":null,"image":"1f3c3-1f3fb.png","sheet_x":9,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F3C3-1F3FC","non_qualified":null,"image":"1f3c3-1f3fc.png","sheet_x":9,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F3C3-1F3FD","non_qualified":null,"image":"1f3c3-1f3fd.png","sheet_x":9,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F3C3-1F3FE","non_qualified":null,"image":"1f3c3-1f3fe.png","sheet_x":9,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F3C3-1F3FF","non_qualified":null,"image":"1f3c3-1f3ff.png","sheet_x":9,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F3C3-200D-2642-FE0F"},{"name":null,"unified":"1F3C4-200D-2640-FE0F","non_qualified":"1F3C4-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3c4-200d-2640-fe0f.png","sheet_x":9,"sheet_y":43,"short_name":"woman-surfing","short_names":["woman-surfing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":287,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3C4-1F3FB-200D-2640-FE0F","non_qualified":"1F3C4-1F3FB-200D-2640","image":"1f3c4-1f3fb-200d-2640-fe0f.png","sheet_x":9,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3C4-1F3FC-200D-2640-FE0F","non_qualified":"1F3C4-1F3FC-200D-2640","image":"1f3c4-1f3fc-200d-2640-fe0f.png","sheet_x":9,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3C4-1F3FD-200D-2640-FE0F","non_qualified":"1F3C4-1F3FD-200D-2640","image":"1f3c4-1f3fd-200d-2640-fe0f.png","sheet_x":9,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3C4-1F3FE-200D-2640-FE0F","non_qualified":"1F3C4-1F3FE-200D-2640","image":"1f3c4-1f3fe-200d-2640-fe0f.png","sheet_x":9,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3C4-1F3FF-200D-2640-FE0F","non_qualified":"1F3C4-1F3FF-200D-2640","image":"1f3c4-1f3ff-200d-2640-fe0f.png","sheet_x":9,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F3C4-200D-2642-FE0F","non_qualified":"1F3C4-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3c4-200d-2642-fe0f.png","sheet_x":9,"sheet_y":49,"short_name":"man-surfing","short_names":["man-surfing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":286,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3C4-1F3FB-200D-2642-FE0F","non_qualified":"1F3C4-1F3FB-200D-2642","image":"1f3c4-1f3fb-200d-2642-fe0f.png","sheet_x":9,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3C4-1F3FC-200D-2642-FE0F","non_qualified":"1F3C4-1F3FC-200D-2642","image":"1f3c4-1f3fc-200d-2642-fe0f.png","sheet_x":9,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3C4-1F3FD-200D-2642-FE0F","non_qualified":"1F3C4-1F3FD-200D-2642","image":"1f3c4-1f3fd-200d-2642-fe0f.png","sheet_x":9,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3C4-1F3FE-200D-2642-FE0F","non_qualified":"1F3C4-1F3FE-200D-2642","image":"1f3c4-1f3fe-200d-2642-fe0f.png","sheet_x":10,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3C4-1F3FF-200D-2642-FE0F","non_qualified":"1F3C4-1F3FF-200D-2642","image":"1f3c4-1f3ff-200d-2642-fe0f.png","sheet_x":10,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F3C4"},{"name":"SURFER","unified":"1F3C4","non_qualified":null,"docomo":"E712","au":"EB41","softbank":"E017","google":"FE7DA","image":"1f3c4.png","sheet_x":10,"sheet_y":2,"short_name":"surfer","short_names":["surfer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":285,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F3C4-1F3FB","non_qualified":null,"image":"1f3c4-1f3fb.png","sheet_x":10,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F3C4-1F3FC","non_qualified":null,"image":"1f3c4-1f3fc.png","sheet_x":10,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F3C4-1F3FD","non_qualified":null,"image":"1f3c4-1f3fd.png","sheet_x":10,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F3C4-1F3FE","non_qualified":null,"image":"1f3c4-1f3fe.png","sheet_x":10,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F3C4-1F3FF","non_qualified":null,"image":"1f3c4-1f3ff.png","sheet_x":10,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F3C4-200D-2642-FE0F"},{"name":"SPORTS MEDAL","unified":"1F3C5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3c5.png","sheet_x":10,"sheet_y":8,"short_name":"sports_medal","short_names":["sports_medal"],"text":null,"texts":null,"category":"Activities","sort_order":24,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"TROPHY","unified":"1F3C6","non_qualified":null,"docomo":null,"au":"E5D3","softbank":"E131","google":"FE7DB","image":"1f3c6.png","sheet_x":10,"sheet_y":9,"short_name":"trophy","short_names":["trophy"],"text":null,"texts":null,"category":"Activities","sort_order":23,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HORSE RACING","unified":"1F3C7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3c7.png","sheet_x":10,"sheet_y":10,"short_name":"horse_racing","short_names":["horse_racing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":279,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F3C7-1F3FB","non_qualified":null,"image":"1f3c7-1f3fb.png","sheet_x":10,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F3C7-1F3FC","non_qualified":null,"image":"1f3c7-1f3fc.png","sheet_x":10,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F3C7-1F3FD","non_qualified":null,"image":"1f3c7-1f3fd.png","sheet_x":10,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F3C7-1F3FE","non_qualified":null,"image":"1f3c7-1f3fe.png","sheet_x":10,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F3C7-1F3FF","non_qualified":null,"image":"1f3c7-1f3ff.png","sheet_x":10,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"AMERICAN FOOTBALL","unified":"1F3C8","non_qualified":null,"docomo":null,"au":"E4BB","softbank":"E42B","google":"FE7DD","image":"1f3c8.png","sheet_x":10,"sheet_y":16,"short_name":"football","short_names":["football"],"text":null,"texts":null,"category":"Activities","sort_order":33,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RUGBY FOOTBALL","unified":"1F3C9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3c9.png","sheet_x":10,"sheet_y":17,"short_name":"rugby_football","short_names":["rugby_football"],"text":null,"texts":null,"category":"Activities","sort_order":34,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F3CA-200D-2640-FE0F","non_qualified":"1F3CA-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3ca-200d-2640-fe0f.png","sheet_x":10,"sheet_y":18,"short_name":"woman-swimming","short_names":["woman-swimming"],"text":null,"texts":null,"category":"Smileys & People","sort_order":293,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3CA-1F3FB-200D-2640-FE0F","non_qualified":"1F3CA-1F3FB-200D-2640","image":"1f3ca-1f3fb-200d-2640-fe0f.png","sheet_x":10,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3CA-1F3FC-200D-2640-FE0F","non_qualified":"1F3CA-1F3FC-200D-2640","image":"1f3ca-1f3fc-200d-2640-fe0f.png","sheet_x":10,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3CA-1F3FD-200D-2640-FE0F","non_qualified":"1F3CA-1F3FD-200D-2640","image":"1f3ca-1f3fd-200d-2640-fe0f.png","sheet_x":10,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3CA-1F3FE-200D-2640-FE0F","non_qualified":"1F3CA-1F3FE-200D-2640","image":"1f3ca-1f3fe-200d-2640-fe0f.png","sheet_x":10,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3CA-1F3FF-200D-2640-FE0F","non_qualified":"1F3CA-1F3FF-200D-2640","image":"1f3ca-1f3ff-200d-2640-fe0f.png","sheet_x":10,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F3CA-200D-2642-FE0F","non_qualified":"1F3CA-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3ca-200d-2642-fe0f.png","sheet_x":10,"sheet_y":24,"short_name":"man-swimming","short_names":["man-swimming"],"text":null,"texts":null,"category":"Smileys & People","sort_order":292,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3CA-1F3FB-200D-2642-FE0F","non_qualified":"1F3CA-1F3FB-200D-2642","image":"1f3ca-1f3fb-200d-2642-fe0f.png","sheet_x":10,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3CA-1F3FC-200D-2642-FE0F","non_qualified":"1F3CA-1F3FC-200D-2642","image":"1f3ca-1f3fc-200d-2642-fe0f.png","sheet_x":10,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3CA-1F3FD-200D-2642-FE0F","non_qualified":"1F3CA-1F3FD-200D-2642","image":"1f3ca-1f3fd-200d-2642-fe0f.png","sheet_x":10,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3CA-1F3FE-200D-2642-FE0F","non_qualified":"1F3CA-1F3FE-200D-2642","image":"1f3ca-1f3fe-200d-2642-fe0f.png","sheet_x":10,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3CA-1F3FF-200D-2642-FE0F","non_qualified":"1F3CA-1F3FF-200D-2642","image":"1f3ca-1f3ff-200d-2642-fe0f.png","sheet_x":10,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F3CA"},{"name":"SWIMMER","unified":"1F3CA","non_qualified":null,"docomo":null,"au":"EADE","softbank":"E42D","google":"FE7DE","image":"1f3ca.png","sheet_x":10,"sheet_y":30,"short_name":"swimmer","short_names":["swimmer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":291,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F3CA-1F3FB","non_qualified":null,"image":"1f3ca-1f3fb.png","sheet_x":10,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F3CA-1F3FC","non_qualified":null,"image":"1f3ca-1f3fc.png","sheet_x":10,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F3CA-1F3FD","non_qualified":null,"image":"1f3ca-1f3fd.png","sheet_x":10,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F3CA-1F3FE","non_qualified":null,"image":"1f3ca-1f3fe.png","sheet_x":10,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F3CA-1F3FF","non_qualified":null,"image":"1f3ca-1f3ff.png","sheet_x":10,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F3CA-200D-2642-FE0F"},{"name":null,"unified":"1F3CB-FE0F-200D-2640-FE0F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3cb-fe0f-200d-2640-fe0f.png","sheet_x":10,"sheet_y":36,"short_name":"woman-lifting-weights","short_names":["woman-lifting-weights"],"text":null,"texts":null,"category":"Smileys & People","sort_order":299,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3CB-1F3FB-200D-2640-FE0F","non_qualified":"1F3CB-1F3FB-200D-2640","image":"1f3cb-1f3fb-200d-2640-fe0f.png","sheet_x":10,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3CB-1F3FC-200D-2640-FE0F","non_qualified":"1F3CB-1F3FC-200D-2640","image":"1f3cb-1f3fc-200d-2640-fe0f.png","sheet_x":10,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3CB-1F3FD-200D-2640-FE0F","non_qualified":"1F3CB-1F3FD-200D-2640","image":"1f3cb-1f3fd-200d-2640-fe0f.png","sheet_x":10,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3CB-1F3FE-200D-2640-FE0F","non_qualified":"1F3CB-1F3FE-200D-2640","image":"1f3cb-1f3fe-200d-2640-fe0f.png","sheet_x":10,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3CB-1F3FF-200D-2640-FE0F","non_qualified":"1F3CB-1F3FF-200D-2640","image":"1f3cb-1f3ff-200d-2640-fe0f.png","sheet_x":10,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F3CB-FE0F-200D-2642-FE0F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3cb-fe0f-200d-2642-fe0f.png","sheet_x":10,"sheet_y":42,"short_name":"man-lifting-weights","short_names":["man-lifting-weights"],"text":null,"texts":null,"category":"Smileys & People","sort_order":298,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3CB-1F3FB-200D-2642-FE0F","non_qualified":"1F3CB-1F3FB-200D-2642","image":"1f3cb-1f3fb-200d-2642-fe0f.png","sheet_x":10,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3CB-1F3FC-200D-2642-FE0F","non_qualified":"1F3CB-1F3FC-200D-2642","image":"1f3cb-1f3fc-200d-2642-fe0f.png","sheet_x":10,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3CB-1F3FD-200D-2642-FE0F","non_qualified":"1F3CB-1F3FD-200D-2642","image":"1f3cb-1f3fd-200d-2642-fe0f.png","sheet_x":10,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3CB-1F3FE-200D-2642-FE0F","non_qualified":"1F3CB-1F3FE-200D-2642","image":"1f3cb-1f3fe-200d-2642-fe0f.png","sheet_x":10,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3CB-1F3FF-200D-2642-FE0F","non_qualified":"1F3CB-1F3FF-200D-2642","image":"1f3cb-1f3ff-200d-2642-fe0f.png","sheet_x":10,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F3CB-FE0F"},{"name":null,"unified":"1F3CB-FE0F","non_qualified":"1F3CB","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3cb-fe0f.png","sheet_x":10,"sheet_y":48,"short_name":"weight_lifter","short_names":["weight_lifter"],"text":null,"texts":null,"category":"Smileys & People","sort_order":297,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3CB-1F3FB","non_qualified":null,"image":"1f3cb-1f3fb.png","sheet_x":10,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3CB-1F3FC","non_qualified":null,"image":"1f3cb-1f3fc.png","sheet_x":10,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3CB-1F3FD","non_qualified":null,"image":"1f3cb-1f3fd.png","sheet_x":10,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3CB-1F3FE","non_qualified":null,"image":"1f3cb-1f3fe.png","sheet_x":10,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3CB-1F3FF","non_qualified":null,"image":"1f3cb-1f3ff.png","sheet_x":11,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoleted_by":"1F3CB-FE0F-200D-2642-FE0F"},{"name":null,"unified":"1F3CC-FE0F-200D-2640-FE0F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3cc-fe0f-200d-2640-fe0f.png","sheet_x":11,"sheet_y":1,"short_name":"woman-golfing","short_names":["woman-golfing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":284,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3CC-1F3FB-200D-2640-FE0F","non_qualified":"1F3CC-1F3FB-200D-2640","image":"1f3cc-1f3fb-200d-2640-fe0f.png","sheet_x":11,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3CC-1F3FC-200D-2640-FE0F","non_qualified":"1F3CC-1F3FC-200D-2640","image":"1f3cc-1f3fc-200d-2640-fe0f.png","sheet_x":11,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3CC-1F3FD-200D-2640-FE0F","non_qualified":"1F3CC-1F3FD-200D-2640","image":"1f3cc-1f3fd-200d-2640-fe0f.png","sheet_x":11,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3CC-1F3FE-200D-2640-FE0F","non_qualified":"1F3CC-1F3FE-200D-2640","image":"1f3cc-1f3fe-200d-2640-fe0f.png","sheet_x":11,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3CC-1F3FF-200D-2640-FE0F","non_qualified":"1F3CC-1F3FF-200D-2640","image":"1f3cc-1f3ff-200d-2640-fe0f.png","sheet_x":11,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F3CC-FE0F-200D-2642-FE0F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3cc-fe0f-200d-2642-fe0f.png","sheet_x":11,"sheet_y":7,"short_name":"man-golfing","short_names":["man-golfing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":283,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3CC-1F3FB-200D-2642-FE0F","non_qualified":"1F3CC-1F3FB-200D-2642","image":"1f3cc-1f3fb-200d-2642-fe0f.png","sheet_x":11,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3CC-1F3FC-200D-2642-FE0F","non_qualified":"1F3CC-1F3FC-200D-2642","image":"1f3cc-1f3fc-200d-2642-fe0f.png","sheet_x":11,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3CC-1F3FD-200D-2642-FE0F","non_qualified":"1F3CC-1F3FD-200D-2642","image":"1f3cc-1f3fd-200d-2642-fe0f.png","sheet_x":11,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3CC-1F3FE-200D-2642-FE0F","non_qualified":"1F3CC-1F3FE-200D-2642","image":"1f3cc-1f3fe-200d-2642-fe0f.png","sheet_x":11,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3CC-1F3FF-200D-2642-FE0F","non_qualified":"1F3CC-1F3FF-200D-2642","image":"1f3cc-1f3ff-200d-2642-fe0f.png","sheet_x":11,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F3CC-FE0F"},{"name":null,"unified":"1F3CC-FE0F","non_qualified":"1F3CC","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3cc-fe0f.png","sheet_x":11,"sheet_y":13,"short_name":"golfer","short_names":["golfer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":282,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F3CC-1F3FB","non_qualified":null,"image":"1f3cc-1f3fb.png","sheet_x":11,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F3CC-1F3FC","non_qualified":null,"image":"1f3cc-1f3fc.png","sheet_x":11,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F3CC-1F3FD","non_qualified":null,"image":"1f3cc-1f3fd.png","sheet_x":11,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F3CC-1F3FE","non_qualified":null,"image":"1f3cc-1f3fe.png","sheet_x":11,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F3CC-1F3FF","non_qualified":null,"image":"1f3cc-1f3ff.png","sheet_x":11,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoleted_by":"1F3CC-FE0F-200D-2642-FE0F"},{"name":null,"unified":"1F3CD-FE0F","non_qualified":"1F3CD","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3cd-fe0f.png","sheet_x":11,"sheet_y":19,"short_name":"racing_motorcycle","short_names":["racing_motorcycle"],"text":null,"texts":null,"category":"Smileys & People","sort_order":307,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3CE-FE0F","non_qualified":"1F3CE","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3ce-fe0f.png","sheet_x":11,"sheet_y":20,"short_name":"racing_car","short_names":["racing_car"],"text":null,"texts":null,"category":"Smileys & People","sort_order":306,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CRICKET BAT AND BALL","unified":"1F3CF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3cf.png","sheet_x":11,"sheet_y":21,"short_name":"cricket_bat_and_ball","short_names":["cricket_bat_and_ball"],"text":null,"texts":null,"category":"Activities","sort_order":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"VOLLEYBALL","unified":"1F3D0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d0.png","sheet_x":11,"sheet_y":22,"short_name":"volleyball","short_names":["volleyball"],"text":null,"texts":null,"category":"Activities","sort_order":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FIELD HOCKEY STICK AND BALL","unified":"1F3D1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d1.png","sheet_x":11,"sheet_y":23,"short_name":"field_hockey_stick_and_ball","short_names":["field_hockey_stick_and_ball"],"text":null,"texts":null,"category":"Activities","sort_order":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"ICE HOCKEY STICK AND PUCK","unified":"1F3D2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d2.png","sheet_x":11,"sheet_y":24,"short_name":"ice_hockey_stick_and_puck","short_names":["ice_hockey_stick_and_puck"],"text":null,"texts":null,"category":"Activities","sort_order":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"TABLE TENNIS PADDLE AND BALL","unified":"1F3D3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d3.png","sheet_x":11,"sheet_y":25,"short_name":"table_tennis_paddle_and_ball","short_names":["table_tennis_paddle_and_ball"],"text":null,"texts":null,"category":"Activities","sort_order":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3D4-FE0F","non_qualified":"1F3D4","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d4-fe0f.png","sheet_x":11,"sheet_y":26,"short_name":"snow_capped_mountain","short_names":["snow_capped_mountain"],"text":null,"texts":null,"category":"Travel & Places","sort_order":8,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3D5-FE0F","non_qualified":"1F3D5","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d5-fe0f.png","sheet_x":11,"sheet_y":27,"short_name":"camping","short_names":["camping"],"text":null,"texts":null,"category":"Travel & Places","sort_order":12,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3D6-FE0F","non_qualified":"1F3D6","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d6-fe0f.png","sheet_x":11,"sheet_y":28,"short_name":"beach_with_umbrella","short_names":["beach_with_umbrella"],"text":null,"texts":null,"category":"Travel & Places","sort_order":13,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3D7-FE0F","non_qualified":"1F3D7","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d7-fe0f.png","sheet_x":11,"sheet_y":29,"short_name":"building_construction","short_names":["building_construction"],"text":null,"texts":null,"category":"Travel & Places","sort_order":19,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3D8-FE0F","non_qualified":"1F3D8","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d8-fe0f.png","sheet_x":11,"sheet_y":30,"short_name":"house_buildings","short_names":["house_buildings"],"text":null,"texts":null,"category":"Travel & Places","sort_order":21,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3D9-FE0F","non_qualified":"1F3D9","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3d9-fe0f.png","sheet_x":11,"sheet_y":31,"short_name":"cityscape","short_names":["cityscape"],"text":null,"texts":null,"category":"Travel & Places","sort_order":50,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3DA-FE0F","non_qualified":"1F3DA","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3da-fe0f.png","sheet_x":11,"sheet_y":32,"short_name":"derelict_house_building","short_names":["derelict_house_building"],"text":null,"texts":null,"category":"Travel & Places","sort_order":22,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3DB-FE0F","non_qualified":"1F3DB","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3db-fe0f.png","sheet_x":11,"sheet_y":33,"short_name":"classical_building","short_names":["classical_building"],"text":null,"texts":null,"category":"Travel & Places","sort_order":18,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3DC-FE0F","non_qualified":"1F3DC","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3dc-fe0f.png","sheet_x":11,"sheet_y":34,"short_name":"desert","short_names":["desert"],"text":null,"texts":null,"category":"Travel & Places","sort_order":14,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3DD-FE0F","non_qualified":"1F3DD","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3dd-fe0f.png","sheet_x":11,"sheet_y":35,"short_name":"desert_island","short_names":["desert_island"],"text":null,"texts":null,"category":"Travel & Places","sort_order":15,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3DE-FE0F","non_qualified":"1F3DE","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3de-fe0f.png","sheet_x":11,"sheet_y":36,"short_name":"national_park","short_names":["national_park"],"text":null,"texts":null,"category":"Travel & Places","sort_order":16,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3DF-FE0F","non_qualified":"1F3DF","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3df-fe0f.png","sheet_x":11,"sheet_y":37,"short_name":"stadium","short_names":["stadium"],"text":null,"texts":null,"category":"Travel & Places","sort_order":17,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"HOUSE BUILDING","unified":"1F3E0","non_qualified":null,"docomo":"E663","au":"E4AB","softbank":"E036","google":"FE4B0","image":"1f3e0.png","sheet_x":11,"sheet_y":38,"short_name":"house","short_names":["house"],"text":null,"texts":null,"category":"Travel & Places","sort_order":23,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HOUSE WITH GARDEN","unified":"1F3E1","non_qualified":null,"docomo":"E663","au":"EB09","softbank":null,"google":"FE4B1","image":"1f3e1.png","sheet_x":11,"sheet_y":39,"short_name":"house_with_garden","short_names":["house_with_garden"],"text":null,"texts":null,"category":"Travel & Places","sort_order":24,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OFFICE BUILDING","unified":"1F3E2","non_qualified":null,"docomo":"E664","au":"E4AD","softbank":"E038","google":"FE4B2","image":"1f3e2.png","sheet_x":11,"sheet_y":40,"short_name":"office","short_names":["office"],"text":null,"texts":null,"category":"Travel & Places","sort_order":25,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"JAPANESE POST OFFICE","unified":"1F3E3","non_qualified":null,"docomo":"E665","au":"E5DE","softbank":"E153","google":"FE4B3","image":"1f3e3.png","sheet_x":11,"sheet_y":41,"short_name":"post_office","short_names":["post_office"],"text":null,"texts":null,"category":"Travel & Places","sort_order":26,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EUROPEAN POST OFFICE","unified":"1F3E4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3e4.png","sheet_x":11,"sheet_y":42,"short_name":"european_post_office","short_names":["european_post_office"],"text":null,"texts":null,"category":"Travel & Places","sort_order":27,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HOSPITAL","unified":"1F3E5","non_qualified":null,"docomo":"E666","au":"E5DF","softbank":"E155","google":"FE4B4","image":"1f3e5.png","sheet_x":11,"sheet_y":43,"short_name":"hospital","short_names":["hospital"],"text":null,"texts":null,"category":"Travel & Places","sort_order":28,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BANK","unified":"1F3E6","non_qualified":null,"docomo":"E667","au":"E4AA","softbank":"E14D","google":"FE4B5","image":"1f3e6.png","sheet_x":11,"sheet_y":44,"short_name":"bank","short_names":["bank"],"text":null,"texts":null,"category":"Travel & Places","sort_order":29,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"AUTOMATED TELLER MACHINE","unified":"1F3E7","non_qualified":null,"docomo":"E668","au":"E4A3","softbank":"E154","google":"FE4B6","image":"1f3e7.png","sheet_x":11,"sheet_y":45,"short_name":"atm","short_names":["atm"],"text":null,"texts":null,"category":"Symbols","sort_order":1,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HOTEL","unified":"1F3E8","non_qualified":null,"docomo":"E669","au":"EA81","softbank":"E158","google":"FE4B7","image":"1f3e8.png","sheet_x":11,"sheet_y":46,"short_name":"hotel","short_names":["hotel"],"text":null,"texts":null,"category":"Travel & Places","sort_order":30,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LOVE HOTEL","unified":"1F3E9","non_qualified":null,"docomo":"E669-E6EF","au":"EAF3","softbank":"E501","google":"FE4B8","image":"1f3e9.png","sheet_x":11,"sheet_y":47,"short_name":"love_hotel","short_names":["love_hotel"],"text":null,"texts":null,"category":"Travel & Places","sort_order":31,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CONVENIENCE STORE","unified":"1F3EA","non_qualified":null,"docomo":"E66A","au":"E4A4","softbank":"E156","google":"FE4B9","image":"1f3ea.png","sheet_x":11,"sheet_y":48,"short_name":"convenience_store","short_names":["convenience_store"],"text":null,"texts":null,"category":"Travel & Places","sort_order":32,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SCHOOL","unified":"1F3EB","non_qualified":null,"docomo":"E73E","au":"EA80","softbank":"E157","google":"FE4BA","image":"1f3eb.png","sheet_x":11,"sheet_y":49,"short_name":"school","short_names":["school"],"text":null,"texts":null,"category":"Travel & Places","sort_order":33,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DEPARTMENT STORE","unified":"1F3EC","non_qualified":null,"docomo":null,"au":"EAF6","softbank":"E504","google":"FE4BD","image":"1f3ec.png","sheet_x":11,"sheet_y":50,"short_name":"department_store","short_names":["department_store"],"text":null,"texts":null,"category":"Travel & Places","sort_order":34,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACTORY","unified":"1F3ED","non_qualified":null,"docomo":null,"au":"EAF9","softbank":"E508","google":"FE4C0","image":"1f3ed.png","sheet_x":11,"sheet_y":51,"short_name":"factory","short_names":["factory"],"text":null,"texts":null,"category":"Travel & Places","sort_order":35,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"IZAKAYA LANTERN","unified":"1F3EE","non_qualified":null,"docomo":"E74B","au":"E4BD","softbank":null,"google":"FE4C2","image":"1f3ee.png","sheet_x":11,"sheet_y":52,"short_name":"izakaya_lantern","short_names":["izakaya_lantern","lantern"],"text":null,"texts":null,"category":"Objects","sort_order":58,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"JAPANESE CASTLE","unified":"1F3EF","non_qualified":null,"docomo":null,"au":"EAF7","softbank":"E505","google":"FE4BE","image":"1f3ef.png","sheet_x":12,"sheet_y":0,"short_name":"japanese_castle","short_names":["japanese_castle"],"text":null,"texts":null,"category":"Travel & Places","sort_order":36,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EUROPEAN CASTLE","unified":"1F3F0","non_qualified":null,"docomo":null,"au":"EAF8","softbank":"E506","google":"FE4BF","image":"1f3f0.png","sheet_x":12,"sheet_y":1,"short_name":"european_castle","short_names":["european_castle"],"text":null,"texts":null,"category":"Travel & Places","sort_order":37,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F3F3-FE0F-200D-1F308","non_qualified":"1F3F3-200D-1F308","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f3-fe0f-200d-1f308.png","sheet_x":12,"sheet_y":2,"short_name":"rainbow-flag","short_names":["rainbow-flag"],"text":null,"texts":null,"category":"Flags","sort_order":6,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F3F3-FE0F","non_qualified":"1F3F3","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f3-fe0f.png","sheet_x":12,"sheet_y":3,"short_name":"waving_white_flag","short_names":["waving_white_flag"],"text":null,"texts":null,"category":"Flags","sort_order":5,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3F4-200D-2620-FE0F","non_qualified":"1F3F4-200D-2620","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f4-200d-2620-fe0f.png","sheet_x":12,"sheet_y":4,"short_name":"pirate_flag","short_names":["pirate_flag"],"text":null,"texts":null,"category":"Flags","sort_order":7,"added_in":"7.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"England Flag","unified":"1F3F4-E0067-E0062-E0065-E006E-E0067-E007F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f.png","sheet_x":12,"sheet_y":5,"short_name":"flag-england","short_names":["flag-england"],"text":null,"texts":null,"category":"Flags","sort_order":266,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"Scotland Flag","unified":"1F3F4-E0067-E0062-E0073-E0063-E0074-E007F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f.png","sheet_x":12,"sheet_y":6,"short_name":"flag-scotland","short_names":["flag-scotland"],"text":null,"texts":null,"category":"Flags","sort_order":267,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"Wales Flag","unified":"1F3F4-E0067-E0062-E0077-E006C-E0073-E007F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f.png","sheet_x":12,"sheet_y":7,"short_name":"flag-wales","short_names":["flag-wales"],"text":null,"texts":null,"category":"Flags","sort_order":268,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"WAVING BLACK FLAG","unified":"1F3F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f4.png","sheet_x":12,"sheet_y":8,"short_name":"waving_black_flag","short_names":["waving_black_flag"],"text":null,"texts":null,"category":"Flags","sort_order":4,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3F5-FE0F","non_qualified":"1F3F5","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f5-fe0f.png","sheet_x":12,"sheet_y":9,"short_name":"rosette","short_names":["rosette"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":106,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F3F7-FE0F","non_qualified":"1F3F7","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f7-fe0f.png","sheet_x":12,"sheet_y":10,"short_name":"label","short_names":["label"],"text":null,"texts":null,"category":"Objects","sort_order":75,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BADMINTON RACQUET AND SHUTTLECOCK","unified":"1F3F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f8.png","sheet_x":12,"sheet_y":11,"short_name":"badminton_racquet_and_shuttlecock","short_names":["badminton_racquet_and_shuttlecock"],"text":null,"texts":null,"category":"Activities","sort_order":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BOW AND ARROW","unified":"1F3F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3f9.png","sheet_x":12,"sheet_y":12,"short_name":"bow_and_arrow","short_names":["bow_and_arrow"],"text":null,"texts":null,"category":"Objects","sort_order":143,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"AMPHORA","unified":"1F3FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3fa.png","sheet_x":12,"sheet_y":13,"short_name":"amphora","short_names":["amphora"],"text":null,"texts":null,"category":"Food & Drink","sort_order":108,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"EMOJI MODIFIER FITZPATRICK TYPE-1-2","unified":"1F3FB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3fb.png","sheet_x":12,"sheet_y":14,"short_name":"skin-tone-2","short_names":["skin-tone-2"],"text":null,"texts":null,"category":"Skin Tones","sort_order":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"EMOJI MODIFIER FITZPATRICK TYPE-3","unified":"1F3FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3fc.png","sheet_x":12,"sheet_y":15,"short_name":"skin-tone-3","short_names":["skin-tone-3"],"text":null,"texts":null,"category":"Skin Tones","sort_order":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"EMOJI MODIFIER FITZPATRICK TYPE-4","unified":"1F3FD","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3fd.png","sheet_x":12,"sheet_y":16,"short_name":"skin-tone-4","short_names":["skin-tone-4"],"text":null,"texts":null,"category":"Skin Tones","sort_order":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"EMOJI MODIFIER FITZPATRICK TYPE-5","unified":"1F3FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3fe.png","sheet_x":12,"sheet_y":17,"short_name":"skin-tone-5","short_names":["skin-tone-5"],"text":null,"texts":null,"category":"Skin Tones","sort_order":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"EMOJI MODIFIER FITZPATRICK TYPE-6","unified":"1F3FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f3ff.png","sheet_x":12,"sheet_y":18,"short_name":"skin-tone-6","short_names":["skin-tone-6"],"text":null,"texts":null,"category":"Skin Tones","sort_order":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"RAT","unified":"1F400","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f400.png","sheet_x":12,"sheet_y":19,"short_name":"rat","short_names":["rat"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":41,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOUSE","unified":"1F401","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f401.png","sheet_x":12,"sheet_y":20,"short_name":"mouse2","short_names":["mouse2"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":40,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OX","unified":"1F402","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f402.png","sheet_x":12,"sheet_y":21,"short_name":"ox","short_names":["ox"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":22,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WATER BUFFALO","unified":"1F403","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f403.png","sheet_x":12,"sheet_y":22,"short_name":"water_buffalo","short_names":["water_buffalo"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":23,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"COW","unified":"1F404","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f404.png","sheet_x":12,"sheet_y":23,"short_name":"cow2","short_names":["cow2"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":24,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TIGER","unified":"1F405","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f405.png","sheet_x":12,"sheet_y":24,"short_name":"tiger2","short_names":["tiger2"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":14,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEOPARD","unified":"1F406","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f406.png","sheet_x":12,"sheet_y":25,"short_name":"leopard","short_names":["leopard"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":15,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RABBIT","unified":"1F407","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f407.png","sheet_x":12,"sheet_y":26,"short_name":"rabbit2","short_names":["rabbit2"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":44,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CAT","unified":"1F408","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f408.png","sheet_x":12,"sheet_y":27,"short_name":"cat2","short_names":["cat2"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":11,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DRAGON","unified":"1F409","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f409.png","sheet_x":12,"sheet_y":28,"short_name":"dragon","short_names":["dragon"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":75,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CROCODILE","unified":"1F40A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f40a.png","sheet_x":12,"sheet_y":29,"short_name":"crocodile","short_names":["crocodile"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":70,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHALE","unified":"1F40B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f40b.png","sheet_x":12,"sheet_y":30,"short_name":"whale2","short_names":["whale2"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":79,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SNAIL","unified":"1F40C","non_qualified":null,"docomo":"E74E","au":"EB7E","softbank":null,"google":"FE1B9","image":"1f40c.png","sheet_x":12,"sheet_y":31,"short_name":"snail","short_names":["snail"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":91,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SNAKE","unified":"1F40D","non_qualified":null,"docomo":null,"au":"EB22","softbank":"E52D","google":"FE1D3","image":"1f40d.png","sheet_x":12,"sheet_y":32,"short_name":"snake","short_names":["snake"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":73,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HORSE","unified":"1F40E","non_qualified":null,"docomo":"E754","au":"E4D8","softbank":"E134","google":"FE7DC","image":"1f40e.png","sheet_x":12,"sheet_y":33,"short_name":"racehorse","short_names":["racehorse"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":17,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RAM","unified":"1F40F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f40f.png","sheet_x":12,"sheet_y":34,"short_name":"ram","short_names":["ram"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":29,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GOAT","unified":"1F410","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f410.png","sheet_x":12,"sheet_y":35,"short_name":"goat","short_names":["goat"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":31,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SHEEP","unified":"1F411","non_qualified":null,"docomo":null,"au":"E48F","softbank":"E529","google":"FE1CF","image":"1f411.png","sheet_x":12,"sheet_y":36,"short_name":"sheep","short_names":["sheep"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":30,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MONKEY","unified":"1F412","non_qualified":null,"docomo":null,"au":"E4D9","softbank":"E528","google":"FE1CE","image":"1f412.png","sheet_x":12,"sheet_y":37,"short_name":"monkey","short_names":["monkey"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":2,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ROOSTER","unified":"1F413","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f413.png","sheet_x":12,"sheet_y":38,"short_name":"rooster","short_names":["rooster"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":56,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHICKEN","unified":"1F414","non_qualified":null,"docomo":null,"au":"EB23","softbank":"E52E","google":"FE1D4","image":"1f414.png","sheet_x":12,"sheet_y":39,"short_name":"chicken","short_names":["chicken"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":55,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DOG","unified":"1F415","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f415.png","sheet_x":12,"sheet_y":40,"short_name":"dog2","short_names":["dog2"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":5,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PIG","unified":"1F416","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f416.png","sheet_x":12,"sheet_y":41,"short_name":"pig2","short_names":["pig2"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":26,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BOAR","unified":"1F417","non_qualified":null,"docomo":null,"au":"EB24","softbank":"E52F","google":"FE1D5","image":"1f417.png","sheet_x":12,"sheet_y":42,"short_name":"boar","short_names":["boar"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":27,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ELEPHANT","unified":"1F418","non_qualified":null,"docomo":null,"au":"EB1F","softbank":"E526","google":"FE1CC","image":"1f418.png","sheet_x":12,"sheet_y":43,"short_name":"elephant","short_names":["elephant"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":36,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OCTOPUS","unified":"1F419","non_qualified":null,"docomo":null,"au":"E5C7","softbank":"E10A","google":"FE1C5","image":"1f419.png","sheet_x":12,"sheet_y":44,"short_name":"octopus","short_names":["octopus"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":85,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPIRAL SHELL","unified":"1F41A","non_qualified":null,"docomo":null,"au":"EAEC","softbank":"E441","google":"FE1C6","image":"1f41a.png","sheet_x":12,"sheet_y":45,"short_name":"shell","short_names":["shell"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":86,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BUG","unified":"1F41B","non_qualified":null,"docomo":null,"au":"EB1E","softbank":"E525","google":"FE1CB","image":"1f41b.png","sheet_x":12,"sheet_y":46,"short_name":"bug","short_names":["bug"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":93,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ANT","unified":"1F41C","non_qualified":null,"docomo":null,"au":"E4DD","softbank":null,"google":"FE1DA","image":"1f41c.png","sheet_x":12,"sheet_y":47,"short_name":"ant","short_names":["ant"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":94,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HONEYBEE","unified":"1F41D","non_qualified":null,"docomo":null,"au":"EB57","softbank":null,"google":"FE1E1","image":"1f41d.png","sheet_x":12,"sheet_y":48,"short_name":"bee","short_names":["bee","honeybee"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":95,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LADY BEETLE","unified":"1F41E","non_qualified":null,"docomo":null,"au":"EB58","softbank":null,"google":"FE1E2","image":"1f41e.png","sheet_x":12,"sheet_y":49,"short_name":"beetle","short_names":["beetle"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":96,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FISH","unified":"1F41F","non_qualified":null,"docomo":"E751","au":"E49A","softbank":"E019","google":"FE1BD","image":"1f41f.png","sheet_x":12,"sheet_y":50,"short_name":"fish","short_names":["fish"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":81,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TROPICAL FISH","unified":"1F420","non_qualified":null,"docomo":"E751","au":"EB1D","softbank":"E522","google":"FE1C9","image":"1f420.png","sheet_x":12,"sheet_y":51,"short_name":"tropical_fish","short_names":["tropical_fish"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":82,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLOWFISH","unified":"1F421","non_qualified":null,"docomo":"E751","au":"E4D3","softbank":null,"google":"FE1D9","image":"1f421.png","sheet_x":12,"sheet_y":52,"short_name":"blowfish","short_names":["blowfish"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":83,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TURTLE","unified":"1F422","non_qualified":null,"docomo":null,"au":"E5D4","softbank":null,"google":"FE1DC","image":"1f422.png","sheet_x":13,"sheet_y":0,"short_name":"turtle","short_names":["turtle"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":71,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HATCHING CHICK","unified":"1F423","non_qualified":null,"docomo":"E74F","au":"E5DB","softbank":null,"google":"FE1DD","image":"1f423.png","sheet_x":13,"sheet_y":1,"short_name":"hatching_chick","short_names":["hatching_chick"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":57,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BABY CHICK","unified":"1F424","non_qualified":null,"docomo":"E74F","au":"E4E0","softbank":"E523","google":"FE1BA","image":"1f424.png","sheet_x":13,"sheet_y":2,"short_name":"baby_chick","short_names":["baby_chick"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":58,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FRONT-FACING BABY CHICK","unified":"1F425","non_qualified":null,"docomo":"E74F","au":"EB76","softbank":null,"google":"FE1BB","image":"1f425.png","sheet_x":13,"sheet_y":3,"short_name":"hatched_chick","short_names":["hatched_chick"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":59,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BIRD","unified":"1F426","non_qualified":null,"docomo":"E74F","au":"E4E0","softbank":"E521","google":"FE1C8","image":"1f426.png","sheet_x":13,"sheet_y":4,"short_name":"bird","short_names":["bird"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":60,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PENGUIN","unified":"1F427","non_qualified":null,"docomo":"E750","au":"E4DC","softbank":"E055","google":"FE1BC","image":"1f427.png","sheet_x":13,"sheet_y":5,"short_name":"penguin","short_names":["penguin"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":61,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KOALA","unified":"1F428","non_qualified":null,"docomo":null,"au":"EB20","softbank":"E527","google":"FE1CD","image":"1f428.png","sheet_x":13,"sheet_y":6,"short_name":"koala","short_names":["koala"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":49,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POODLE","unified":"1F429","non_qualified":null,"docomo":"E6A1","au":"E4DF","softbank":null,"google":"FE1D8","image":"1f429.png","sheet_x":13,"sheet_y":7,"short_name":"poodle","short_names":["poodle"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":6,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DROMEDARY CAMEL","unified":"1F42A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f42a.png","sheet_x":13,"sheet_y":8,"short_name":"dromedary_camel","short_names":["dromedary_camel"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":32,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BACTRIAN CAMEL","unified":"1F42B","non_qualified":null,"docomo":null,"au":"EB25","softbank":"E530","google":"FE1D6","image":"1f42b.png","sheet_x":13,"sheet_y":9,"short_name":"camel","short_names":["camel"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":33,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DOLPHIN","unified":"1F42C","non_qualified":null,"docomo":null,"au":"EB1B","softbank":"E520","google":"FE1C7","image":"1f42c.png","sheet_x":13,"sheet_y":10,"short_name":"dolphin","short_names":["dolphin","flipper"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":80,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOUSE FACE","unified":"1F42D","non_qualified":null,"docomo":null,"au":"E5C2","softbank":"E053","google":"FE1C2","image":"1f42d.png","sheet_x":13,"sheet_y":11,"short_name":"mouse","short_names":["mouse"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":39,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"COW FACE","unified":"1F42E","non_qualified":null,"docomo":null,"au":"EB21","softbank":"E52B","google":"FE1D1","image":"1f42e.png","sheet_x":13,"sheet_y":12,"short_name":"cow","short_names":["cow"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":21,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TIGER FACE","unified":"1F42F","non_qualified":null,"docomo":null,"au":"E5C0","softbank":"E050","google":"FE1C0","image":"1f42f.png","sheet_x":13,"sheet_y":13,"short_name":"tiger","short_names":["tiger"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":13,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RABBIT FACE","unified":"1F430","non_qualified":null,"docomo":null,"au":"E4D7","softbank":"E52C","google":"FE1D2","image":"1f430.png","sheet_x":13,"sheet_y":14,"short_name":"rabbit","short_names":["rabbit"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":43,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CAT FACE","unified":"1F431","non_qualified":null,"docomo":"E6A2","au":"E4DB","softbank":"E04F","google":"FE1B8","image":"1f431.png","sheet_x":13,"sheet_y":15,"short_name":"cat","short_names":["cat"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":10,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DRAGON FACE","unified":"1F432","non_qualified":null,"docomo":null,"au":"EB3F","softbank":null,"google":"FE1DE","image":"1f432.png","sheet_x":13,"sheet_y":16,"short_name":"dragon_face","short_names":["dragon_face"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":74,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPOUTING WHALE","unified":"1F433","non_qualified":null,"docomo":null,"au":"E470","softbank":"E054","google":"FE1C3","image":"1f433.png","sheet_x":13,"sheet_y":17,"short_name":"whale","short_names":["whale"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":78,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HORSE FACE","unified":"1F434","non_qualified":null,"docomo":"E754","au":"E4D8","softbank":"E01A","google":"FE1BE","image":"1f434.png","sheet_x":13,"sheet_y":18,"short_name":"horse","short_names":["horse"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":16,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MONKEY FACE","unified":"1F435","non_qualified":null,"docomo":null,"au":"E4D9","softbank":"E109","google":"FE1C4","image":"1f435.png","sheet_x":13,"sheet_y":19,"short_name":"monkey_face","short_names":["monkey_face"],"text":null,"texts":[":o)"],"category":"Animals & Nature","sort_order":1,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DOG FACE","unified":"1F436","non_qualified":null,"docomo":"E6A1","au":"E4E1","softbank":"E052","google":"FE1B7","image":"1f436.png","sheet_x":13,"sheet_y":20,"short_name":"dog","short_names":["dog"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":4,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PIG FACE","unified":"1F437","non_qualified":null,"docomo":"E755","au":"E4DE","softbank":"E10B","google":"FE1BF","image":"1f437.png","sheet_x":13,"sheet_y":21,"short_name":"pig","short_names":["pig"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":25,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FROG FACE","unified":"1F438","non_qualified":null,"docomo":null,"au":"E4DA","softbank":"E531","google":"FE1D7","image":"1f438.png","sheet_x":13,"sheet_y":22,"short_name":"frog","short_names":["frog"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":69,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HAMSTER FACE","unified":"1F439","non_qualified":null,"docomo":null,"au":null,"softbank":"E524","google":"FE1CA","image":"1f439.png","sheet_x":13,"sheet_y":23,"short_name":"hamster","short_names":["hamster"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":42,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WOLF FACE","unified":"1F43A","non_qualified":null,"docomo":"E6A1","au":"E4E1","softbank":"E52A","google":"FE1D0","image":"1f43a.png","sheet_x":13,"sheet_y":24,"short_name":"wolf","short_names":["wolf"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":7,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BEAR FACE","unified":"1F43B","non_qualified":null,"docomo":null,"au":"E5C1","softbank":"E051","google":"FE1C1","image":"1f43b.png","sheet_x":13,"sheet_y":25,"short_name":"bear","short_names":["bear"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":48,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PANDA FACE","unified":"1F43C","non_qualified":null,"docomo":null,"au":"EB46","softbank":null,"google":"FE1DF","image":"1f43c.png","sheet_x":13,"sheet_y":26,"short_name":"panda_face","short_names":["panda_face"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":50,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PIG NOSE","unified":"1F43D","non_qualified":null,"docomo":"E755","au":"EB48","softbank":null,"google":"FE1E0","image":"1f43d.png","sheet_x":13,"sheet_y":27,"short_name":"pig_nose","short_names":["pig_nose"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":28,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PAW PRINTS","unified":"1F43E","non_qualified":null,"docomo":"E698","au":"E4EE","softbank":null,"google":"FE1DB","image":"1f43e.png","sheet_x":13,"sheet_y":28,"short_name":"feet","short_names":["feet","paw_prints"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":53,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F43F-FE0F","non_qualified":"1F43F","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f43f-fe0f.png","sheet_x":13,"sheet_y":29,"short_name":"chipmunk","short_names":["chipmunk"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":45,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"EYES","unified":"1F440","non_qualified":null,"docomo":"E691","au":"E5A4","softbank":"E419","google":"FE190","image":"1f440.png","sheet_x":13,"sheet_y":30,"short_name":"eyes","short_names":["eyes"],"text":null,"texts":null,"category":"Smileys & People","sort_order":398,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F441-FE0F-200D-1F5E8-FE0F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f441-fe0f-200d-1f5e8-fe0f.png","sheet_x":13,"sheet_y":31,"short_name":"eye-in-speech-bubble","short_names":["eye-in-speech-bubble"],"text":null,"texts":null,"category":"Smileys & People","sort_order":400,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":null,"unified":"1F441-FE0F","non_qualified":"1F441","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f441-fe0f.png","sheet_x":13,"sheet_y":32,"short_name":"eye","short_names":["eye"],"text":null,"texts":null,"category":"Smileys & People","sort_order":399,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"EAR","unified":"1F442","non_qualified":null,"docomo":"E692","au":"E5A5","softbank":"E41B","google":"FE191","image":"1f442.png","sheet_x":13,"sheet_y":33,"short_name":"ear","short_names":["ear"],"text":null,"texts":null,"category":"Smileys & People","sort_order":395,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F442-1F3FB","non_qualified":null,"image":"1f442-1f3fb.png","sheet_x":13,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F442-1F3FC","non_qualified":null,"image":"1f442-1f3fc.png","sheet_x":13,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F442-1F3FD","non_qualified":null,"image":"1f442-1f3fd.png","sheet_x":13,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F442-1F3FE","non_qualified":null,"image":"1f442-1f3fe.png","sheet_x":13,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F442-1F3FF","non_qualified":null,"image":"1f442-1f3ff.png","sheet_x":13,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"NOSE","unified":"1F443","non_qualified":null,"docomo":null,"au":"EAD0","softbank":"E41A","google":"FE192","image":"1f443.png","sheet_x":13,"sheet_y":39,"short_name":"nose","short_names":["nose"],"text":null,"texts":null,"category":"Smileys & People","sort_order":396,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F443-1F3FB","non_qualified":null,"image":"1f443-1f3fb.png","sheet_x":13,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F443-1F3FC","non_qualified":null,"image":"1f443-1f3fc.png","sheet_x":13,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F443-1F3FD","non_qualified":null,"image":"1f443-1f3fd.png","sheet_x":13,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F443-1F3FE","non_qualified":null,"image":"1f443-1f3fe.png","sheet_x":13,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F443-1F3FF","non_qualified":null,"image":"1f443-1f3ff.png","sheet_x":13,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"MOUTH","unified":"1F444","non_qualified":null,"docomo":"E6F9","au":"EAD1","softbank":"E41C","google":"FE193","image":"1f444.png","sheet_x":13,"sheet_y":45,"short_name":"lips","short_names":["lips"],"text":null,"texts":null,"category":"Smileys & People","sort_order":405,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TONGUE","unified":"1F445","non_qualified":null,"docomo":"E728","au":"EB47","softbank":null,"google":"FE194","image":"1f445.png","sheet_x":13,"sheet_y":46,"short_name":"tongue","short_names":["tongue"],"text":null,"texts":null,"category":"Smileys & People","sort_order":404,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE UP POINTING BACKHAND INDEX","unified":"1F446","non_qualified":null,"docomo":null,"au":"EA8D","softbank":"E22E","google":"FEB99","image":"1f446.png","sheet_x":13,"sheet_y":47,"short_name":"point_up_2","short_names":["point_up_2"],"text":null,"texts":null,"category":"Smileys & People","sort_order":367,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F446-1F3FB","non_qualified":null,"image":"1f446-1f3fb.png","sheet_x":13,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F446-1F3FC","non_qualified":null,"image":"1f446-1f3fc.png","sheet_x":13,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F446-1F3FD","non_qualified":null,"image":"1f446-1f3fd.png","sheet_x":13,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F446-1F3FE","non_qualified":null,"image":"1f446-1f3fe.png","sheet_x":13,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F446-1F3FF","non_qualified":null,"image":"1f446-1f3ff.png","sheet_x":13,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"WHITE DOWN POINTING BACKHAND INDEX","unified":"1F447","non_qualified":null,"docomo":null,"au":"EA8E","softbank":"E22F","google":"FEB9A","image":"1f447.png","sheet_x":14,"sheet_y":0,"short_name":"point_down","short_names":["point_down"],"text":null,"texts":null,"category":"Smileys & People","sort_order":369,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F447-1F3FB","non_qualified":null,"image":"1f447-1f3fb.png","sheet_x":14,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F447-1F3FC","non_qualified":null,"image":"1f447-1f3fc.png","sheet_x":14,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F447-1F3FD","non_qualified":null,"image":"1f447-1f3fd.png","sheet_x":14,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F447-1F3FE","non_qualified":null,"image":"1f447-1f3fe.png","sheet_x":14,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F447-1F3FF","non_qualified":null,"image":"1f447-1f3ff.png","sheet_x":14,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"WHITE LEFT POINTING BACKHAND INDEX","unified":"1F448","non_qualified":null,"docomo":null,"au":"E4FF","softbank":"E230","google":"FEB9B","image":"1f448.png","sheet_x":14,"sheet_y":6,"short_name":"point_left","short_names":["point_left"],"text":null,"texts":null,"category":"Smileys & People","sort_order":364,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F448-1F3FB","non_qualified":null,"image":"1f448-1f3fb.png","sheet_x":14,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F448-1F3FC","non_qualified":null,"image":"1f448-1f3fc.png","sheet_x":14,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F448-1F3FD","non_qualified":null,"image":"1f448-1f3fd.png","sheet_x":14,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F448-1F3FE","non_qualified":null,"image":"1f448-1f3fe.png","sheet_x":14,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F448-1F3FF","non_qualified":null,"image":"1f448-1f3ff.png","sheet_x":14,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"WHITE RIGHT POINTING BACKHAND INDEX","unified":"1F449","non_qualified":null,"docomo":null,"au":"E500","softbank":"E231","google":"FEB9C","image":"1f449.png","sheet_x":14,"sheet_y":12,"short_name":"point_right","short_names":["point_right"],"text":null,"texts":null,"category":"Smileys & People","sort_order":365,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F449-1F3FB","non_qualified":null,"image":"1f449-1f3fb.png","sheet_x":14,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F449-1F3FC","non_qualified":null,"image":"1f449-1f3fc.png","sheet_x":14,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F449-1F3FD","non_qualified":null,"image":"1f449-1f3fd.png","sheet_x":14,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F449-1F3FE","non_qualified":null,"image":"1f449-1f3fe.png","sheet_x":14,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F449-1F3FF","non_qualified":null,"image":"1f449-1f3ff.png","sheet_x":14,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"FISTED HAND SIGN","unified":"1F44A","non_qualified":null,"docomo":"E6FD","au":"E4F3","softbank":"E00D","google":"FEB96","image":"1f44a.png","sheet_x":14,"sheet_y":18,"short_name":"facepunch","short_names":["facepunch","punch"],"text":null,"texts":null,"category":"Smileys & People","sort_order":381,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F44A-1F3FB","non_qualified":null,"image":"1f44a-1f3fb.png","sheet_x":14,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F44A-1F3FC","non_qualified":null,"image":"1f44a-1f3fc.png","sheet_x":14,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F44A-1F3FD","non_qualified":null,"image":"1f44a-1f3fd.png","sheet_x":14,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F44A-1F3FE","non_qualified":null,"image":"1f44a-1f3fe.png","sheet_x":14,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F44A-1F3FF","non_qualified":null,"image":"1f44a-1f3ff.png","sheet_x":14,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"WAVING HAND SIGN","unified":"1F44B","non_qualified":null,"docomo":"E695","au":"EAD6","softbank":"E41E","google":"FEB9D","image":"1f44b.png","sheet_x":14,"sheet_y":24,"short_name":"wave","short_names":["wave"],"text":null,"texts":null,"category":"Smileys & People","sort_order":385,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F44B-1F3FB","non_qualified":null,"image":"1f44b-1f3fb.png","sheet_x":14,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F44B-1F3FC","non_qualified":null,"image":"1f44b-1f3fc.png","sheet_x":14,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F44B-1F3FD","non_qualified":null,"image":"1f44b-1f3fd.png","sheet_x":14,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F44B-1F3FE","non_qualified":null,"image":"1f44b-1f3fe.png","sheet_x":14,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F44B-1F3FF","non_qualified":null,"image":"1f44b-1f3ff.png","sheet_x":14,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"OK HAND SIGN","unified":"1F44C","non_qualified":null,"docomo":"E70B","au":"EAD4","softbank":"E420","google":"FEB9F","image":"1f44c.png","sheet_x":14,"sheet_y":30,"short_name":"ok_hand","short_names":["ok_hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":377,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F44C-1F3FB","non_qualified":null,"image":"1f44c-1f3fb.png","sheet_x":14,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F44C-1F3FC","non_qualified":null,"image":"1f44c-1f3fc.png","sheet_x":14,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F44C-1F3FD","non_qualified":null,"image":"1f44c-1f3fd.png","sheet_x":14,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F44C-1F3FE","non_qualified":null,"image":"1f44c-1f3fe.png","sheet_x":14,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F44C-1F3FF","non_qualified":null,"image":"1f44c-1f3ff.png","sheet_x":14,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"THUMBS UP SIGN","unified":"1F44D","non_qualified":null,"docomo":"E727","au":"E4F9","softbank":"E00E","google":"FEB97","image":"1f44d.png","sheet_x":14,"sheet_y":36,"short_name":"+1","short_names":["+1","thumbsup"],"text":null,"texts":null,"category":"Smileys & People","sort_order":378,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F44D-1F3FB","non_qualified":null,"image":"1f44d-1f3fb.png","sheet_x":14,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F44D-1F3FC","non_qualified":null,"image":"1f44d-1f3fc.png","sheet_x":14,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F44D-1F3FD","non_qualified":null,"image":"1f44d-1f3fd.png","sheet_x":14,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F44D-1F3FE","non_qualified":null,"image":"1f44d-1f3fe.png","sheet_x":14,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F44D-1F3FF","non_qualified":null,"image":"1f44d-1f3ff.png","sheet_x":14,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"THUMBS DOWN SIGN","unified":"1F44E","non_qualified":null,"docomo":"E700","au":"EAD5","softbank":"E421","google":"FEBA0","image":"1f44e.png","sheet_x":14,"sheet_y":42,"short_name":"-1","short_names":["-1","thumbsdown"],"text":null,"texts":null,"category":"Smileys & People","sort_order":379,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F44E-1F3FB","non_qualified":null,"image":"1f44e-1f3fb.png","sheet_x":14,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F44E-1F3FC","non_qualified":null,"image":"1f44e-1f3fc.png","sheet_x":14,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F44E-1F3FD","non_qualified":null,"image":"1f44e-1f3fd.png","sheet_x":14,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F44E-1F3FE","non_qualified":null,"image":"1f44e-1f3fe.png","sheet_x":14,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F44E-1F3FF","non_qualified":null,"image":"1f44e-1f3ff.png","sheet_x":14,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"CLAPPING HANDS SIGN","unified":"1F44F","non_qualified":null,"docomo":null,"au":"EAD3","softbank":"E41F","google":"FEB9E","image":"1f44f.png","sheet_x":14,"sheet_y":48,"short_name":"clap","short_names":["clap"],"text":null,"texts":null,"category":"Smileys & People","sort_order":388,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F44F-1F3FB","non_qualified":null,"image":"1f44f-1f3fb.png","sheet_x":14,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F44F-1F3FC","non_qualified":null,"image":"1f44f-1f3fc.png","sheet_x":14,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F44F-1F3FD","non_qualified":null,"image":"1f44f-1f3fd.png","sheet_x":14,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F44F-1F3FE","non_qualified":null,"image":"1f44f-1f3fe.png","sheet_x":14,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F44F-1F3FF","non_qualified":null,"image":"1f44f-1f3ff.png","sheet_x":15,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"OPEN HANDS SIGN","unified":"1F450","non_qualified":null,"docomo":"E695","au":"EAD6","softbank":"E422","google":"FEBA1","image":"1f450.png","sheet_x":15,"sheet_y":1,"short_name":"open_hands","short_names":["open_hands"],"text":null,"texts":null,"category":"Smileys & People","sort_order":389,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F450-1F3FB","non_qualified":null,"image":"1f450-1f3fb.png","sheet_x":15,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F450-1F3FC","non_qualified":null,"image":"1f450-1f3fc.png","sheet_x":15,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F450-1F3FD","non_qualified":null,"image":"1f450-1f3fd.png","sheet_x":15,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F450-1F3FE","non_qualified":null,"image":"1f450-1f3fe.png","sheet_x":15,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F450-1F3FF","non_qualified":null,"image":"1f450-1f3ff.png","sheet_x":15,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"CROWN","unified":"1F451","non_qualified":null,"docomo":"E71A","au":"E5C9","softbank":"E10E","google":"FE4D1","image":"1f451.png","sheet_x":15,"sheet_y":7,"short_name":"crown","short_names":["crown"],"text":null,"texts":null,"category":"Smileys & People","sort_order":464,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WOMANS HAT","unified":"1F452","non_qualified":null,"docomo":null,"au":"EA9E","softbank":"E318","google":"FE4D4","image":"1f452.png","sheet_x":15,"sheet_y":8,"short_name":"womans_hat","short_names":["womans_hat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":465,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EYEGLASSES","unified":"1F453","non_qualified":null,"docomo":"E69A","au":"E4FE","softbank":null,"google":"FE4CE","image":"1f453.png","sheet_x":15,"sheet_y":9,"short_name":"eyeglasses","short_names":["eyeglasses"],"text":null,"texts":null,"category":"Smileys & People","sort_order":437,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NECKTIE","unified":"1F454","non_qualified":null,"docomo":null,"au":"EA93","softbank":"E302","google":"FE4D3","image":"1f454.png","sheet_x":15,"sheet_y":10,"short_name":"necktie","short_names":["necktie"],"text":null,"texts":null,"category":"Smileys & People","sort_order":441,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"T-SHIRT","unified":"1F455","non_qualified":null,"docomo":"E70E","au":"E5B6","softbank":"E006","google":"FE4CF","image":"1f455.png","sheet_x":15,"sheet_y":11,"short_name":"shirt","short_names":["shirt","tshirt"],"text":null,"texts":null,"category":"Smileys & People","sort_order":442,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"JEANS","unified":"1F456","non_qualified":null,"docomo":"E711","au":"EB77","softbank":null,"google":"FE4D0","image":"1f456.png","sheet_x":15,"sheet_y":12,"short_name":"jeans","short_names":["jeans"],"text":null,"texts":null,"category":"Smileys & People","sort_order":443,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DRESS","unified":"1F457","non_qualified":null,"docomo":null,"au":"EB6B","softbank":"E319","google":"FE4D5","image":"1f457.png","sheet_x":15,"sheet_y":13,"short_name":"dress","short_names":["dress"],"text":null,"texts":null,"category":"Smileys & People","sort_order":448,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KIMONO","unified":"1F458","non_qualified":null,"docomo":null,"au":"EAA3","softbank":"E321","google":"FE4D9","image":"1f458.png","sheet_x":15,"sheet_y":14,"short_name":"kimono","short_names":["kimono"],"text":null,"texts":null,"category":"Smileys & People","sort_order":449,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BIKINI","unified":"1F459","non_qualified":null,"docomo":null,"au":"EAA4","softbank":"E322","google":"FE4DA","image":"1f459.png","sheet_x":15,"sheet_y":15,"short_name":"bikini","short_names":["bikini"],"text":null,"texts":null,"category":"Smileys & People","sort_order":450,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WOMANS CLOTHES","unified":"1F45A","non_qualified":null,"docomo":"E70E","au":"E50D","softbank":null,"google":"FE4DB","image":"1f45a.png","sheet_x":15,"sheet_y":16,"short_name":"womans_clothes","short_names":["womans_clothes"],"text":null,"texts":null,"category":"Smileys & People","sort_order":451,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PURSE","unified":"1F45B","non_qualified":null,"docomo":"E70F","au":"E504","softbank":null,"google":"FE4DC","image":"1f45b.png","sheet_x":15,"sheet_y":17,"short_name":"purse","short_names":["purse"],"text":null,"texts":null,"category":"Smileys & People","sort_order":452,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HANDBAG","unified":"1F45C","non_qualified":null,"docomo":"E682","au":"E49C","softbank":"E323","google":"FE4F0","image":"1f45c.png","sheet_x":15,"sheet_y":18,"short_name":"handbag","short_names":["handbag"],"text":null,"texts":null,"category":"Smileys & People","sort_order":453,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POUCH","unified":"1F45D","non_qualified":null,"docomo":"E6AD","au":null,"softbank":null,"google":"FE4F1","image":"1f45d.png","sheet_x":15,"sheet_y":19,"short_name":"pouch","short_names":["pouch"],"text":null,"texts":null,"category":"Smileys & People","sort_order":454,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MANS SHOE","unified":"1F45E","non_qualified":null,"docomo":"E699","au":"E5B7","softbank":null,"google":"FE4CC","image":"1f45e.png","sheet_x":15,"sheet_y":20,"short_name":"mans_shoe","short_names":["mans_shoe","shoe"],"text":null,"texts":null,"category":"Smileys & People","sort_order":457,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ATHLETIC SHOE","unified":"1F45F","non_qualified":null,"docomo":"E699","au":"EB2B","softbank":"E007","google":"FE4CD","image":"1f45f.png","sheet_x":15,"sheet_y":21,"short_name":"athletic_shoe","short_names":["athletic_shoe"],"text":null,"texts":null,"category":"Smileys & People","sort_order":458,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HIGH-HEELED SHOE","unified":"1F460","non_qualified":null,"docomo":"E674","au":"E51A","softbank":"E13E","google":"FE4D6","image":"1f460.png","sheet_x":15,"sheet_y":22,"short_name":"high_heel","short_names":["high_heel"],"text":null,"texts":null,"category":"Smileys & People","sort_order":461,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WOMANS SANDAL","unified":"1F461","non_qualified":null,"docomo":"E674","au":"E51A","softbank":"E31A","google":"FE4D7","image":"1f461.png","sheet_x":15,"sheet_y":23,"short_name":"sandal","short_names":["sandal"],"text":null,"texts":null,"category":"Smileys & People","sort_order":462,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WOMANS BOOTS","unified":"1F462","non_qualified":null,"docomo":null,"au":"EA9F","softbank":"E31B","google":"FE4D8","image":"1f462.png","sheet_x":15,"sheet_y":24,"short_name":"boot","short_names":["boot"],"text":null,"texts":null,"category":"Smileys & People","sort_order":463,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FOOTPRINTS","unified":"1F463","non_qualified":null,"docomo":"E698","au":"EB2A","softbank":"E536","google":"FE553","image":"1f463.png","sheet_x":15,"sheet_y":25,"short_name":"footprints","short_names":["footprints"],"text":null,"texts":null,"category":"Smileys & People","sort_order":397,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BUST IN SILHOUETTE","unified":"1F464","non_qualified":null,"docomo":"E6B1","au":null,"softbank":null,"google":"FE19A","image":"1f464.png","sheet_x":15,"sheet_y":26,"short_name":"bust_in_silhouette","short_names":["bust_in_silhouette"],"text":null,"texts":null,"category":"Smileys & People","sort_order":276,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BUSTS IN SILHOUETTE","unified":"1F465","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f465.png","sheet_x":15,"sheet_y":27,"short_name":"busts_in_silhouette","short_names":["busts_in_silhouette"],"text":null,"texts":null,"category":"Smileys & People","sort_order":277,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BOY","unified":"1F466","non_qualified":null,"docomo":"E6F0","au":"E4FC","softbank":"E001","google":"FE19B","image":"1f466.png","sheet_x":15,"sheet_y":28,"short_name":"boy","short_names":["boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":116,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F466-1F3FB","non_qualified":null,"image":"1f466-1f3fb.png","sheet_x":15,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F466-1F3FC","non_qualified":null,"image":"1f466-1f3fc.png","sheet_x":15,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F466-1F3FD","non_qualified":null,"image":"1f466-1f3fd.png","sheet_x":15,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F466-1F3FE","non_qualified":null,"image":"1f466-1f3fe.png","sheet_x":15,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F466-1F3FF","non_qualified":null,"image":"1f466-1f3ff.png","sheet_x":15,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"GIRL","unified":"1F467","non_qualified":null,"docomo":"E6F0","au":"E4FA","softbank":"E002","google":"FE19C","image":"1f467.png","sheet_x":15,"sheet_y":34,"short_name":"girl","short_names":["girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":117,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F467-1F3FB","non_qualified":null,"image":"1f467-1f3fb.png","sheet_x":15,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F467-1F3FC","non_qualified":null,"image":"1f467-1f3fc.png","sheet_x":15,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F467-1F3FD","non_qualified":null,"image":"1f467-1f3fd.png","sheet_x":15,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F467-1F3FE","non_qualified":null,"image":"1f467-1f3fe.png","sheet_x":15,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F467-1F3FF","non_qualified":null,"image":"1f467-1f3ff.png","sheet_x":15,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"1F468-200D-1F33E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f33e.png","sheet_x":15,"sheet_y":40,"short_name":"male-farmer","short_names":["male-farmer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":132,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F33E","non_qualified":null,"image":"1f468-1f3fb-200d-1f33e.png","sheet_x":15,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F33E","non_qualified":null,"image":"1f468-1f3fc-200d-1f33e.png","sheet_x":15,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F33E","non_qualified":null,"image":"1f468-1f3fd-200d-1f33e.png","sheet_x":15,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F33E","non_qualified":null,"image":"1f468-1f3fe-200d-1f33e.png","sheet_x":15,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F33E","non_qualified":null,"image":"1f468-1f3ff-200d-1f33e.png","sheet_x":15,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F373","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f373.png","sheet_x":15,"sheet_y":46,"short_name":"male-cook","short_names":["male-cook"],"text":null,"texts":null,"category":"Smileys & People","sort_order":134,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F373","non_qualified":null,"image":"1f468-1f3fb-200d-1f373.png","sheet_x":15,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F373","non_qualified":null,"image":"1f468-1f3fc-200d-1f373.png","sheet_x":15,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F373","non_qualified":null,"image":"1f468-1f3fd-200d-1f373.png","sheet_x":15,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F373","non_qualified":null,"image":"1f468-1f3fe-200d-1f373.png","sheet_x":15,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F373","non_qualified":null,"image":"1f468-1f3ff-200d-1f373.png","sheet_x":15,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F393","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f393.png","sheet_x":15,"sheet_y":52,"short_name":"male-student","short_names":["male-student"],"text":null,"texts":null,"category":"Smileys & People","sort_order":126,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F393","non_qualified":null,"image":"1f468-1f3fb-200d-1f393.png","sheet_x":16,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F393","non_qualified":null,"image":"1f468-1f3fc-200d-1f393.png","sheet_x":16,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F393","non_qualified":null,"image":"1f468-1f3fd-200d-1f393.png","sheet_x":16,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F393","non_qualified":null,"image":"1f468-1f3fe-200d-1f393.png","sheet_x":16,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F393","non_qualified":null,"image":"1f468-1f3ff-200d-1f393.png","sheet_x":16,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F3A4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f3a4.png","sheet_x":16,"sheet_y":5,"short_name":"male-singer","short_names":["male-singer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":146,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F3A4","non_qualified":null,"image":"1f468-1f3fb-200d-1f3a4.png","sheet_x":16,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F3A4","non_qualified":null,"image":"1f468-1f3fc-200d-1f3a4.png","sheet_x":16,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F3A4","non_qualified":null,"image":"1f468-1f3fd-200d-1f3a4.png","sheet_x":16,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F3A4","non_qualified":null,"image":"1f468-1f3fe-200d-1f3a4.png","sheet_x":16,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F3A4","non_qualified":null,"image":"1f468-1f3ff-200d-1f3a4.png","sheet_x":16,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F3A8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f3a8.png","sheet_x":16,"sheet_y":11,"short_name":"male-artist","short_names":["male-artist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":148,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F3A8","non_qualified":null,"image":"1f468-1f3fb-200d-1f3a8.png","sheet_x":16,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F3A8","non_qualified":null,"image":"1f468-1f3fc-200d-1f3a8.png","sheet_x":16,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F3A8","non_qualified":null,"image":"1f468-1f3fd-200d-1f3a8.png","sheet_x":16,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F3A8","non_qualified":null,"image":"1f468-1f3fe-200d-1f3a8.png","sheet_x":16,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F3A8","non_qualified":null,"image":"1f468-1f3ff-200d-1f3a8.png","sheet_x":16,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F3EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f3eb.png","sheet_x":16,"sheet_y":17,"short_name":"male-teacher","short_names":["male-teacher"],"text":null,"texts":null,"category":"Smileys & People","sort_order":128,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F3EB","non_qualified":null,"image":"1f468-1f3fb-200d-1f3eb.png","sheet_x":16,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F3EB","non_qualified":null,"image":"1f468-1f3fc-200d-1f3eb.png","sheet_x":16,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F3EB","non_qualified":null,"image":"1f468-1f3fd-200d-1f3eb.png","sheet_x":16,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F3EB","non_qualified":null,"image":"1f468-1f3fe-200d-1f3eb.png","sheet_x":16,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F3EB","non_qualified":null,"image":"1f468-1f3ff-200d-1f3eb.png","sheet_x":16,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F3ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f3ed.png","sheet_x":16,"sheet_y":23,"short_name":"male-factory-worker","short_names":["male-factory-worker"],"text":null,"texts":null,"category":"Smileys & People","sort_order":138,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F3ED","non_qualified":null,"image":"1f468-1f3fb-200d-1f3ed.png","sheet_x":16,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F3ED","non_qualified":null,"image":"1f468-1f3fc-200d-1f3ed.png","sheet_x":16,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F3ED","non_qualified":null,"image":"1f468-1f3fd-200d-1f3ed.png","sheet_x":16,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F3ED","non_qualified":null,"image":"1f468-1f3fe-200d-1f3ed.png","sheet_x":16,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F3ED","non_qualified":null,"image":"1f468-1f3ff-200d-1f3ed.png","sheet_x":16,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F466-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f466-200d-1f466.png","sheet_x":16,"sheet_y":29,"short_name":"man-boy-boy","short_names":["man-boy-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":351,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F468-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f466.png","sheet_x":16,"sheet_y":30,"short_name":"man-boy","short_names":["man-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":350,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F468-200D-1F467-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f467-200d-1f466.png","sheet_x":16,"sheet_y":31,"short_name":"man-girl-boy","short_names":["man-girl-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":353,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F468-200D-1F467-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f467-200d-1f467.png","sheet_x":16,"sheet_y":32,"short_name":"man-girl-girl","short_names":["man-girl-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":354,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F468-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f467.png","sheet_x":16,"sheet_y":33,"short_name":"man-girl","short_names":["man-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":352,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F468-200D-1F468-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f468-200d-1f466.png","sheet_x":16,"sheet_y":34,"short_name":"man-man-boy","short_names":["man-man-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":340,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-1F468-200D-1F466-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f468-200d-1f466-200d-1f466.png","sheet_x":16,"sheet_y":35,"short_name":"man-man-boy-boy","short_names":["man-man-boy-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":343,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-1F468-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f468-200d-1f467.png","sheet_x":16,"sheet_y":36,"short_name":"man-man-girl","short_names":["man-man-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":341,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-1F468-200D-1F467-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f468-200d-1f467-200d-1f466.png","sheet_x":16,"sheet_y":37,"short_name":"man-man-girl-boy","short_names":["man-man-girl-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":342,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-1F468-200D-1F467-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f468-200d-1f467-200d-1f467.png","sheet_x":16,"sheet_y":38,"short_name":"man-man-girl-girl","short_names":["man-man-girl-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":344,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-1F469-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f469-200d-1f466.png","sheet_x":16,"sheet_y":39,"short_name":"man-woman-boy","short_names":["man-woman-boy","family"],"text":null,"texts":null,"category":"Smileys & People","sort_order":335,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"obsoletes":"1F46A"},{"name":null,"unified":"1F468-200D-1F469-200D-1F466-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f469-200d-1f466-200d-1f466.png","sheet_x":16,"sheet_y":40,"short_name":"man-woman-boy-boy","short_names":["man-woman-boy-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":338,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-1F469-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f469-200d-1f467.png","sheet_x":16,"sheet_y":41,"short_name":"man-woman-girl","short_names":["man-woman-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":336,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-1F469-200D-1F467-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f469-200d-1f467-200d-1f466.png","sheet_x":16,"sheet_y":42,"short_name":"man-woman-girl-boy","short_names":["man-woman-girl-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":337,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-1F469-200D-1F467-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f469-200d-1f467-200d-1f467.png","sheet_x":16,"sheet_y":43,"short_name":"man-woman-girl-girl","short_names":["man-woman-girl-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":339,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-1F4BB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f4bb.png","sheet_x":16,"sheet_y":44,"short_name":"male-technologist","short_names":["male-technologist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":144,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F4BB","non_qualified":null,"image":"1f468-1f3fb-200d-1f4bb.png","sheet_x":16,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F4BB","non_qualified":null,"image":"1f468-1f3fc-200d-1f4bb.png","sheet_x":16,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F4BB","non_qualified":null,"image":"1f468-1f3fd-200d-1f4bb.png","sheet_x":16,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F4BB","non_qualified":null,"image":"1f468-1f3fe-200d-1f4bb.png","sheet_x":16,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F4BB","non_qualified":null,"image":"1f468-1f3ff-200d-1f4bb.png","sheet_x":16,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F4BC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f4bc.png","sheet_x":16,"sheet_y":50,"short_name":"male-office-worker","short_names":["male-office-worker"],"text":null,"texts":null,"category":"Smileys & People","sort_order":140,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F4BC","non_qualified":null,"image":"1f468-1f3fb-200d-1f4bc.png","sheet_x":16,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F4BC","non_qualified":null,"image":"1f468-1f3fc-200d-1f4bc.png","sheet_x":16,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F4BC","non_qualified":null,"image":"1f468-1f3fd-200d-1f4bc.png","sheet_x":17,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F4BC","non_qualified":null,"image":"1f468-1f3fe-200d-1f4bc.png","sheet_x":17,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F4BC","non_qualified":null,"image":"1f468-1f3ff-200d-1f4bc.png","sheet_x":17,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F527","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f527.png","sheet_x":17,"sheet_y":3,"short_name":"male-mechanic","short_names":["male-mechanic"],"text":null,"texts":null,"category":"Smileys & People","sort_order":136,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F527","non_qualified":null,"image":"1f468-1f3fb-200d-1f527.png","sheet_x":17,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F527","non_qualified":null,"image":"1f468-1f3fc-200d-1f527.png","sheet_x":17,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F527","non_qualified":null,"image":"1f468-1f3fd-200d-1f527.png","sheet_x":17,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F527","non_qualified":null,"image":"1f468-1f3fe-200d-1f527.png","sheet_x":17,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F527","non_qualified":null,"image":"1f468-1f3ff-200d-1f527.png","sheet_x":17,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F52C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f52c.png","sheet_x":17,"sheet_y":9,"short_name":"male-scientist","short_names":["male-scientist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":142,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F52C","non_qualified":null,"image":"1f468-1f3fb-200d-1f52c.png","sheet_x":17,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F52C","non_qualified":null,"image":"1f468-1f3fc-200d-1f52c.png","sheet_x":17,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F52C","non_qualified":null,"image":"1f468-1f3fd-200d-1f52c.png","sheet_x":17,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F52C","non_qualified":null,"image":"1f468-1f3fe-200d-1f52c.png","sheet_x":17,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F52C","non_qualified":null,"image":"1f468-1f3ff-200d-1f52c.png","sheet_x":17,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F680","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f680.png","sheet_x":17,"sheet_y":15,"short_name":"male-astronaut","short_names":["male-astronaut"],"text":null,"texts":null,"category":"Smileys & People","sort_order":152,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F680","non_qualified":null,"image":"1f468-1f3fb-200d-1f680.png","sheet_x":17,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F680","non_qualified":null,"image":"1f468-1f3fc-200d-1f680.png","sheet_x":17,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F680","non_qualified":null,"image":"1f468-1f3fd-200d-1f680.png","sheet_x":17,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F680","non_qualified":null,"image":"1f468-1f3fe-200d-1f680.png","sheet_x":17,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F680","non_qualified":null,"image":"1f468-1f3ff-200d-1f680.png","sheet_x":17,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F692","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f692.png","sheet_x":17,"sheet_y":21,"short_name":"male-firefighter","short_names":["male-firefighter"],"text":null,"texts":null,"category":"Smileys & People","sort_order":154,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F692","non_qualified":null,"image":"1f468-1f3fb-200d-1f692.png","sheet_x":17,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F692","non_qualified":null,"image":"1f468-1f3fc-200d-1f692.png","sheet_x":17,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F692","non_qualified":null,"image":"1f468-1f3fd-200d-1f692.png","sheet_x":17,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F692","non_qualified":null,"image":"1f468-1f3fe-200d-1f692.png","sheet_x":17,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F692","non_qualified":null,"image":"1f468-1f3ff-200d-1f692.png","sheet_x":17,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F9B0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f9b0.png","sheet_x":17,"sheet_y":27,"short_name":"male_red_haired","short_names":["male_red_haired"],"text":null,"texts":null,"category":"Smileys & People","sort_order":179,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F9B0","non_qualified":null,"image":"1f468-1f3fb-200d-1f9b0.png","sheet_x":17,"sheet_y":28,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F9B0","non_qualified":null,"image":"1f468-1f3fc-200d-1f9b0.png","sheet_x":17,"sheet_y":29,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F9B0","non_qualified":null,"image":"1f468-1f3fd-200d-1f9b0.png","sheet_x":17,"sheet_y":30,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F9B0","non_qualified":null,"image":"1f468-1f3fe-200d-1f9b0.png","sheet_x":17,"sheet_y":31,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F9B0","non_qualified":null,"image":"1f468-1f3ff-200d-1f9b0.png","sheet_x":17,"sheet_y":32,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F9B1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f9b1.png","sheet_x":17,"sheet_y":33,"short_name":"male_curly_haired","short_names":["male_curly_haired"],"text":null,"texts":null,"category":"Smileys & People","sort_order":181,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F9B1","non_qualified":null,"image":"1f468-1f3fb-200d-1f9b1.png","sheet_x":17,"sheet_y":34,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F9B1","non_qualified":null,"image":"1f468-1f3fc-200d-1f9b1.png","sheet_x":17,"sheet_y":35,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F9B1","non_qualified":null,"image":"1f468-1f3fd-200d-1f9b1.png","sheet_x":17,"sheet_y":36,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F9B1","non_qualified":null,"image":"1f468-1f3fe-200d-1f9b1.png","sheet_x":17,"sheet_y":37,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F9B1","non_qualified":null,"image":"1f468-1f3ff-200d-1f9b1.png","sheet_x":17,"sheet_y":38,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F9B2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f9b2.png","sheet_x":17,"sheet_y":39,"short_name":"male_bald","short_names":["male_bald"],"text":null,"texts":null,"category":"Smileys & People","sort_order":183,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F9B2","non_qualified":null,"image":"1f468-1f3fb-200d-1f9b2.png","sheet_x":17,"sheet_y":40,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F9B2","non_qualified":null,"image":"1f468-1f3fc-200d-1f9b2.png","sheet_x":17,"sheet_y":41,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F9B2","non_qualified":null,"image":"1f468-1f3fd-200d-1f9b2.png","sheet_x":17,"sheet_y":42,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F9B2","non_qualified":null,"image":"1f468-1f3fe-200d-1f9b2.png","sheet_x":17,"sheet_y":43,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F9B2","non_qualified":null,"image":"1f468-1f3ff-200d-1f9b2.png","sheet_x":17,"sheet_y":44,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-1F9B3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-1f9b3.png","sheet_x":17,"sheet_y":45,"short_name":"male_white_haired","short_names":["male_white_haired"],"text":null,"texts":null,"category":"Smileys & People","sort_order":185,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F9B3","non_qualified":null,"image":"1f468-1f3fb-200d-1f9b3.png","sheet_x":17,"sheet_y":46,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F9B3","non_qualified":null,"image":"1f468-1f3fc-200d-1f9b3.png","sheet_x":17,"sheet_y":47,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F9B3","non_qualified":null,"image":"1f468-1f3fd-200d-1f9b3.png","sheet_x":17,"sheet_y":48,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F9B3","non_qualified":null,"image":"1f468-1f3fe-200d-1f9b3.png","sheet_x":17,"sheet_y":49,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F9B3","non_qualified":null,"image":"1f468-1f3ff-200d-1f9b3.png","sheet_x":17,"sheet_y":50,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-2695-FE0F","non_qualified":"1F468-200D-2695","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-2695-fe0f.png","sheet_x":17,"sheet_y":51,"short_name":"male-doctor","short_names":["male-doctor"],"text":null,"texts":null,"category":"Smileys & People","sort_order":124,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-2695-FE0F","non_qualified":"1F468-1F3FB-200D-2695","image":"1f468-1f3fb-200d-2695-fe0f.png","sheet_x":17,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-2695-FE0F","non_qualified":"1F468-1F3FC-200D-2695","image":"1f468-1f3fc-200d-2695-fe0f.png","sheet_x":18,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-2695-FE0F","non_qualified":"1F468-1F3FD-200D-2695","image":"1f468-1f3fd-200d-2695-fe0f.png","sheet_x":18,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-2695-FE0F","non_qualified":"1F468-1F3FE-200D-2695","image":"1f468-1f3fe-200d-2695-fe0f.png","sheet_x":18,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-2695-FE0F","non_qualified":"1F468-1F3FF-200D-2695","image":"1f468-1f3ff-200d-2695-fe0f.png","sheet_x":18,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-2696-FE0F","non_qualified":"1F468-200D-2696","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-2696-fe0f.png","sheet_x":18,"sheet_y":4,"short_name":"male-judge","short_names":["male-judge"],"text":null,"texts":null,"category":"Smileys & People","sort_order":130,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-2696-FE0F","non_qualified":"1F468-1F3FB-200D-2696","image":"1f468-1f3fb-200d-2696-fe0f.png","sheet_x":18,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-2696-FE0F","non_qualified":"1F468-1F3FC-200D-2696","image":"1f468-1f3fc-200d-2696-fe0f.png","sheet_x":18,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-2696-FE0F","non_qualified":"1F468-1F3FD-200D-2696","image":"1f468-1f3fd-200d-2696-fe0f.png","sheet_x":18,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-2696-FE0F","non_qualified":"1F468-1F3FE-200D-2696","image":"1f468-1f3fe-200d-2696-fe0f.png","sheet_x":18,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-2696-FE0F","non_qualified":"1F468-1F3FF-200D-2696","image":"1f468-1f3ff-200d-2696-fe0f.png","sheet_x":18,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-2708-FE0F","non_qualified":"1F468-200D-2708","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-2708-fe0f.png","sheet_x":18,"sheet_y":10,"short_name":"male-pilot","short_names":["male-pilot"],"text":null,"texts":null,"category":"Smileys & People","sort_order":150,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-2708-FE0F","non_qualified":"1F468-1F3FB-200D-2708","image":"1f468-1f3fb-200d-2708-fe0f.png","sheet_x":18,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-2708-FE0F","non_qualified":"1F468-1F3FC-200D-2708","image":"1f468-1f3fc-200d-2708-fe0f.png","sheet_x":18,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-2708-FE0F","non_qualified":"1F468-1F3FD-200D-2708","image":"1f468-1f3fd-200d-2708-fe0f.png","sheet_x":18,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-2708-FE0F","non_qualified":"1F468-1F3FE-200D-2708","image":"1f468-1f3fe-200d-2708-fe0f.png","sheet_x":18,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-2708-FE0F","non_qualified":"1F468-1F3FF-200D-2708","image":"1f468-1f3ff-200d-2708-fe0f.png","sheet_x":18,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F468-200D-2764-FE0F-200D-1F468","non_qualified":"1F468-200D-2764-200D-1F468","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-2764-fe0f-200d-1f468.png","sheet_x":18,"sheet_y":16,"short_name":"man-heart-man","short_names":["man-heart-man"],"text":null,"texts":null,"category":"Smileys & People","sort_order":332,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F468-200D-2764-FE0F-200D-1F48B-200D-1F468","non_qualified":"1F468-200D-2764-200D-1F48B-200D-1F468","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468.png","sheet_x":18,"sheet_y":17,"short_name":"man-kiss-man","short_names":["man-kiss-man"],"text":null,"texts":null,"category":"Smileys & People","sort_order":328,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MAN","unified":"1F468","non_qualified":null,"docomo":"E6F0","au":"E4FC","softbank":"E004","google":"FE19D","image":"1f468.png","sheet_x":18,"sheet_y":18,"short_name":"man","short_names":["man"],"text":null,"texts":null,"category":"Smileys & People","sort_order":119,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB","non_qualified":null,"image":"1f468-1f3fb.png","sheet_x":18,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F468-1F3FC","non_qualified":null,"image":"1f468-1f3fc.png","sheet_x":18,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F468-1F3FD","non_qualified":null,"image":"1f468-1f3fd.png","sheet_x":18,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F468-1F3FE","non_qualified":null,"image":"1f468-1f3fe.png","sheet_x":18,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F468-1F3FF","non_qualified":null,"image":"1f468-1f3ff.png","sheet_x":18,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"1F469-200D-1F33E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f33e.png","sheet_x":18,"sheet_y":24,"short_name":"female-farmer","short_names":["female-farmer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":133,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F33E","non_qualified":null,"image":"1f469-1f3fb-200d-1f33e.png","sheet_x":18,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F33E","non_qualified":null,"image":"1f469-1f3fc-200d-1f33e.png","sheet_x":18,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F33E","non_qualified":null,"image":"1f469-1f3fd-200d-1f33e.png","sheet_x":18,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F33E","non_qualified":null,"image":"1f469-1f3fe-200d-1f33e.png","sheet_x":18,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F33E","non_qualified":null,"image":"1f469-1f3ff-200d-1f33e.png","sheet_x":18,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F373","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f373.png","sheet_x":18,"sheet_y":30,"short_name":"female-cook","short_names":["female-cook"],"text":null,"texts":null,"category":"Smileys & People","sort_order":135,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F373","non_qualified":null,"image":"1f469-1f3fb-200d-1f373.png","sheet_x":18,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F373","non_qualified":null,"image":"1f469-1f3fc-200d-1f373.png","sheet_x":18,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F373","non_qualified":null,"image":"1f469-1f3fd-200d-1f373.png","sheet_x":18,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F373","non_qualified":null,"image":"1f469-1f3fe-200d-1f373.png","sheet_x":18,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F373","non_qualified":null,"image":"1f469-1f3ff-200d-1f373.png","sheet_x":18,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F393","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f393.png","sheet_x":18,"sheet_y":36,"short_name":"female-student","short_names":["female-student"],"text":null,"texts":null,"category":"Smileys & People","sort_order":127,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F393","non_qualified":null,"image":"1f469-1f3fb-200d-1f393.png","sheet_x":18,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F393","non_qualified":null,"image":"1f469-1f3fc-200d-1f393.png","sheet_x":18,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F393","non_qualified":null,"image":"1f469-1f3fd-200d-1f393.png","sheet_x":18,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F393","non_qualified":null,"image":"1f469-1f3fe-200d-1f393.png","sheet_x":18,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F393","non_qualified":null,"image":"1f469-1f3ff-200d-1f393.png","sheet_x":18,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F3A4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f3a4.png","sheet_x":18,"sheet_y":42,"short_name":"female-singer","short_names":["female-singer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":147,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F3A4","non_qualified":null,"image":"1f469-1f3fb-200d-1f3a4.png","sheet_x":18,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F3A4","non_qualified":null,"image":"1f469-1f3fc-200d-1f3a4.png","sheet_x":18,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F3A4","non_qualified":null,"image":"1f469-1f3fd-200d-1f3a4.png","sheet_x":18,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F3A4","non_qualified":null,"image":"1f469-1f3fe-200d-1f3a4.png","sheet_x":18,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F3A4","non_qualified":null,"image":"1f469-1f3ff-200d-1f3a4.png","sheet_x":18,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F3A8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f3a8.png","sheet_x":18,"sheet_y":48,"short_name":"female-artist","short_names":["female-artist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":149,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F3A8","non_qualified":null,"image":"1f469-1f3fb-200d-1f3a8.png","sheet_x":18,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F3A8","non_qualified":null,"image":"1f469-1f3fc-200d-1f3a8.png","sheet_x":18,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F3A8","non_qualified":null,"image":"1f469-1f3fd-200d-1f3a8.png","sheet_x":18,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F3A8","non_qualified":null,"image":"1f469-1f3fe-200d-1f3a8.png","sheet_x":18,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F3A8","non_qualified":null,"image":"1f469-1f3ff-200d-1f3a8.png","sheet_x":19,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F3EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f3eb.png","sheet_x":19,"sheet_y":1,"short_name":"female-teacher","short_names":["female-teacher"],"text":null,"texts":null,"category":"Smileys & People","sort_order":129,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F3EB","non_qualified":null,"image":"1f469-1f3fb-200d-1f3eb.png","sheet_x":19,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F3EB","non_qualified":null,"image":"1f469-1f3fc-200d-1f3eb.png","sheet_x":19,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F3EB","non_qualified":null,"image":"1f469-1f3fd-200d-1f3eb.png","sheet_x":19,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F3EB","non_qualified":null,"image":"1f469-1f3fe-200d-1f3eb.png","sheet_x":19,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F3EB","non_qualified":null,"image":"1f469-1f3ff-200d-1f3eb.png","sheet_x":19,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F3ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f3ed.png","sheet_x":19,"sheet_y":7,"short_name":"female-factory-worker","short_names":["female-factory-worker"],"text":null,"texts":null,"category":"Smileys & People","sort_order":139,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F3ED","non_qualified":null,"image":"1f469-1f3fb-200d-1f3ed.png","sheet_x":19,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F3ED","non_qualified":null,"image":"1f469-1f3fc-200d-1f3ed.png","sheet_x":19,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F3ED","non_qualified":null,"image":"1f469-1f3fd-200d-1f3ed.png","sheet_x":19,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F3ED","non_qualified":null,"image":"1f469-1f3fe-200d-1f3ed.png","sheet_x":19,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F3ED","non_qualified":null,"image":"1f469-1f3ff-200d-1f3ed.png","sheet_x":19,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F466-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f466-200d-1f466.png","sheet_x":19,"sheet_y":13,"short_name":"woman-boy-boy","short_names":["woman-boy-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":356,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F469-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f466.png","sheet_x":19,"sheet_y":14,"short_name":"woman-boy","short_names":["woman-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":355,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F469-200D-1F467-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f467-200d-1f466.png","sheet_x":19,"sheet_y":15,"short_name":"woman-girl-boy","short_names":["woman-girl-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":358,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F469-200D-1F467-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f467-200d-1f467.png","sheet_x":19,"sheet_y":16,"short_name":"woman-girl-girl","short_names":["woman-girl-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":359,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F469-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f467.png","sheet_x":19,"sheet_y":17,"short_name":"woman-girl","short_names":["woman-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":357,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F469-200D-1F469-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f469-200d-1f466.png","sheet_x":19,"sheet_y":18,"short_name":"woman-woman-boy","short_names":["woman-woman-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":345,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F469-200D-1F469-200D-1F466-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f469-200d-1f466-200d-1f466.png","sheet_x":19,"sheet_y":19,"short_name":"woman-woman-boy-boy","short_names":["woman-woman-boy-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":348,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F469-200D-1F469-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f469-200d-1f467.png","sheet_x":19,"sheet_y":20,"short_name":"woman-woman-girl","short_names":["woman-woman-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":346,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F469-200D-1F469-200D-1F467-200D-1F466","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f469-200d-1f467-200d-1f466.png","sheet_x":19,"sheet_y":21,"short_name":"woman-woman-girl-boy","short_names":["woman-woman-girl-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":347,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F469-200D-1F469-200D-1F467-200D-1F467","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f469-200d-1f467-200d-1f467.png","sheet_x":19,"sheet_y":22,"short_name":"woman-woman-girl-girl","short_names":["woman-woman-girl-girl"],"text":null,"texts":null,"category":"Smileys & People","sort_order":349,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F469-200D-1F4BB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f4bb.png","sheet_x":19,"sheet_y":23,"short_name":"female-technologist","short_names":["female-technologist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":145,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F4BB","non_qualified":null,"image":"1f469-1f3fb-200d-1f4bb.png","sheet_x":19,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F4BB","non_qualified":null,"image":"1f469-1f3fc-200d-1f4bb.png","sheet_x":19,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F4BB","non_qualified":null,"image":"1f469-1f3fd-200d-1f4bb.png","sheet_x":19,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F4BB","non_qualified":null,"image":"1f469-1f3fe-200d-1f4bb.png","sheet_x":19,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F4BB","non_qualified":null,"image":"1f469-1f3ff-200d-1f4bb.png","sheet_x":19,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F4BC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f4bc.png","sheet_x":19,"sheet_y":29,"short_name":"female-office-worker","short_names":["female-office-worker"],"text":null,"texts":null,"category":"Smileys & People","sort_order":141,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F4BC","non_qualified":null,"image":"1f469-1f3fb-200d-1f4bc.png","sheet_x":19,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F4BC","non_qualified":null,"image":"1f469-1f3fc-200d-1f4bc.png","sheet_x":19,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F4BC","non_qualified":null,"image":"1f469-1f3fd-200d-1f4bc.png","sheet_x":19,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F4BC","non_qualified":null,"image":"1f469-1f3fe-200d-1f4bc.png","sheet_x":19,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F4BC","non_qualified":null,"image":"1f469-1f3ff-200d-1f4bc.png","sheet_x":19,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F527","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f527.png","sheet_x":19,"sheet_y":35,"short_name":"female-mechanic","short_names":["female-mechanic"],"text":null,"texts":null,"category":"Smileys & People","sort_order":137,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F527","non_qualified":null,"image":"1f469-1f3fb-200d-1f527.png","sheet_x":19,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F527","non_qualified":null,"image":"1f469-1f3fc-200d-1f527.png","sheet_x":19,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F527","non_qualified":null,"image":"1f469-1f3fd-200d-1f527.png","sheet_x":19,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F527","non_qualified":null,"image":"1f469-1f3fe-200d-1f527.png","sheet_x":19,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F527","non_qualified":null,"image":"1f469-1f3ff-200d-1f527.png","sheet_x":19,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F52C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f52c.png","sheet_x":19,"sheet_y":41,"short_name":"female-scientist","short_names":["female-scientist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":143,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F52C","non_qualified":null,"image":"1f469-1f3fb-200d-1f52c.png","sheet_x":19,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F52C","non_qualified":null,"image":"1f469-1f3fc-200d-1f52c.png","sheet_x":19,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F52C","non_qualified":null,"image":"1f469-1f3fd-200d-1f52c.png","sheet_x":19,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F52C","non_qualified":null,"image":"1f469-1f3fe-200d-1f52c.png","sheet_x":19,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F52C","non_qualified":null,"image":"1f469-1f3ff-200d-1f52c.png","sheet_x":19,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F680","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f680.png","sheet_x":19,"sheet_y":47,"short_name":"female-astronaut","short_names":["female-astronaut"],"text":null,"texts":null,"category":"Smileys & People","sort_order":153,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F680","non_qualified":null,"image":"1f469-1f3fb-200d-1f680.png","sheet_x":19,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F680","non_qualified":null,"image":"1f469-1f3fc-200d-1f680.png","sheet_x":19,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F680","non_qualified":null,"image":"1f469-1f3fd-200d-1f680.png","sheet_x":19,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F680","non_qualified":null,"image":"1f469-1f3fe-200d-1f680.png","sheet_x":19,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F680","non_qualified":null,"image":"1f469-1f3ff-200d-1f680.png","sheet_x":19,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F692","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f692.png","sheet_x":20,"sheet_y":0,"short_name":"female-firefighter","short_names":["female-firefighter"],"text":null,"texts":null,"category":"Smileys & People","sort_order":155,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F692","non_qualified":null,"image":"1f469-1f3fb-200d-1f692.png","sheet_x":20,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F692","non_qualified":null,"image":"1f469-1f3fc-200d-1f692.png","sheet_x":20,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F692","non_qualified":null,"image":"1f469-1f3fd-200d-1f692.png","sheet_x":20,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F692","non_qualified":null,"image":"1f469-1f3fe-200d-1f692.png","sheet_x":20,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F692","non_qualified":null,"image":"1f469-1f3ff-200d-1f692.png","sheet_x":20,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F9B0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f9b0.png","sheet_x":20,"sheet_y":6,"short_name":"female_red_haired","short_names":["female_red_haired"],"text":null,"texts":null,"category":"Smileys & People","sort_order":180,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F9B0","non_qualified":null,"image":"1f469-1f3fb-200d-1f9b0.png","sheet_x":20,"sheet_y":7,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F9B0","non_qualified":null,"image":"1f469-1f3fc-200d-1f9b0.png","sheet_x":20,"sheet_y":8,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F9B0","non_qualified":null,"image":"1f469-1f3fd-200d-1f9b0.png","sheet_x":20,"sheet_y":9,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F9B0","non_qualified":null,"image":"1f469-1f3fe-200d-1f9b0.png","sheet_x":20,"sheet_y":10,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F9B0","non_qualified":null,"image":"1f469-1f3ff-200d-1f9b0.png","sheet_x":20,"sheet_y":11,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F9B1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f9b1.png","sheet_x":20,"sheet_y":12,"short_name":"female_curly_haired","short_names":["female_curly_haired"],"text":null,"texts":null,"category":"Smileys & People","sort_order":182,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F9B1","non_qualified":null,"image":"1f469-1f3fb-200d-1f9b1.png","sheet_x":20,"sheet_y":13,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F9B1","non_qualified":null,"image":"1f469-1f3fc-200d-1f9b1.png","sheet_x":20,"sheet_y":14,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F9B1","non_qualified":null,"image":"1f469-1f3fd-200d-1f9b1.png","sheet_x":20,"sheet_y":15,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F9B1","non_qualified":null,"image":"1f469-1f3fe-200d-1f9b1.png","sheet_x":20,"sheet_y":16,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F9B1","non_qualified":null,"image":"1f469-1f3ff-200d-1f9b1.png","sheet_x":20,"sheet_y":17,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F9B2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f9b2.png","sheet_x":20,"sheet_y":18,"short_name":"female_bald","short_names":["female_bald"],"text":null,"texts":null,"category":"Smileys & People","sort_order":184,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F9B2","non_qualified":null,"image":"1f469-1f3fb-200d-1f9b2.png","sheet_x":20,"sheet_y":19,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F9B2","non_qualified":null,"image":"1f469-1f3fc-200d-1f9b2.png","sheet_x":20,"sheet_y":20,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F9B2","non_qualified":null,"image":"1f469-1f3fd-200d-1f9b2.png","sheet_x":20,"sheet_y":21,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F9B2","non_qualified":null,"image":"1f469-1f3fe-200d-1f9b2.png","sheet_x":20,"sheet_y":22,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F9B2","non_qualified":null,"image":"1f469-1f3ff-200d-1f9b2.png","sheet_x":20,"sheet_y":23,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-1F9B3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-1f9b3.png","sheet_x":20,"sheet_y":24,"short_name":"female_white_haired","short_names":["female_white_haired"],"text":null,"texts":null,"category":"Smileys & People","sort_order":186,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F9B3","non_qualified":null,"image":"1f469-1f3fb-200d-1f9b3.png","sheet_x":20,"sheet_y":25,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F9B3","non_qualified":null,"image":"1f469-1f3fc-200d-1f9b3.png","sheet_x":20,"sheet_y":26,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F9B3","non_qualified":null,"image":"1f469-1f3fd-200d-1f9b3.png","sheet_x":20,"sheet_y":27,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F9B3","non_qualified":null,"image":"1f469-1f3fe-200d-1f9b3.png","sheet_x":20,"sheet_y":28,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F9B3","non_qualified":null,"image":"1f469-1f3ff-200d-1f9b3.png","sheet_x":20,"sheet_y":29,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-2695-FE0F","non_qualified":"1F469-200D-2695","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-2695-fe0f.png","sheet_x":20,"sheet_y":30,"short_name":"female-doctor","short_names":["female-doctor"],"text":null,"texts":null,"category":"Smileys & People","sort_order":125,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-2695-FE0F","non_qualified":"1F469-1F3FB-200D-2695","image":"1f469-1f3fb-200d-2695-fe0f.png","sheet_x":20,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-2695-FE0F","non_qualified":"1F469-1F3FC-200D-2695","image":"1f469-1f3fc-200d-2695-fe0f.png","sheet_x":20,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-2695-FE0F","non_qualified":"1F469-1F3FD-200D-2695","image":"1f469-1f3fd-200d-2695-fe0f.png","sheet_x":20,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-2695-FE0F","non_qualified":"1F469-1F3FE-200D-2695","image":"1f469-1f3fe-200d-2695-fe0f.png","sheet_x":20,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-2695-FE0F","non_qualified":"1F469-1F3FF-200D-2695","image":"1f469-1f3ff-200d-2695-fe0f.png","sheet_x":20,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-2696-FE0F","non_qualified":"1F469-200D-2696","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-2696-fe0f.png","sheet_x":20,"sheet_y":36,"short_name":"female-judge","short_names":["female-judge"],"text":null,"texts":null,"category":"Smileys & People","sort_order":131,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-2696-FE0F","non_qualified":"1F469-1F3FB-200D-2696","image":"1f469-1f3fb-200d-2696-fe0f.png","sheet_x":20,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-2696-FE0F","non_qualified":"1F469-1F3FC-200D-2696","image":"1f469-1f3fc-200d-2696-fe0f.png","sheet_x":20,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-2696-FE0F","non_qualified":"1F469-1F3FD-200D-2696","image":"1f469-1f3fd-200d-2696-fe0f.png","sheet_x":20,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-2696-FE0F","non_qualified":"1F469-1F3FE-200D-2696","image":"1f469-1f3fe-200d-2696-fe0f.png","sheet_x":20,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-2696-FE0F","non_qualified":"1F469-1F3FF-200D-2696","image":"1f469-1f3ff-200d-2696-fe0f.png","sheet_x":20,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-2708-FE0F","non_qualified":"1F469-200D-2708","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-2708-fe0f.png","sheet_x":20,"sheet_y":42,"short_name":"female-pilot","short_names":["female-pilot"],"text":null,"texts":null,"category":"Smileys & People","sort_order":151,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-2708-FE0F","non_qualified":"1F469-1F3FB-200D-2708","image":"1f469-1f3fb-200d-2708-fe0f.png","sheet_x":20,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-2708-FE0F","non_qualified":"1F469-1F3FC-200D-2708","image":"1f469-1f3fc-200d-2708-fe0f.png","sheet_x":20,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-2708-FE0F","non_qualified":"1F469-1F3FD-200D-2708","image":"1f469-1f3fd-200d-2708-fe0f.png","sheet_x":20,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-2708-FE0F","non_qualified":"1F469-1F3FE-200D-2708","image":"1f469-1f3fe-200d-2708-fe0f.png","sheet_x":20,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-2708-FE0F","non_qualified":"1F469-1F3FF-200D-2708","image":"1f469-1f3ff-200d-2708-fe0f.png","sheet_x":20,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F469-200D-2764-FE0F-200D-1F468","non_qualified":"1F469-200D-2764-200D-1F468","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-2764-fe0f-200d-1f468.png","sheet_x":20,"sheet_y":48,"short_name":"woman-heart-man","short_names":["woman-heart-man"],"text":null,"texts":null,"category":"Smileys & People","sort_order":331,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoletes":"1F491"},{"name":null,"unified":"1F469-200D-2764-FE0F-200D-1F469","non_qualified":"1F469-200D-2764-200D-1F469","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-2764-fe0f-200d-1f469.png","sheet_x":20,"sheet_y":49,"short_name":"woman-heart-woman","short_names":["woman-heart-woman"],"text":null,"texts":null,"category":"Smileys & People","sort_order":333,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F468","non_qualified":"1F469-200D-2764-200D-1F48B-200D-1F468","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468.png","sheet_x":20,"sheet_y":50,"short_name":"woman-kiss-man","short_names":["woman-kiss-man"],"text":null,"texts":null,"category":"Smileys & People","sort_order":327,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoletes":"1F48F"},{"name":null,"unified":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F469","non_qualified":"1F469-200D-2764-200D-1F48B-200D-1F469","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469.png","sheet_x":20,"sheet_y":51,"short_name":"woman-kiss-woman","short_names":["woman-kiss-woman"],"text":null,"texts":null,"category":"Smileys & People","sort_order":329,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WOMAN","unified":"1F469","non_qualified":null,"docomo":"E6F0","au":"E4FA","softbank":"E005","google":"FE19E","image":"1f469.png","sheet_x":20,"sheet_y":52,"short_name":"woman","short_names":["woman"],"text":null,"texts":null,"category":"Smileys & People","sort_order":120,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB","non_qualified":null,"image":"1f469-1f3fb.png","sheet_x":21,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F469-1F3FC","non_qualified":null,"image":"1f469-1f3fc.png","sheet_x":21,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F469-1F3FD","non_qualified":null,"image":"1f469-1f3fd.png","sheet_x":21,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F469-1F3FE","non_qualified":null,"image":"1f469-1f3fe.png","sheet_x":21,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F469-1F3FF","non_qualified":null,"image":"1f469-1f3ff.png","sheet_x":21,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"FAMILY","unified":"1F46A","non_qualified":null,"docomo":null,"au":"E501","softbank":null,"google":"FE19F","image":"1f46a.png","sheet_x":21,"sheet_y":5,"short_name":"family","short_names":["family","man-woman-boy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":334,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"obsoleted_by":"1F468-200D-1F469-200D-1F466"},{"name":"MAN AND WOMAN HOLDING HANDS","unified":"1F46B","non_qualified":null,"docomo":null,"au":null,"softbank":"E428","google":"FE1A0","image":"1f46b.png","sheet_x":21,"sheet_y":6,"short_name":"couple","short_names":["couple","man_and_woman_holding_hands"],"text":null,"texts":null,"category":"Smileys & People","sort_order":323,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TWO MEN HOLDING HANDS","unified":"1F46C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f46c.png","sheet_x":21,"sheet_y":7,"short_name":"two_men_holding_hands","short_names":["two_men_holding_hands"],"text":null,"texts":null,"category":"Smileys & People","sort_order":324,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TWO WOMEN HOLDING HANDS","unified":"1F46D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f46d.png","sheet_x":21,"sheet_y":8,"short_name":"two_women_holding_hands","short_names":["two_women_holding_hands"],"text":null,"texts":null,"category":"Smileys & People","sort_order":325,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F46E-200D-2640-FE0F","non_qualified":"1F46E-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f46e-200d-2640-fe0f.png","sheet_x":21,"sheet_y":9,"short_name":"female-police-officer","short_names":["female-police-officer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":158,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F46E-1F3FB-200D-2640-FE0F","non_qualified":"1F46E-1F3FB-200D-2640","image":"1f46e-1f3fb-200d-2640-fe0f.png","sheet_x":21,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F46E-1F3FC-200D-2640-FE0F","non_qualified":"1F46E-1F3FC-200D-2640","image":"1f46e-1f3fc-200d-2640-fe0f.png","sheet_x":21,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F46E-1F3FD-200D-2640-FE0F","non_qualified":"1F46E-1F3FD-200D-2640","image":"1f46e-1f3fd-200d-2640-fe0f.png","sheet_x":21,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F46E-1F3FE-200D-2640-FE0F","non_qualified":"1F46E-1F3FE-200D-2640","image":"1f46e-1f3fe-200d-2640-fe0f.png","sheet_x":21,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F46E-1F3FF-200D-2640-FE0F","non_qualified":"1F46E-1F3FF-200D-2640","image":"1f46e-1f3ff-200d-2640-fe0f.png","sheet_x":21,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F46E-200D-2642-FE0F","non_qualified":"1F46E-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f46e-200d-2642-fe0f.png","sheet_x":21,"sheet_y":15,"short_name":"male-police-officer","short_names":["male-police-officer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":157,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F46E-1F3FB-200D-2642-FE0F","non_qualified":"1F46E-1F3FB-200D-2642","image":"1f46e-1f3fb-200d-2642-fe0f.png","sheet_x":21,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F46E-1F3FC-200D-2642-FE0F","non_qualified":"1F46E-1F3FC-200D-2642","image":"1f46e-1f3fc-200d-2642-fe0f.png","sheet_x":21,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F46E-1F3FD-200D-2642-FE0F","non_qualified":"1F46E-1F3FD-200D-2642","image":"1f46e-1f3fd-200d-2642-fe0f.png","sheet_x":21,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F46E-1F3FE-200D-2642-FE0F","non_qualified":"1F46E-1F3FE-200D-2642","image":"1f46e-1f3fe-200d-2642-fe0f.png","sheet_x":21,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F46E-1F3FF-200D-2642-FE0F","non_qualified":"1F46E-1F3FF-200D-2642","image":"1f46e-1f3ff-200d-2642-fe0f.png","sheet_x":21,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F46E"},{"name":"POLICE OFFICER","unified":"1F46E","non_qualified":null,"docomo":null,"au":"E5DD","softbank":"E152","google":"FE1A1","image":"1f46e.png","sheet_x":21,"sheet_y":21,"short_name":"cop","short_names":["cop"],"text":null,"texts":null,"category":"Smileys & People","sort_order":156,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F46E-1F3FB","non_qualified":null,"image":"1f46e-1f3fb.png","sheet_x":21,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F46E-1F3FC","non_qualified":null,"image":"1f46e-1f3fc.png","sheet_x":21,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F46E-1F3FD","non_qualified":null,"image":"1f46e-1f3fd.png","sheet_x":21,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F46E-1F3FE","non_qualified":null,"image":"1f46e-1f3fe.png","sheet_x":21,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F46E-1F3FF","non_qualified":null,"image":"1f46e-1f3ff.png","sheet_x":21,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F46E-200D-2642-FE0F"},{"name":null,"unified":"1F46F-200D-2640-FE0F","non_qualified":"1F46F-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f46f-200d-2640-fe0f.png","sheet_x":21,"sheet_y":27,"short_name":"woman-with-bunny-ears-partying","short_names":["woman-with-bunny-ears-partying"],"text":null,"texts":null,"category":"Smileys & People","sort_order":262,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoletes":"1F46F"},{"name":null,"unified":"1F46F-200D-2642-FE0F","non_qualified":"1F46F-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f46f-200d-2642-fe0f.png","sheet_x":21,"sheet_y":28,"short_name":"man-with-bunny-ears-partying","short_names":["man-with-bunny-ears-partying"],"text":null,"texts":null,"category":"Smileys & People","sort_order":261,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"WOMAN WITH BUNNY EARS","unified":"1F46F","non_qualified":null,"docomo":null,"au":"EADB","softbank":"E429","google":"FE1A2","image":"1f46f.png","sheet_x":21,"sheet_y":29,"short_name":"dancers","short_names":["dancers"],"text":null,"texts":null,"category":"Smileys & People","sort_order":260,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"obsoleted_by":"1F46F-200D-2640-FE0F"},{"name":"BRIDE WITH VEIL","unified":"1F470","non_qualified":null,"docomo":null,"au":"EAE9","softbank":null,"google":"FE1A3","image":"1f470.png","sheet_x":21,"sheet_y":30,"short_name":"bride_with_veil","short_names":["bride_with_veil"],"text":null,"texts":null,"category":"Smileys & People","sort_order":188,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F470-1F3FB","non_qualified":null,"image":"1f470-1f3fb.png","sheet_x":21,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F470-1F3FC","non_qualified":null,"image":"1f470-1f3fc.png","sheet_x":21,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F470-1F3FD","non_qualified":null,"image":"1f470-1f3fd.png","sheet_x":21,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F470-1F3FE","non_qualified":null,"image":"1f470-1f3fe.png","sheet_x":21,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F470-1F3FF","non_qualified":null,"image":"1f470-1f3ff.png","sheet_x":21,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"1F471-200D-2640-FE0F","non_qualified":"1F471-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f471-200d-2640-fe0f.png","sheet_x":21,"sheet_y":36,"short_name":"blond-haired-woman","short_names":["blond-haired-woman"],"text":null,"texts":null,"category":"Smileys & People","sort_order":178,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F471-1F3FB-200D-2640-FE0F","non_qualified":"1F471-1F3FB-200D-2640","image":"1f471-1f3fb-200d-2640-fe0f.png","sheet_x":21,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F471-1F3FC-200D-2640-FE0F","non_qualified":"1F471-1F3FC-200D-2640","image":"1f471-1f3fc-200d-2640-fe0f.png","sheet_x":21,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F471-1F3FD-200D-2640-FE0F","non_qualified":"1F471-1F3FD-200D-2640","image":"1f471-1f3fd-200d-2640-fe0f.png","sheet_x":21,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F471-1F3FE-200D-2640-FE0F","non_qualified":"1F471-1F3FE-200D-2640","image":"1f471-1f3fe-200d-2640-fe0f.png","sheet_x":21,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F471-1F3FF-200D-2640-FE0F","non_qualified":"1F471-1F3FF-200D-2640","image":"1f471-1f3ff-200d-2640-fe0f.png","sheet_x":21,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F471-200D-2642-FE0F","non_qualified":"1F471-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f471-200d-2642-fe0f.png","sheet_x":21,"sheet_y":42,"short_name":"blond-haired-man","short_names":["blond-haired-man"],"text":null,"texts":null,"category":"Smileys & People","sort_order":177,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F471-1F3FB-200D-2642-FE0F","non_qualified":"1F471-1F3FB-200D-2642","image":"1f471-1f3fb-200d-2642-fe0f.png","sheet_x":21,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F471-1F3FC-200D-2642-FE0F","non_qualified":"1F471-1F3FC-200D-2642","image":"1f471-1f3fc-200d-2642-fe0f.png","sheet_x":21,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F471-1F3FD-200D-2642-FE0F","non_qualified":"1F471-1F3FD-200D-2642","image":"1f471-1f3fd-200d-2642-fe0f.png","sheet_x":21,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F471-1F3FE-200D-2642-FE0F","non_qualified":"1F471-1F3FE-200D-2642","image":"1f471-1f3fe-200d-2642-fe0f.png","sheet_x":21,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F471-1F3FF-200D-2642-FE0F","non_qualified":"1F471-1F3FF-200D-2642","image":"1f471-1f3ff-200d-2642-fe0f.png","sheet_x":21,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F471"},{"name":"PERSON WITH BLOND HAIR","unified":"1F471","non_qualified":null,"docomo":null,"au":"EB13","softbank":"E515","google":"FE1A4","image":"1f471.png","sheet_x":21,"sheet_y":48,"short_name":"person_with_blond_hair","short_names":["person_with_blond_hair"],"text":null,"texts":null,"category":"Smileys & People","sort_order":176,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F471-1F3FB","non_qualified":null,"image":"1f471-1f3fb.png","sheet_x":21,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F471-1F3FC","non_qualified":null,"image":"1f471-1f3fc.png","sheet_x":21,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F471-1F3FD","non_qualified":null,"image":"1f471-1f3fd.png","sheet_x":21,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F471-1F3FE","non_qualified":null,"image":"1f471-1f3fe.png","sheet_x":21,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F471-1F3FF","non_qualified":null,"image":"1f471-1f3ff.png","sheet_x":22,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F471-200D-2642-FE0F"},{"name":"MAN WITH GUA PI MAO","unified":"1F472","non_qualified":null,"docomo":null,"au":"EB14","softbank":"E516","google":"FE1A5","image":"1f472.png","sheet_x":22,"sheet_y":1,"short_name":"man_with_gua_pi_mao","short_names":["man_with_gua_pi_mao"],"text":null,"texts":null,"category":"Smileys & People","sort_order":173,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F472-1F3FB","non_qualified":null,"image":"1f472-1f3fb.png","sheet_x":22,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F472-1F3FC","non_qualified":null,"image":"1f472-1f3fc.png","sheet_x":22,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F472-1F3FD","non_qualified":null,"image":"1f472-1f3fd.png","sheet_x":22,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F472-1F3FE","non_qualified":null,"image":"1f472-1f3fe.png","sheet_x":22,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F472-1F3FF","non_qualified":null,"image":"1f472-1f3ff.png","sheet_x":22,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"1F473-200D-2640-FE0F","non_qualified":"1F473-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f473-200d-2640-fe0f.png","sheet_x":22,"sheet_y":7,"short_name":"woman-wearing-turban","short_names":["woman-wearing-turban"],"text":null,"texts":null,"category":"Smileys & People","sort_order":172,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F473-1F3FB-200D-2640-FE0F","non_qualified":"1F473-1F3FB-200D-2640","image":"1f473-1f3fb-200d-2640-fe0f.png","sheet_x":22,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F473-1F3FC-200D-2640-FE0F","non_qualified":"1F473-1F3FC-200D-2640","image":"1f473-1f3fc-200d-2640-fe0f.png","sheet_x":22,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F473-1F3FD-200D-2640-FE0F","non_qualified":"1F473-1F3FD-200D-2640","image":"1f473-1f3fd-200d-2640-fe0f.png","sheet_x":22,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F473-1F3FE-200D-2640-FE0F","non_qualified":"1F473-1F3FE-200D-2640","image":"1f473-1f3fe-200d-2640-fe0f.png","sheet_x":22,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F473-1F3FF-200D-2640-FE0F","non_qualified":"1F473-1F3FF-200D-2640","image":"1f473-1f3ff-200d-2640-fe0f.png","sheet_x":22,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F473-200D-2642-FE0F","non_qualified":"1F473-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f473-200d-2642-fe0f.png","sheet_x":22,"sheet_y":13,"short_name":"man-wearing-turban","short_names":["man-wearing-turban"],"text":null,"texts":null,"category":"Smileys & People","sort_order":171,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F473-1F3FB-200D-2642-FE0F","non_qualified":"1F473-1F3FB-200D-2642","image":"1f473-1f3fb-200d-2642-fe0f.png","sheet_x":22,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F473-1F3FC-200D-2642-FE0F","non_qualified":"1F473-1F3FC-200D-2642","image":"1f473-1f3fc-200d-2642-fe0f.png","sheet_x":22,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F473-1F3FD-200D-2642-FE0F","non_qualified":"1F473-1F3FD-200D-2642","image":"1f473-1f3fd-200d-2642-fe0f.png","sheet_x":22,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F473-1F3FE-200D-2642-FE0F","non_qualified":"1F473-1F3FE-200D-2642","image":"1f473-1f3fe-200d-2642-fe0f.png","sheet_x":22,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F473-1F3FF-200D-2642-FE0F","non_qualified":"1F473-1F3FF-200D-2642","image":"1f473-1f3ff-200d-2642-fe0f.png","sheet_x":22,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F473"},{"name":"MAN WITH TURBAN","unified":"1F473","non_qualified":null,"docomo":null,"au":"EB15","softbank":"E517","google":"FE1A6","image":"1f473.png","sheet_x":22,"sheet_y":19,"short_name":"man_with_turban","short_names":["man_with_turban"],"text":null,"texts":null,"category":"Smileys & People","sort_order":170,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F473-1F3FB","non_qualified":null,"image":"1f473-1f3fb.png","sheet_x":22,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F473-1F3FC","non_qualified":null,"image":"1f473-1f3fc.png","sheet_x":22,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F473-1F3FD","non_qualified":null,"image":"1f473-1f3fd.png","sheet_x":22,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F473-1F3FE","non_qualified":null,"image":"1f473-1f3fe.png","sheet_x":22,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F473-1F3FF","non_qualified":null,"image":"1f473-1f3ff.png","sheet_x":22,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F473-200D-2642-FE0F"},{"name":"OLDER MAN","unified":"1F474","non_qualified":null,"docomo":null,"au":"EB16","softbank":"E518","google":"FE1A7","image":"1f474.png","sheet_x":22,"sheet_y":25,"short_name":"older_man","short_names":["older_man"],"text":null,"texts":null,"category":"Smileys & People","sort_order":122,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F474-1F3FB","non_qualified":null,"image":"1f474-1f3fb.png","sheet_x":22,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F474-1F3FC","non_qualified":null,"image":"1f474-1f3fc.png","sheet_x":22,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F474-1F3FD","non_qualified":null,"image":"1f474-1f3fd.png","sheet_x":22,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F474-1F3FE","non_qualified":null,"image":"1f474-1f3fe.png","sheet_x":22,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F474-1F3FF","non_qualified":null,"image":"1f474-1f3ff.png","sheet_x":22,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"OLDER WOMAN","unified":"1F475","non_qualified":null,"docomo":null,"au":"EB17","softbank":"E519","google":"FE1A8","image":"1f475.png","sheet_x":22,"sheet_y":31,"short_name":"older_woman","short_names":["older_woman"],"text":null,"texts":null,"category":"Smileys & People","sort_order":123,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F475-1F3FB","non_qualified":null,"image":"1f475-1f3fb.png","sheet_x":22,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F475-1F3FC","non_qualified":null,"image":"1f475-1f3fc.png","sheet_x":22,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F475-1F3FD","non_qualified":null,"image":"1f475-1f3fd.png","sheet_x":22,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F475-1F3FE","non_qualified":null,"image":"1f475-1f3fe.png","sheet_x":22,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F475-1F3FF","non_qualified":null,"image":"1f475-1f3ff.png","sheet_x":22,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"BABY","unified":"1F476","non_qualified":null,"docomo":null,"au":"EB18","softbank":"E51A","google":"FE1A9","image":"1f476.png","sheet_x":22,"sheet_y":37,"short_name":"baby","short_names":["baby"],"text":null,"texts":null,"category":"Smileys & People","sort_order":114,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F476-1F3FB","non_qualified":null,"image":"1f476-1f3fb.png","sheet_x":22,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F476-1F3FC","non_qualified":null,"image":"1f476-1f3fc.png","sheet_x":22,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F476-1F3FD","non_qualified":null,"image":"1f476-1f3fd.png","sheet_x":22,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F476-1F3FE","non_qualified":null,"image":"1f476-1f3fe.png","sheet_x":22,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F476-1F3FF","non_qualified":null,"image":"1f476-1f3ff.png","sheet_x":22,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"1F477-200D-2640-FE0F","non_qualified":"1F477-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f477-200d-2640-fe0f.png","sheet_x":22,"sheet_y":43,"short_name":"female-construction-worker","short_names":["female-construction-worker"],"text":null,"texts":null,"category":"Smileys & People","sort_order":167,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F477-1F3FB-200D-2640-FE0F","non_qualified":"1F477-1F3FB-200D-2640","image":"1f477-1f3fb-200d-2640-fe0f.png","sheet_x":22,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F477-1F3FC-200D-2640-FE0F","non_qualified":"1F477-1F3FC-200D-2640","image":"1f477-1f3fc-200d-2640-fe0f.png","sheet_x":22,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F477-1F3FD-200D-2640-FE0F","non_qualified":"1F477-1F3FD-200D-2640","image":"1f477-1f3fd-200d-2640-fe0f.png","sheet_x":22,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F477-1F3FE-200D-2640-FE0F","non_qualified":"1F477-1F3FE-200D-2640","image":"1f477-1f3fe-200d-2640-fe0f.png","sheet_x":22,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F477-1F3FF-200D-2640-FE0F","non_qualified":"1F477-1F3FF-200D-2640","image":"1f477-1f3ff-200d-2640-fe0f.png","sheet_x":22,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F477-200D-2642-FE0F","non_qualified":"1F477-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f477-200d-2642-fe0f.png","sheet_x":22,"sheet_y":49,"short_name":"male-construction-worker","short_names":["male-construction-worker"],"text":null,"texts":null,"category":"Smileys & People","sort_order":166,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F477-1F3FB-200D-2642-FE0F","non_qualified":"1F477-1F3FB-200D-2642","image":"1f477-1f3fb-200d-2642-fe0f.png","sheet_x":22,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F477-1F3FC-200D-2642-FE0F","non_qualified":"1F477-1F3FC-200D-2642","image":"1f477-1f3fc-200d-2642-fe0f.png","sheet_x":22,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F477-1F3FD-200D-2642-FE0F","non_qualified":"1F477-1F3FD-200D-2642","image":"1f477-1f3fd-200d-2642-fe0f.png","sheet_x":22,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F477-1F3FE-200D-2642-FE0F","non_qualified":"1F477-1F3FE-200D-2642","image":"1f477-1f3fe-200d-2642-fe0f.png","sheet_x":23,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F477-1F3FF-200D-2642-FE0F","non_qualified":"1F477-1F3FF-200D-2642","image":"1f477-1f3ff-200d-2642-fe0f.png","sheet_x":23,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F477"},{"name":"CONSTRUCTION WORKER","unified":"1F477","non_qualified":null,"docomo":null,"au":"EB19","softbank":"E51B","google":"FE1AA","image":"1f477.png","sheet_x":23,"sheet_y":2,"short_name":"construction_worker","short_names":["construction_worker"],"text":null,"texts":null,"category":"Smileys & People","sort_order":165,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F477-1F3FB","non_qualified":null,"image":"1f477-1f3fb.png","sheet_x":23,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F477-1F3FC","non_qualified":null,"image":"1f477-1f3fc.png","sheet_x":23,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F477-1F3FD","non_qualified":null,"image":"1f477-1f3fd.png","sheet_x":23,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F477-1F3FE","non_qualified":null,"image":"1f477-1f3fe.png","sheet_x":23,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F477-1F3FF","non_qualified":null,"image":"1f477-1f3ff.png","sheet_x":23,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F477-200D-2642-FE0F"},{"name":"PRINCESS","unified":"1F478","non_qualified":null,"docomo":null,"au":"EB1A","softbank":"E51C","google":"FE1AB","image":"1f478.png","sheet_x":23,"sheet_y":8,"short_name":"princess","short_names":["princess"],"text":null,"texts":null,"category":"Smileys & People","sort_order":169,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F478-1F3FB","non_qualified":null,"image":"1f478-1f3fb.png","sheet_x":23,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F478-1F3FC","non_qualified":null,"image":"1f478-1f3fc.png","sheet_x":23,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F478-1F3FD","non_qualified":null,"image":"1f478-1f3fd.png","sheet_x":23,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F478-1F3FE","non_qualified":null,"image":"1f478-1f3fe.png","sheet_x":23,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F478-1F3FF","non_qualified":null,"image":"1f478-1f3ff.png","sheet_x":23,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"JAPANESE OGRE","unified":"1F479","non_qualified":null,"docomo":null,"au":"EB44","softbank":null,"google":"FE1AC","image":"1f479.png","sheet_x":23,"sheet_y":14,"short_name":"japanese_ogre","short_names":["japanese_ogre"],"text":null,"texts":null,"category":"Smileys & People","sort_order":93,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"JAPANESE GOBLIN","unified":"1F47A","non_qualified":null,"docomo":null,"au":"EB45","softbank":null,"google":"FE1AD","image":"1f47a.png","sheet_x":23,"sheet_y":15,"short_name":"japanese_goblin","short_names":["japanese_goblin"],"text":null,"texts":null,"category":"Smileys & People","sort_order":94,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GHOST","unified":"1F47B","non_qualified":null,"docomo":null,"au":"E4CB","softbank":"E11B","google":"FE1AE","image":"1f47b.png","sheet_x":23,"sheet_y":16,"short_name":"ghost","short_names":["ghost"],"text":null,"texts":null,"category":"Smileys & People","sort_order":97,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BABY ANGEL","unified":"1F47C","non_qualified":null,"docomo":null,"au":"E5BF","softbank":"E04E","google":"FE1AF","image":"1f47c.png","sheet_x":23,"sheet_y":17,"short_name":"angel","short_names":["angel"],"text":null,"texts":null,"category":"Smileys & People","sort_order":191,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F47C-1F3FB","non_qualified":null,"image":"1f47c-1f3fb.png","sheet_x":23,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F47C-1F3FC","non_qualified":null,"image":"1f47c-1f3fc.png","sheet_x":23,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F47C-1F3FD","non_qualified":null,"image":"1f47c-1f3fd.png","sheet_x":23,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F47C-1F3FE","non_qualified":null,"image":"1f47c-1f3fe.png","sheet_x":23,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F47C-1F3FF","non_qualified":null,"image":"1f47c-1f3ff.png","sheet_x":23,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"EXTRATERRESTRIAL ALIEN","unified":"1F47D","non_qualified":null,"docomo":null,"au":"E50E","softbank":"E10C","google":"FE1B0","image":"1f47d.png","sheet_x":23,"sheet_y":23,"short_name":"alien","short_names":["alien"],"text":null,"texts":null,"category":"Smileys & People","sort_order":98,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ALIEN MONSTER","unified":"1F47E","non_qualified":null,"docomo":null,"au":"E4EC","softbank":"E12B","google":"FE1B1","image":"1f47e.png","sheet_x":23,"sheet_y":24,"short_name":"space_invader","short_names":["space_invader"],"text":null,"texts":null,"category":"Smileys & People","sort_order":99,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"IMP","unified":"1F47F","non_qualified":null,"docomo":null,"au":"E4EF","softbank":"E11A","google":"FE1B2","image":"1f47f.png","sheet_x":23,"sheet_y":25,"short_name":"imp","short_names":["imp"],"text":null,"texts":null,"category":"Smileys & People","sort_order":91,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SKULL","unified":"1F480","non_qualified":null,"docomo":null,"au":"E4F8","softbank":"E11C","google":"FE1B3","image":"1f480.png","sheet_x":23,"sheet_y":26,"short_name":"skull","short_names":["skull"],"text":null,"texts":null,"category":"Smileys & People","sort_order":95,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F481-200D-2640-FE0F","non_qualified":"1F481-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f481-200d-2640-fe0f.png","sheet_x":23,"sheet_y":27,"short_name":"woman-tipping-hand","short_names":["woman-tipping-hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":233,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F481-1F3FB-200D-2640-FE0F","non_qualified":"1F481-1F3FB-200D-2640","image":"1f481-1f3fb-200d-2640-fe0f.png","sheet_x":23,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F481-1F3FC-200D-2640-FE0F","non_qualified":"1F481-1F3FC-200D-2640","image":"1f481-1f3fc-200d-2640-fe0f.png","sheet_x":23,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F481-1F3FD-200D-2640-FE0F","non_qualified":"1F481-1F3FD-200D-2640","image":"1f481-1f3fd-200d-2640-fe0f.png","sheet_x":23,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F481-1F3FE-200D-2640-FE0F","non_qualified":"1F481-1F3FE-200D-2640","image":"1f481-1f3fe-200d-2640-fe0f.png","sheet_x":23,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F481-1F3FF-200D-2640-FE0F","non_qualified":"1F481-1F3FF-200D-2640","image":"1f481-1f3ff-200d-2640-fe0f.png","sheet_x":23,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F481"},{"name":null,"unified":"1F481-200D-2642-FE0F","non_qualified":"1F481-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f481-200d-2642-fe0f.png","sheet_x":23,"sheet_y":33,"short_name":"man-tipping-hand","short_names":["man-tipping-hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":232,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F481-1F3FB-200D-2642-FE0F","non_qualified":"1F481-1F3FB-200D-2642","image":"1f481-1f3fb-200d-2642-fe0f.png","sheet_x":23,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F481-1F3FC-200D-2642-FE0F","non_qualified":"1F481-1F3FC-200D-2642","image":"1f481-1f3fc-200d-2642-fe0f.png","sheet_x":23,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F481-1F3FD-200D-2642-FE0F","non_qualified":"1F481-1F3FD-200D-2642","image":"1f481-1f3fd-200d-2642-fe0f.png","sheet_x":23,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F481-1F3FE-200D-2642-FE0F","non_qualified":"1F481-1F3FE-200D-2642","image":"1f481-1f3fe-200d-2642-fe0f.png","sheet_x":23,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F481-1F3FF-200D-2642-FE0F","non_qualified":"1F481-1F3FF-200D-2642","image":"1f481-1f3ff-200d-2642-fe0f.png","sheet_x":23,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"INFORMATION DESK PERSON","unified":"1F481","non_qualified":null,"docomo":null,"au":null,"softbank":"E253","google":"FE1B4","image":"1f481.png","sheet_x":23,"sheet_y":39,"short_name":"information_desk_person","short_names":["information_desk_person"],"text":null,"texts":null,"category":"Smileys & People","sort_order":231,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F481-1F3FB","non_qualified":null,"image":"1f481-1f3fb.png","sheet_x":23,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F481-1F3FC","non_qualified":null,"image":"1f481-1f3fc.png","sheet_x":23,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F481-1F3FD","non_qualified":null,"image":"1f481-1f3fd.png","sheet_x":23,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F481-1F3FE","non_qualified":null,"image":"1f481-1f3fe.png","sheet_x":23,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F481-1F3FF","non_qualified":null,"image":"1f481-1f3ff.png","sheet_x":23,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F481-200D-2640-FE0F"},{"name":null,"unified":"1F482-200D-2640-FE0F","non_qualified":"1F482-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f482-200d-2640-fe0f.png","sheet_x":23,"sheet_y":45,"short_name":"female-guard","short_names":["female-guard"],"text":null,"texts":null,"category":"Smileys & People","sort_order":164,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F482-1F3FB-200D-2640-FE0F","non_qualified":"1F482-1F3FB-200D-2640","image":"1f482-1f3fb-200d-2640-fe0f.png","sheet_x":23,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F482-1F3FC-200D-2640-FE0F","non_qualified":"1F482-1F3FC-200D-2640","image":"1f482-1f3fc-200d-2640-fe0f.png","sheet_x":23,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F482-1F3FD-200D-2640-FE0F","non_qualified":"1F482-1F3FD-200D-2640","image":"1f482-1f3fd-200d-2640-fe0f.png","sheet_x":23,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F482-1F3FE-200D-2640-FE0F","non_qualified":"1F482-1F3FE-200D-2640","image":"1f482-1f3fe-200d-2640-fe0f.png","sheet_x":23,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F482-1F3FF-200D-2640-FE0F","non_qualified":"1F482-1F3FF-200D-2640","image":"1f482-1f3ff-200d-2640-fe0f.png","sheet_x":23,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F482-200D-2642-FE0F","non_qualified":"1F482-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f482-200d-2642-fe0f.png","sheet_x":23,"sheet_y":51,"short_name":"male-guard","short_names":["male-guard"],"text":null,"texts":null,"category":"Smileys & People","sort_order":163,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F482-1F3FB-200D-2642-FE0F","non_qualified":"1F482-1F3FB-200D-2642","image":"1f482-1f3fb-200d-2642-fe0f.png","sheet_x":23,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F482-1F3FC-200D-2642-FE0F","non_qualified":"1F482-1F3FC-200D-2642","image":"1f482-1f3fc-200d-2642-fe0f.png","sheet_x":24,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F482-1F3FD-200D-2642-FE0F","non_qualified":"1F482-1F3FD-200D-2642","image":"1f482-1f3fd-200d-2642-fe0f.png","sheet_x":24,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F482-1F3FE-200D-2642-FE0F","non_qualified":"1F482-1F3FE-200D-2642","image":"1f482-1f3fe-200d-2642-fe0f.png","sheet_x":24,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F482-1F3FF-200D-2642-FE0F","non_qualified":"1F482-1F3FF-200D-2642","image":"1f482-1f3ff-200d-2642-fe0f.png","sheet_x":24,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F482"},{"name":"GUARDSMAN","unified":"1F482","non_qualified":null,"docomo":null,"au":null,"softbank":"E51E","google":"FE1B5","image":"1f482.png","sheet_x":24,"sheet_y":4,"short_name":"guardsman","short_names":["guardsman"],"text":null,"texts":null,"category":"Smileys & People","sort_order":162,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F482-1F3FB","non_qualified":null,"image":"1f482-1f3fb.png","sheet_x":24,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F482-1F3FC","non_qualified":null,"image":"1f482-1f3fc.png","sheet_x":24,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F482-1F3FD","non_qualified":null,"image":"1f482-1f3fd.png","sheet_x":24,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F482-1F3FE","non_qualified":null,"image":"1f482-1f3fe.png","sheet_x":24,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F482-1F3FF","non_qualified":null,"image":"1f482-1f3ff.png","sheet_x":24,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F482-200D-2642-FE0F"},{"name":"DANCER","unified":"1F483","non_qualified":null,"docomo":null,"au":"EB1C","softbank":"E51F","google":"FE1B6","image":"1f483.png","sheet_x":24,"sheet_y":10,"short_name":"dancer","short_names":["dancer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":258,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F483-1F3FB","non_qualified":null,"image":"1f483-1f3fb.png","sheet_x":24,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F483-1F3FC","non_qualified":null,"image":"1f483-1f3fc.png","sheet_x":24,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F483-1F3FD","non_qualified":null,"image":"1f483-1f3fd.png","sheet_x":24,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F483-1F3FE","non_qualified":null,"image":"1f483-1f3fe.png","sheet_x":24,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F483-1F3FF","non_qualified":null,"image":"1f483-1f3ff.png","sheet_x":24,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"LIPSTICK","unified":"1F484","non_qualified":null,"docomo":"E710","au":"E509","softbank":"E31C","google":"FE195","image":"1f484.png","sheet_x":24,"sheet_y":16,"short_name":"lipstick","short_names":["lipstick"],"text":null,"texts":null,"category":"Smileys & People","sort_order":471,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NAIL POLISH","unified":"1F485","non_qualified":null,"docomo":null,"au":"EAA0","softbank":"E31D","google":"FE196","image":"1f485.png","sheet_x":24,"sheet_y":17,"short_name":"nail_care","short_names":["nail_care"],"text":null,"texts":null,"category":"Smileys & People","sort_order":394,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F485-1F3FB","non_qualified":null,"image":"1f485-1f3fb.png","sheet_x":24,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F485-1F3FC","non_qualified":null,"image":"1f485-1f3fc.png","sheet_x":24,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F485-1F3FD","non_qualified":null,"image":"1f485-1f3fd.png","sheet_x":24,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F485-1F3FE","non_qualified":null,"image":"1f485-1f3fe.png","sheet_x":24,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F485-1F3FF","non_qualified":null,"image":"1f485-1f3ff.png","sheet_x":24,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"1F486-200D-2640-FE0F","non_qualified":"1F486-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f486-200d-2640-fe0f.png","sheet_x":24,"sheet_y":23,"short_name":"woman-getting-massage","short_names":["woman-getting-massage"],"text":null,"texts":null,"category":"Smileys & People","sort_order":248,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F486-1F3FB-200D-2640-FE0F","non_qualified":"1F486-1F3FB-200D-2640","image":"1f486-1f3fb-200d-2640-fe0f.png","sheet_x":24,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F486-1F3FC-200D-2640-FE0F","non_qualified":"1F486-1F3FC-200D-2640","image":"1f486-1f3fc-200d-2640-fe0f.png","sheet_x":24,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F486-1F3FD-200D-2640-FE0F","non_qualified":"1F486-1F3FD-200D-2640","image":"1f486-1f3fd-200d-2640-fe0f.png","sheet_x":24,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F486-1F3FE-200D-2640-FE0F","non_qualified":"1F486-1F3FE-200D-2640","image":"1f486-1f3fe-200d-2640-fe0f.png","sheet_x":24,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F486-1F3FF-200D-2640-FE0F","non_qualified":"1F486-1F3FF-200D-2640","image":"1f486-1f3ff-200d-2640-fe0f.png","sheet_x":24,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F486"},{"name":null,"unified":"1F486-200D-2642-FE0F","non_qualified":"1F486-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f486-200d-2642-fe0f.png","sheet_x":24,"sheet_y":29,"short_name":"man-getting-massage","short_names":["man-getting-massage"],"text":null,"texts":null,"category":"Smileys & People","sort_order":247,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F486-1F3FB-200D-2642-FE0F","non_qualified":"1F486-1F3FB-200D-2642","image":"1f486-1f3fb-200d-2642-fe0f.png","sheet_x":24,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F486-1F3FC-200D-2642-FE0F","non_qualified":"1F486-1F3FC-200D-2642","image":"1f486-1f3fc-200d-2642-fe0f.png","sheet_x":24,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F486-1F3FD-200D-2642-FE0F","non_qualified":"1F486-1F3FD-200D-2642","image":"1f486-1f3fd-200d-2642-fe0f.png","sheet_x":24,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F486-1F3FE-200D-2642-FE0F","non_qualified":"1F486-1F3FE-200D-2642","image":"1f486-1f3fe-200d-2642-fe0f.png","sheet_x":24,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F486-1F3FF-200D-2642-FE0F","non_qualified":"1F486-1F3FF-200D-2642","image":"1f486-1f3ff-200d-2642-fe0f.png","sheet_x":24,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"FACE MASSAGE","unified":"1F486","non_qualified":null,"docomo":null,"au":"E50B","softbank":"E31E","google":"FE197","image":"1f486.png","sheet_x":24,"sheet_y":35,"short_name":"massage","short_names":["massage"],"text":null,"texts":null,"category":"Smileys & People","sort_order":246,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F486-1F3FB","non_qualified":null,"image":"1f486-1f3fb.png","sheet_x":24,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F486-1F3FC","non_qualified":null,"image":"1f486-1f3fc.png","sheet_x":24,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F486-1F3FD","non_qualified":null,"image":"1f486-1f3fd.png","sheet_x":24,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F486-1F3FE","non_qualified":null,"image":"1f486-1f3fe.png","sheet_x":24,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F486-1F3FF","non_qualified":null,"image":"1f486-1f3ff.png","sheet_x":24,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F486-200D-2640-FE0F"},{"name":null,"unified":"1F487-200D-2640-FE0F","non_qualified":"1F487-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f487-200d-2640-fe0f.png","sheet_x":24,"sheet_y":41,"short_name":"woman-getting-haircut","short_names":["woman-getting-haircut"],"text":null,"texts":null,"category":"Smileys & People","sort_order":251,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F487-1F3FB-200D-2640-FE0F","non_qualified":"1F487-1F3FB-200D-2640","image":"1f487-1f3fb-200d-2640-fe0f.png","sheet_x":24,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F487-1F3FC-200D-2640-FE0F","non_qualified":"1F487-1F3FC-200D-2640","image":"1f487-1f3fc-200d-2640-fe0f.png","sheet_x":24,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F487-1F3FD-200D-2640-FE0F","non_qualified":"1F487-1F3FD-200D-2640","image":"1f487-1f3fd-200d-2640-fe0f.png","sheet_x":24,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F487-1F3FE-200D-2640-FE0F","non_qualified":"1F487-1F3FE-200D-2640","image":"1f487-1f3fe-200d-2640-fe0f.png","sheet_x":24,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F487-1F3FF-200D-2640-FE0F","non_qualified":"1F487-1F3FF-200D-2640","image":"1f487-1f3ff-200d-2640-fe0f.png","sheet_x":24,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F487"},{"name":null,"unified":"1F487-200D-2642-FE0F","non_qualified":"1F487-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f487-200d-2642-fe0f.png","sheet_x":24,"sheet_y":47,"short_name":"man-getting-haircut","short_names":["man-getting-haircut"],"text":null,"texts":null,"category":"Smileys & People","sort_order":250,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F487-1F3FB-200D-2642-FE0F","non_qualified":"1F487-1F3FB-200D-2642","image":"1f487-1f3fb-200d-2642-fe0f.png","sheet_x":24,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F487-1F3FC-200D-2642-FE0F","non_qualified":"1F487-1F3FC-200D-2642","image":"1f487-1f3fc-200d-2642-fe0f.png","sheet_x":24,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F487-1F3FD-200D-2642-FE0F","non_qualified":"1F487-1F3FD-200D-2642","image":"1f487-1f3fd-200d-2642-fe0f.png","sheet_x":24,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F487-1F3FE-200D-2642-FE0F","non_qualified":"1F487-1F3FE-200D-2642","image":"1f487-1f3fe-200d-2642-fe0f.png","sheet_x":24,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F487-1F3FF-200D-2642-FE0F","non_qualified":"1F487-1F3FF-200D-2642","image":"1f487-1f3ff-200d-2642-fe0f.png","sheet_x":24,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"HAIRCUT","unified":"1F487","non_qualified":null,"docomo":"E675","au":"EAA1","softbank":"E31F","google":"FE198","image":"1f487.png","sheet_x":25,"sheet_y":0,"short_name":"haircut","short_names":["haircut"],"text":null,"texts":null,"category":"Smileys & People","sort_order":249,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F487-1F3FB","non_qualified":null,"image":"1f487-1f3fb.png","sheet_x":25,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F487-1F3FC","non_qualified":null,"image":"1f487-1f3fc.png","sheet_x":25,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F487-1F3FD","non_qualified":null,"image":"1f487-1f3fd.png","sheet_x":25,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F487-1F3FE","non_qualified":null,"image":"1f487-1f3fe.png","sheet_x":25,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F487-1F3FF","non_qualified":null,"image":"1f487-1f3ff.png","sheet_x":25,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F487-200D-2640-FE0F"},{"name":"BARBER POLE","unified":"1F488","non_qualified":null,"docomo":null,"au":"EAA2","softbank":"E320","google":"FE199","image":"1f488.png","sheet_x":25,"sheet_y":6,"short_name":"barber","short_names":["barber"],"text":null,"texts":null,"category":"Travel & Places","sort_order":61,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SYRINGE","unified":"1F489","non_qualified":null,"docomo":null,"au":"E510","softbank":"E13B","google":"FE509","image":"1f489.png","sheet_x":25,"sheet_y":7,"short_name":"syringe","short_names":["syringe"],"text":null,"texts":null,"category":"Objects","sort_order":161,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PILL","unified":"1F48A","non_qualified":null,"docomo":null,"au":"EA9A","softbank":"E30F","google":"FE50A","image":"1f48a.png","sheet_x":25,"sheet_y":8,"short_name":"pill","short_names":["pill"],"text":null,"texts":null,"category":"Objects","sort_order":162,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KISS MARK","unified":"1F48B","non_qualified":null,"docomo":"E6F9","au":"E4EB","softbank":"E003","google":"FE823","image":"1f48b.png","sheet_x":25,"sheet_y":9,"short_name":"kiss","short_names":["kiss"],"text":null,"texts":null,"category":"Smileys & People","sort_order":406,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LOVE LETTER","unified":"1F48C","non_qualified":null,"docomo":"E717","au":"EB78","softbank":null,"google":"FE824","image":"1f48c.png","sheet_x":25,"sheet_y":10,"short_name":"love_letter","short_names":["love_letter"],"text":null,"texts":null,"category":"Smileys & People","sort_order":424,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RING","unified":"1F48D","non_qualified":null,"docomo":"E71B","au":"E514","softbank":"E034","google":"FE825","image":"1f48d.png","sheet_x":25,"sheet_y":11,"short_name":"ring","short_names":["ring"],"text":null,"texts":null,"category":"Smileys & People","sort_order":472,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GEM STONE","unified":"1F48E","non_qualified":null,"docomo":"E71B","au":"E514","softbank":"E035","google":"FE826","image":"1f48e.png","sheet_x":25,"sheet_y":12,"short_name":"gem","short_names":["gem"],"text":null,"texts":null,"category":"Smileys & People","sort_order":473,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KISS","unified":"1F48F","non_qualified":null,"docomo":"E6F9","au":"E5CA","softbank":"E111","google":"FE827","image":"1f48f.png","sheet_x":25,"sheet_y":13,"short_name":"couplekiss","short_names":["couplekiss"],"text":null,"texts":null,"category":"Smileys & People","sort_order":326,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"obsoleted_by":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F468"},{"name":"BOUQUET","unified":"1F490","non_qualified":null,"docomo":null,"au":"EA95","softbank":"E306","google":"FE828","image":"1f490.png","sheet_x":25,"sheet_y":14,"short_name":"bouquet","short_names":["bouquet"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":103,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"COUPLE WITH HEART","unified":"1F491","non_qualified":null,"docomo":"E6ED","au":"EADA","softbank":"E425","google":"FE829","image":"1f491.png","sheet_x":25,"sheet_y":15,"short_name":"couple_with_heart","short_names":["couple_with_heart"],"text":null,"texts":null,"category":"Smileys & People","sort_order":330,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"obsoleted_by":"1F469-200D-2764-FE0F-200D-1F468"},{"name":"WEDDING","unified":"1F492","non_qualified":null,"docomo":null,"au":"E5BB","softbank":"E43D","google":"FE82A","image":"1f492.png","sheet_x":25,"sheet_y":16,"short_name":"wedding","short_names":["wedding"],"text":null,"texts":null,"category":"Travel & Places","sort_order":38,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BEATING HEART","unified":"1F493","non_qualified":null,"docomo":"E6ED","au":"EB75","softbank":"E327","google":"FEB0D","image":"1f493.png","sheet_x":25,"sheet_y":17,"short_name":"heartbeat","short_names":["heartbeat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":409,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BROKEN HEART","unified":"1F494","non_qualified":null,"docomo":"E6EE","au":"E477","softbank":"E023","google":"FEB0E","image":"1f494.png","sheet_x":25,"sheet_y":18,"short_name":"broken_heart","short_names":["broken_heart"],"text":"<\/3","texts":["<\/3"],"category":"Smileys & People","sort_order":410,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TWO HEARTS","unified":"1F495","non_qualified":null,"docomo":"E6EF","au":"E478","softbank":null,"google":"FEB0F","image":"1f495.png","sheet_x":25,"sheet_y":19,"short_name":"two_hearts","short_names":["two_hearts"],"text":null,"texts":null,"category":"Smileys & People","sort_order":411,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPARKLING HEART","unified":"1F496","non_qualified":null,"docomo":"E6EC","au":"EAA6","softbank":null,"google":"FEB10","image":"1f496.png","sheet_x":25,"sheet_y":20,"short_name":"sparkling_heart","short_names":["sparkling_heart"],"text":null,"texts":null,"category":"Smileys & People","sort_order":412,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GROWING HEART","unified":"1F497","non_qualified":null,"docomo":"E6ED","au":"EB75","softbank":"E328","google":"FEB11","image":"1f497.png","sheet_x":25,"sheet_y":21,"short_name":"heartpulse","short_names":["heartpulse"],"text":null,"texts":null,"category":"Smileys & People","sort_order":413,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEART WITH ARROW","unified":"1F498","non_qualified":null,"docomo":"E6EC","au":"E4EA","softbank":"E329","google":"FEB12","image":"1f498.png","sheet_x":25,"sheet_y":22,"short_name":"cupid","short_names":["cupid"],"text":null,"texts":null,"category":"Smileys & People","sort_order":407,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLUE HEART","unified":"1F499","non_qualified":null,"docomo":"E6EC","au":"EAA7","softbank":"E32A","google":"FEB13","image":"1f499.png","sheet_x":25,"sheet_y":23,"short_name":"blue_heart","short_names":["blue_heart"],"text":"<3","texts":null,"category":"Smileys & People","sort_order":414,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GREEN HEART","unified":"1F49A","non_qualified":null,"docomo":"E6EC","au":"EAA8","softbank":"E32B","google":"FEB14","image":"1f49a.png","sheet_x":25,"sheet_y":24,"short_name":"green_heart","short_names":["green_heart"],"text":"<3","texts":null,"category":"Smileys & People","sort_order":415,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"YELLOW HEART","unified":"1F49B","non_qualified":null,"docomo":"E6EC","au":"EAA9","softbank":"E32C","google":"FEB15","image":"1f49b.png","sheet_x":25,"sheet_y":25,"short_name":"yellow_heart","short_names":["yellow_heart"],"text":"<3","texts":null,"category":"Smileys & People","sort_order":416,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PURPLE HEART","unified":"1F49C","non_qualified":null,"docomo":"E6EC","au":"EAAA","softbank":"E32D","google":"FEB16","image":"1f49c.png","sheet_x":25,"sheet_y":26,"short_name":"purple_heart","short_names":["purple_heart"],"text":"<3","texts":null,"category":"Smileys & People","sort_order":418,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEART WITH RIBBON","unified":"1F49D","non_qualified":null,"docomo":"E6EC","au":"EB54","softbank":"E437","google":"FEB17","image":"1f49d.png","sheet_x":25,"sheet_y":27,"short_name":"gift_heart","short_names":["gift_heart"],"text":null,"texts":null,"category":"Smileys & People","sort_order":420,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"REVOLVING HEARTS","unified":"1F49E","non_qualified":null,"docomo":"E6ED","au":"E5AF","softbank":null,"google":"FEB18","image":"1f49e.png","sheet_x":25,"sheet_y":28,"short_name":"revolving_hearts","short_names":["revolving_hearts"],"text":null,"texts":null,"category":"Smileys & People","sort_order":421,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEART DECORATION","unified":"1F49F","non_qualified":null,"docomo":"E6F8","au":"E595","softbank":"E204","google":"FEB19","image":"1f49f.png","sheet_x":25,"sheet_y":29,"short_name":"heart_decoration","short_names":["heart_decoration"],"text":null,"texts":null,"category":"Smileys & People","sort_order":422,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DIAMOND SHAPE WITH A DOT INSIDE","unified":"1F4A0","non_qualified":null,"docomo":"E6F8","au":null,"softbank":null,"google":"FEB55","image":"1f4a0.png","sheet_x":25,"sheet_y":30,"short_name":"diamond_shape_with_a_dot_inside","short_names":["diamond_shape_with_a_dot_inside"],"text":null,"texts":null,"category":"Symbols","sort_order":199,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ELECTRIC LIGHT BULB","unified":"1F4A1","non_qualified":null,"docomo":"E6FB","au":"E476","softbank":"E10F","google":"FEB56","image":"1f4a1.png","sheet_x":25,"sheet_y":31,"short_name":"bulb","short_names":["bulb"],"text":null,"texts":null,"category":"Objects","sort_order":56,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ANGER SYMBOL","unified":"1F4A2","non_qualified":null,"docomo":"E6FC","au":"E4E5","softbank":"E334","google":"FEB57","image":"1f4a2.png","sheet_x":25,"sheet_y":32,"short_name":"anger","short_names":["anger"],"text":null,"texts":null,"category":"Smileys & People","sort_order":426,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BOMB","unified":"1F4A3","non_qualified":null,"docomo":"E6FE","au":"E47A","softbank":"E311","google":"FEB58","image":"1f4a3.png","sheet_x":25,"sheet_y":33,"short_name":"bomb","short_names":["bomb"],"text":null,"texts":null,"category":"Smileys & People","sort_order":427,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SLEEPING SYMBOL","unified":"1F4A4","non_qualified":null,"docomo":"E701","au":"E475","softbank":"E13C","google":"FEB59","image":"1f4a4.png","sheet_x":25,"sheet_y":34,"short_name":"zzz","short_names":["zzz"],"text":null,"texts":null,"category":"Smileys & People","sort_order":425,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"COLLISION SYMBOL","unified":"1F4A5","non_qualified":null,"docomo":"E705","au":"E5B0","softbank":null,"google":"FEB5A","image":"1f4a5.png","sheet_x":25,"sheet_y":35,"short_name":"boom","short_names":["boom","collision"],"text":null,"texts":null,"category":"Smileys & People","sort_order":428,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPLASHING SWEAT SYMBOL","unified":"1F4A6","non_qualified":null,"docomo":"E706","au":"E5B1","softbank":"E331","google":"FEB5B","image":"1f4a6.png","sheet_x":25,"sheet_y":36,"short_name":"sweat_drops","short_names":["sweat_drops"],"text":null,"texts":null,"category":"Smileys & People","sort_order":429,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DROPLET","unified":"1F4A7","non_qualified":null,"docomo":"E707","au":"E4E6","softbank":null,"google":"FEB5C","image":"1f4a7.png","sheet_x":25,"sheet_y":37,"short_name":"droplet","short_names":["droplet"],"text":null,"texts":null,"category":"Travel & Places","sort_order":201,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DASH SYMBOL","unified":"1F4A8","non_qualified":null,"docomo":"E708","au":"E4F4","softbank":"E330","google":"FEB5D","image":"1f4a8.png","sheet_x":25,"sheet_y":38,"short_name":"dash","short_names":["dash"],"text":null,"texts":null,"category":"Smileys & People","sort_order":430,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PILE OF POO","unified":"1F4A9","non_qualified":null,"docomo":null,"au":"E4F5","softbank":"E05A","google":"FE4F4","image":"1f4a9.png","sheet_x":25,"sheet_y":39,"short_name":"hankey","short_names":["hankey","poop","shit"],"text":null,"texts":null,"category":"Smileys & People","sort_order":101,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FLEXED BICEPS","unified":"1F4AA","non_qualified":null,"docomo":null,"au":"E4E9","softbank":"E14C","google":"FEB5E","image":"1f4aa.png","sheet_x":25,"sheet_y":40,"short_name":"muscle","short_names":["muscle"],"text":null,"texts":null,"category":"Smileys & People","sort_order":361,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F4AA-1F3FB","non_qualified":null,"image":"1f4aa-1f3fb.png","sheet_x":25,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F4AA-1F3FC","non_qualified":null,"image":"1f4aa-1f3fc.png","sheet_x":25,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F4AA-1F3FD","non_qualified":null,"image":"1f4aa-1f3fd.png","sheet_x":25,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F4AA-1F3FE","non_qualified":null,"image":"1f4aa-1f3fe.png","sheet_x":25,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F4AA-1F3FF","non_qualified":null,"image":"1f4aa-1f3ff.png","sheet_x":25,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"DIZZY SYMBOL","unified":"1F4AB","non_qualified":null,"docomo":null,"au":"EB5C","softbank":null,"google":"FEB5F","image":"1f4ab.png","sheet_x":25,"sheet_y":46,"short_name":"dizzy","short_names":["dizzy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":431,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPEECH BALLOON","unified":"1F4AC","non_qualified":null,"docomo":null,"au":"E4FD","softbank":null,"google":"FE532","image":"1f4ac.png","sheet_x":25,"sheet_y":47,"short_name":"speech_balloon","short_names":["speech_balloon"],"text":null,"texts":null,"category":"Smileys & People","sort_order":432,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"THOUGHT BALLOON","unified":"1F4AD","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4ad.png","sheet_x":25,"sheet_y":48,"short_name":"thought_balloon","short_names":["thought_balloon"],"text":null,"texts":null,"category":"Smileys & People","sort_order":435,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE FLOWER","unified":"1F4AE","non_qualified":null,"docomo":null,"au":"E4F0","softbank":null,"google":"FEB7A","image":"1f4ae.png","sheet_x":25,"sheet_y":49,"short_name":"white_flower","short_names":["white_flower"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":105,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HUNDRED POINTS SYMBOL","unified":"1F4AF","non_qualified":null,"docomo":null,"au":"E4F2","softbank":null,"google":"FEB7B","image":"1f4af.png","sheet_x":25,"sheet_y":50,"short_name":"100","short_names":["100"],"text":null,"texts":null,"category":"Symbols","sort_order":145,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MONEY BAG","unified":"1F4B0","non_qualified":null,"docomo":"E715","au":"E4C7","softbank":"E12F","google":"FE4DD","image":"1f4b0.png","sheet_x":25,"sheet_y":51,"short_name":"moneybag","short_names":["moneybag"],"text":null,"texts":null,"category":"Objects","sort_order":76,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CURRENCY EXCHANGE","unified":"1F4B1","non_qualified":null,"docomo":null,"au":null,"softbank":"E149","google":"FE4DE","image":"1f4b1.png","sheet_x":25,"sheet_y":52,"short_name":"currency_exchange","short_names":["currency_exchange"],"text":null,"texts":null,"category":"Objects","sort_order":85,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEAVY DOLLAR SIGN","unified":"1F4B2","non_qualified":null,"docomo":"E715","au":"E579","softbank":null,"google":"FE4E0","image":"1f4b2.png","sheet_x":26,"sheet_y":0,"short_name":"heavy_dollar_sign","short_names":["heavy_dollar_sign"],"text":null,"texts":null,"category":"Objects","sort_order":86,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CREDIT CARD","unified":"1F4B3","non_qualified":null,"docomo":null,"au":"E57C","softbank":null,"google":"FE4E1","image":"1f4b3.png","sheet_x":26,"sheet_y":1,"short_name":"credit_card","short_names":["credit_card"],"text":null,"texts":null,"category":"Objects","sort_order":82,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BANKNOTE WITH YEN SIGN","unified":"1F4B4","non_qualified":null,"docomo":"E6D6","au":"E57D","softbank":null,"google":"FE4E2","image":"1f4b4.png","sheet_x":26,"sheet_y":2,"short_name":"yen","short_names":["yen"],"text":null,"texts":null,"category":"Objects","sort_order":77,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BANKNOTE WITH DOLLAR SIGN","unified":"1F4B5","non_qualified":null,"docomo":"E715","au":"E585","softbank":null,"google":"FE4E3","image":"1f4b5.png","sheet_x":26,"sheet_y":3,"short_name":"dollar","short_names":["dollar"],"text":null,"texts":null,"category":"Objects","sort_order":78,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BANKNOTE WITH EURO SIGN","unified":"1F4B6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4b6.png","sheet_x":26,"sheet_y":4,"short_name":"euro","short_names":["euro"],"text":null,"texts":null,"category":"Objects","sort_order":79,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BANKNOTE WITH POUND SIGN","unified":"1F4B7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4b7.png","sheet_x":26,"sheet_y":5,"short_name":"pound","short_names":["pound"],"text":null,"texts":null,"category":"Objects","sort_order":80,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MONEY WITH WINGS","unified":"1F4B8","non_qualified":null,"docomo":null,"au":"EB5B","softbank":null,"google":"FE4E4","image":"1f4b8.png","sheet_x":26,"sheet_y":6,"short_name":"money_with_wings","short_names":["money_with_wings"],"text":null,"texts":null,"category":"Objects","sort_order":81,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHART WITH UPWARDS TREND AND YEN SIGN","unified":"1F4B9","non_qualified":null,"docomo":null,"au":"E5DC","softbank":"E14A","google":"FE4DF","image":"1f4b9.png","sheet_x":26,"sheet_y":7,"short_name":"chart","short_names":["chart"],"text":null,"texts":null,"category":"Objects","sort_order":84,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SEAT","unified":"1F4BA","non_qualified":null,"docomo":"E6B2","au":null,"softbank":"E11F","google":"FE537","image":"1f4ba.png","sheet_x":26,"sheet_y":8,"short_name":"seat","short_names":["seat"],"text":null,"texts":null,"category":"Travel & Places","sort_order":117,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PERSONAL COMPUTER","unified":"1F4BB","non_qualified":null,"docomo":"E716","au":"E5B8","softbank":"E00C","google":"FE538","image":"1f4bb.png","sheet_x":26,"sheet_y":9,"short_name":"computer","short_names":["computer"],"text":null,"texts":null,"category":"Objects","sort_order":33,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BRIEFCASE","unified":"1F4BC","non_qualified":null,"docomo":"E682","au":"E5CE","softbank":"E11E","google":"FE53B","image":"1f4bc.png","sheet_x":26,"sheet_y":10,"short_name":"briefcase","short_names":["briefcase"],"text":null,"texts":null,"category":"Objects","sort_order":107,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MINIDISC","unified":"1F4BD","non_qualified":null,"docomo":null,"au":"E582","softbank":"E316","google":"FE53C","image":"1f4bd.png","sheet_x":26,"sheet_y":11,"short_name":"minidisc","short_names":["minidisc"],"text":null,"texts":null,"category":"Objects","sort_order":39,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FLOPPY DISK","unified":"1F4BE","non_qualified":null,"docomo":null,"au":"E562","softbank":null,"google":"FE53D","image":"1f4be.png","sheet_x":26,"sheet_y":12,"short_name":"floppy_disk","short_names":["floppy_disk"],"text":null,"texts":null,"category":"Objects","sort_order":40,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OPTICAL DISC","unified":"1F4BF","non_qualified":null,"docomo":"E68C","au":"E50C","softbank":"E126","google":"FE81D","image":"1f4bf.png","sheet_x":26,"sheet_y":13,"short_name":"cd","short_names":["cd"],"text":null,"texts":null,"category":"Objects","sort_order":41,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DVD","unified":"1F4C0","non_qualified":null,"docomo":"E68C","au":"E50C","softbank":"E127","google":"FE81E","image":"1f4c0.png","sheet_x":26,"sheet_y":14,"short_name":"dvd","short_names":["dvd"],"text":null,"texts":null,"category":"Objects","sort_order":42,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FILE FOLDER","unified":"1F4C1","non_qualified":null,"docomo":null,"au":"E58F","softbank":null,"google":"FE543","image":"1f4c1.png","sheet_x":26,"sheet_y":15,"short_name":"file_folder","short_names":["file_folder"],"text":null,"texts":null,"category":"Objects","sort_order":108,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OPEN FILE FOLDER","unified":"1F4C2","non_qualified":null,"docomo":null,"au":"E590","softbank":null,"google":"FE544","image":"1f4c2.png","sheet_x":26,"sheet_y":16,"short_name":"open_file_folder","short_names":["open_file_folder"],"text":null,"texts":null,"category":"Objects","sort_order":109,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PAGE WITH CURL","unified":"1F4C3","non_qualified":null,"docomo":"E689","au":"E561","softbank":null,"google":"FE540","image":"1f4c3.png","sheet_x":26,"sheet_y":17,"short_name":"page_with_curl","short_names":["page_with_curl"],"text":null,"texts":null,"category":"Objects","sort_order":68,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PAGE FACING UP","unified":"1F4C4","non_qualified":null,"docomo":"E689","au":"E569","softbank":null,"google":"FE541","image":"1f4c4.png","sheet_x":26,"sheet_y":18,"short_name":"page_facing_up","short_names":["page_facing_up"],"text":null,"texts":null,"category":"Objects","sort_order":70,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CALENDAR","unified":"1F4C5","non_qualified":null,"docomo":null,"au":"E563","softbank":null,"google":"FE542","image":"1f4c5.png","sheet_x":26,"sheet_y":19,"short_name":"date","short_names":["date"],"text":null,"texts":null,"category":"Objects","sort_order":111,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TEAR-OFF CALENDAR","unified":"1F4C6","non_qualified":null,"docomo":null,"au":"E56A","softbank":null,"google":"FE549","image":"1f4c6.png","sheet_x":26,"sheet_y":20,"short_name":"calendar","short_names":["calendar"],"text":null,"texts":null,"category":"Objects","sort_order":112,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CARD INDEX","unified":"1F4C7","non_qualified":null,"docomo":"E683","au":"E56C","softbank":null,"google":"FE54D","image":"1f4c7.png","sheet_x":26,"sheet_y":21,"short_name":"card_index","short_names":["card_index"],"text":null,"texts":null,"category":"Objects","sort_order":115,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHART WITH UPWARDS TREND","unified":"1F4C8","non_qualified":null,"docomo":null,"au":"E575","softbank":null,"google":"FE54B","image":"1f4c8.png","sheet_x":26,"sheet_y":22,"short_name":"chart_with_upwards_trend","short_names":["chart_with_upwards_trend"],"text":null,"texts":null,"category":"Objects","sort_order":116,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHART WITH DOWNWARDS TREND","unified":"1F4C9","non_qualified":null,"docomo":null,"au":"E576","softbank":null,"google":"FE54C","image":"1f4c9.png","sheet_x":26,"sheet_y":23,"short_name":"chart_with_downwards_trend","short_names":["chart_with_downwards_trend"],"text":null,"texts":null,"category":"Objects","sort_order":117,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BAR CHART","unified":"1F4CA","non_qualified":null,"docomo":null,"au":"E574","softbank":null,"google":"FE54A","image":"1f4ca.png","sheet_x":26,"sheet_y":24,"short_name":"bar_chart","short_names":["bar_chart"],"text":null,"texts":null,"category":"Objects","sort_order":118,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLIPBOARD","unified":"1F4CB","non_qualified":null,"docomo":"E689","au":"E564","softbank":null,"google":"FE548","image":"1f4cb.png","sheet_x":26,"sheet_y":25,"short_name":"clipboard","short_names":["clipboard"],"text":null,"texts":null,"category":"Objects","sort_order":119,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PUSHPIN","unified":"1F4CC","non_qualified":null,"docomo":null,"au":"E56D","softbank":null,"google":"FE54E","image":"1f4cc.png","sheet_x":26,"sheet_y":26,"short_name":"pushpin","short_names":["pushpin"],"text":null,"texts":null,"category":"Objects","sort_order":120,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ROUND PUSHPIN","unified":"1F4CD","non_qualified":null,"docomo":null,"au":"E560","softbank":null,"google":"FE53F","image":"1f4cd.png","sheet_x":26,"sheet_y":27,"short_name":"round_pushpin","short_names":["round_pushpin"],"text":null,"texts":null,"category":"Objects","sort_order":121,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PAPERCLIP","unified":"1F4CE","non_qualified":null,"docomo":"E730","au":"E4A0","softbank":null,"google":"FE53A","image":"1f4ce.png","sheet_x":26,"sheet_y":28,"short_name":"paperclip","short_names":["paperclip"],"text":null,"texts":null,"category":"Objects","sort_order":122,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"STRAIGHT RULER","unified":"1F4CF","non_qualified":null,"docomo":null,"au":"E570","softbank":null,"google":"FE550","image":"1f4cf.png","sheet_x":26,"sheet_y":29,"short_name":"straight_ruler","short_names":["straight_ruler"],"text":null,"texts":null,"category":"Objects","sort_order":124,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TRIANGULAR RULER","unified":"1F4D0","non_qualified":null,"docomo":null,"au":"E4A2","softbank":null,"google":"FE551","image":"1f4d0.png","sheet_x":26,"sheet_y":30,"short_name":"triangular_ruler","short_names":["triangular_ruler"],"text":null,"texts":null,"category":"Objects","sort_order":125,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BOOKMARK TABS","unified":"1F4D1","non_qualified":null,"docomo":"E689","au":"EB0B","softbank":null,"google":"FE552","image":"1f4d1.png","sheet_x":26,"sheet_y":31,"short_name":"bookmark_tabs","short_names":["bookmark_tabs"],"text":null,"texts":null,"category":"Objects","sort_order":73,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEDGER","unified":"1F4D2","non_qualified":null,"docomo":"E683","au":"E56E","softbank":null,"google":"FE54F","image":"1f4d2.png","sheet_x":26,"sheet_y":32,"short_name":"ledger","short_names":["ledger"],"text":null,"texts":null,"category":"Objects","sort_order":67,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NOTEBOOK","unified":"1F4D3","non_qualified":null,"docomo":"E683","au":"E56B","softbank":null,"google":"FE545","image":"1f4d3.png","sheet_x":26,"sheet_y":33,"short_name":"notebook","short_names":["notebook"],"text":null,"texts":null,"category":"Objects","sort_order":66,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NOTEBOOK WITH DECORATIVE COVER","unified":"1F4D4","non_qualified":null,"docomo":"E683","au":"E49D","softbank":null,"google":"FE547","image":"1f4d4.png","sheet_x":26,"sheet_y":34,"short_name":"notebook_with_decorative_cover","short_names":["notebook_with_decorative_cover"],"text":null,"texts":null,"category":"Objects","sort_order":59,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOSED BOOK","unified":"1F4D5","non_qualified":null,"docomo":"E683","au":"E568","softbank":null,"google":"FE502","image":"1f4d5.png","sheet_x":26,"sheet_y":35,"short_name":"closed_book","short_names":["closed_book"],"text":null,"texts":null,"category":"Objects","sort_order":60,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OPEN BOOK","unified":"1F4D6","non_qualified":null,"docomo":"E683","au":"E49F","softbank":"E148","google":"FE546","image":"1f4d6.png","sheet_x":26,"sheet_y":36,"short_name":"book","short_names":["book","open_book"],"text":null,"texts":null,"category":"Objects","sort_order":61,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GREEN BOOK","unified":"1F4D7","non_qualified":null,"docomo":"E683","au":"E565","softbank":null,"google":"FE4FF","image":"1f4d7.png","sheet_x":26,"sheet_y":37,"short_name":"green_book","short_names":["green_book"],"text":null,"texts":null,"category":"Objects","sort_order":62,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLUE BOOK","unified":"1F4D8","non_qualified":null,"docomo":"E683","au":"E566","softbank":null,"google":"FE500","image":"1f4d8.png","sheet_x":26,"sheet_y":38,"short_name":"blue_book","short_names":["blue_book"],"text":null,"texts":null,"category":"Objects","sort_order":63,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ORANGE BOOK","unified":"1F4D9","non_qualified":null,"docomo":"E683","au":"E567","softbank":null,"google":"FE501","image":"1f4d9.png","sheet_x":26,"sheet_y":39,"short_name":"orange_book","short_names":["orange_book"],"text":null,"texts":null,"category":"Objects","sort_order":64,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BOOKS","unified":"1F4DA","non_qualified":null,"docomo":"E683","au":"E56F","softbank":null,"google":"FE503","image":"1f4da.png","sheet_x":26,"sheet_y":40,"short_name":"books","short_names":["books"],"text":null,"texts":null,"category":"Objects","sort_order":65,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NAME BADGE","unified":"1F4DB","non_qualified":null,"docomo":null,"au":"E51D","softbank":null,"google":"FE504","image":"1f4db.png","sheet_x":26,"sheet_y":41,"short_name":"name_badge","short_names":["name_badge"],"text":null,"texts":null,"category":"Symbols","sort_order":104,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SCROLL","unified":"1F4DC","non_qualified":null,"docomo":"E70A","au":"E55F","softbank":null,"google":"FE4FD","image":"1f4dc.png","sheet_x":26,"sheet_y":42,"short_name":"scroll","short_names":["scroll"],"text":null,"texts":null,"category":"Objects","sort_order":69,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MEMO","unified":"1F4DD","non_qualified":null,"docomo":"E689","au":"EA92","softbank":"E301","google":"FE527","image":"1f4dd.png","sheet_x":26,"sheet_y":43,"short_name":"memo","short_names":["memo","pencil"],"text":null,"texts":null,"category":"Objects","sort_order":106,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TELEPHONE RECEIVER","unified":"1F4DE","non_qualified":null,"docomo":"E687","au":"E51E","softbank":null,"google":"FE524","image":"1f4de.png","sheet_x":26,"sheet_y":44,"short_name":"telephone_receiver","short_names":["telephone_receiver"],"text":null,"texts":null,"category":"Objects","sort_order":28,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PAGER","unified":"1F4DF","non_qualified":null,"docomo":"E65A","au":"E59B","softbank":null,"google":"FE522","image":"1f4df.png","sheet_x":26,"sheet_y":45,"short_name":"pager","short_names":["pager"],"text":null,"texts":null,"category":"Objects","sort_order":29,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FAX MACHINE","unified":"1F4E0","non_qualified":null,"docomo":"E6D0","au":"E520","softbank":"E00B","google":"FE528","image":"1f4e0.png","sheet_x":26,"sheet_y":46,"short_name":"fax","short_names":["fax"],"text":null,"texts":null,"category":"Objects","sort_order":30,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SATELLITE ANTENNA","unified":"1F4E1","non_qualified":null,"docomo":null,"au":"E4A8","softbank":"E14B","google":"FE531","image":"1f4e1.png","sheet_x":26,"sheet_y":47,"short_name":"satellite_antenna","short_names":["satellite_antenna"],"text":null,"texts":null,"category":"Objects","sort_order":160,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PUBLIC ADDRESS LOUDSPEAKER","unified":"1F4E2","non_qualified":null,"docomo":null,"au":"E511","softbank":"E142","google":"FE52F","image":"1f4e2.png","sheet_x":26,"sheet_y":48,"short_name":"loudspeaker","short_names":["loudspeaker"],"text":null,"texts":null,"category":"Objects","sort_order":5,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHEERING MEGAPHONE","unified":"1F4E3","non_qualified":null,"docomo":null,"au":"E511","softbank":"E317","google":"FE530","image":"1f4e3.png","sheet_x":26,"sheet_y":49,"short_name":"mega","short_names":["mega"],"text":null,"texts":null,"category":"Objects","sort_order":6,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OUTBOX TRAY","unified":"1F4E4","non_qualified":null,"docomo":null,"au":"E592","softbank":null,"google":"FE533","image":"1f4e4.png","sheet_x":26,"sheet_y":50,"short_name":"outbox_tray","short_names":["outbox_tray"],"text":null,"texts":null,"category":"Objects","sort_order":91,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"INBOX TRAY","unified":"1F4E5","non_qualified":null,"docomo":null,"au":"E593","softbank":null,"google":"FE534","image":"1f4e5.png","sheet_x":26,"sheet_y":51,"short_name":"inbox_tray","short_names":["inbox_tray"],"text":null,"texts":null,"category":"Objects","sort_order":92,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PACKAGE","unified":"1F4E6","non_qualified":null,"docomo":"E685","au":"E51F","softbank":null,"google":"FE535","image":"1f4e6.png","sheet_x":26,"sheet_y":52,"short_name":"package","short_names":["package"],"text":null,"texts":null,"category":"Objects","sort_order":93,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"E-MAIL SYMBOL","unified":"1F4E7","non_qualified":null,"docomo":"E6D3","au":"EB71","softbank":null,"google":"FEB92","image":"1f4e7.png","sheet_x":27,"sheet_y":0,"short_name":"e-mail","short_names":["e-mail"],"text":null,"texts":null,"category":"Objects","sort_order":88,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"INCOMING ENVELOPE","unified":"1F4E8","non_qualified":null,"docomo":"E6CF","au":"E591","softbank":null,"google":"FE52A","image":"1f4e8.png","sheet_x":27,"sheet_y":1,"short_name":"incoming_envelope","short_names":["incoming_envelope"],"text":null,"texts":null,"category":"Objects","sort_order":89,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ENVELOPE WITH DOWNWARDS ARROW ABOVE","unified":"1F4E9","non_qualified":null,"docomo":"E6CF","au":"EB62","softbank":"E103","google":"FE52B","image":"1f4e9.png","sheet_x":27,"sheet_y":2,"short_name":"envelope_with_arrow","short_names":["envelope_with_arrow"],"text":null,"texts":null,"category":"Objects","sort_order":90,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOSED MAILBOX WITH LOWERED FLAG","unified":"1F4EA","non_qualified":null,"docomo":"E665","au":"E51B","softbank":null,"google":"FE52C","image":"1f4ea.png","sheet_x":27,"sheet_y":3,"short_name":"mailbox_closed","short_names":["mailbox_closed"],"text":null,"texts":null,"category":"Objects","sort_order":95,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOSED MAILBOX WITH RAISED FLAG","unified":"1F4EB","non_qualified":null,"docomo":"E665","au":"EB0A","softbank":"E101","google":"FE52D","image":"1f4eb.png","sheet_x":27,"sheet_y":4,"short_name":"mailbox","short_names":["mailbox"],"text":null,"texts":null,"category":"Objects","sort_order":94,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OPEN MAILBOX WITH RAISED FLAG","unified":"1F4EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4ec.png","sheet_x":27,"sheet_y":5,"short_name":"mailbox_with_mail","short_names":["mailbox_with_mail"],"text":null,"texts":null,"category":"Objects","sort_order":96,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OPEN MAILBOX WITH LOWERED FLAG","unified":"1F4ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4ed.png","sheet_x":27,"sheet_y":6,"short_name":"mailbox_with_no_mail","short_names":["mailbox_with_no_mail"],"text":null,"texts":null,"category":"Objects","sort_order":97,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POSTBOX","unified":"1F4EE","non_qualified":null,"docomo":"E665","au":"E51B","softbank":"E102","google":"FE52E","image":"1f4ee.png","sheet_x":27,"sheet_y":7,"short_name":"postbox","short_names":["postbox"],"text":null,"texts":null,"category":"Objects","sort_order":98,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POSTAL HORN","unified":"1F4EF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4ef.png","sheet_x":27,"sheet_y":8,"short_name":"postal_horn","short_names":["postal_horn"],"text":null,"texts":null,"category":"Objects","sort_order":7,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEWSPAPER","unified":"1F4F0","non_qualified":null,"docomo":null,"au":"E58B","softbank":null,"google":"FE822","image":"1f4f0.png","sheet_x":27,"sheet_y":9,"short_name":"newspaper","short_names":["newspaper"],"text":null,"texts":null,"category":"Objects","sort_order":71,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOBILE PHONE","unified":"1F4F1","non_qualified":null,"docomo":"E688","au":"E588","softbank":"E00A","google":"FE525","image":"1f4f1.png","sheet_x":27,"sheet_y":10,"short_name":"iphone","short_names":["iphone"],"text":null,"texts":null,"category":"Objects","sort_order":25,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT","unified":"1F4F2","non_qualified":null,"docomo":"E6CE","au":"EB08","softbank":"E104","google":"FE526","image":"1f4f2.png","sheet_x":27,"sheet_y":11,"short_name":"calling","short_names":["calling"],"text":null,"texts":null,"category":"Objects","sort_order":26,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"VIBRATION MODE","unified":"1F4F3","non_qualified":null,"docomo":null,"au":"EA90","softbank":"E250","google":"FE839","image":"1f4f3.png","sheet_x":27,"sheet_y":12,"short_name":"vibration_mode","short_names":["vibration_mode"],"text":null,"texts":null,"category":"Symbols","sort_order":95,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOBILE PHONE OFF","unified":"1F4F4","non_qualified":null,"docomo":null,"au":"EA91","softbank":"E251","google":"FE83A","image":"1f4f4.png","sheet_x":27,"sheet_y":13,"short_name":"mobile_phone_off","short_names":["mobile_phone_off"],"text":null,"texts":null,"category":"Symbols","sort_order":96,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NO MOBILE PHONES","unified":"1F4F5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4f5.png","sheet_x":27,"sheet_y":14,"short_name":"no_mobile_phones","short_names":["no_mobile_phones"],"text":null,"texts":null,"category":"Symbols","sort_order":23,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ANTENNA WITH BARS","unified":"1F4F6","non_qualified":null,"docomo":null,"au":"EA84","softbank":"E20B","google":"FE838","image":"1f4f6.png","sheet_x":27,"sheet_y":15,"short_name":"signal_strength","short_names":["signal_strength"],"text":null,"texts":null,"category":"Symbols","sort_order":94,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CAMERA","unified":"1F4F7","non_qualified":null,"docomo":"E681","au":"E515","softbank":"E008","google":"FE4EF","image":"1f4f7.png","sheet_x":27,"sheet_y":16,"short_name":"camera","short_names":["camera"],"text":null,"texts":null,"category":"Objects","sort_order":49,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CAMERA WITH FLASH","unified":"1F4F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4f8.png","sheet_x":27,"sheet_y":17,"short_name":"camera_with_flash","short_names":["camera_with_flash"],"text":null,"texts":null,"category":"Objects","sort_order":50,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"VIDEO CAMERA","unified":"1F4F9","non_qualified":null,"docomo":"E677","au":"E57E","softbank":null,"google":"FE4F9","image":"1f4f9.png","sheet_x":27,"sheet_y":18,"short_name":"video_camera","short_names":["video_camera"],"text":null,"texts":null,"category":"Objects","sort_order":51,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TELEVISION","unified":"1F4FA","non_qualified":null,"docomo":"E68A","au":"E502","softbank":"E12A","google":"FE81C","image":"1f4fa.png","sheet_x":27,"sheet_y":19,"short_name":"tv","short_names":["tv"],"text":null,"texts":null,"category":"Objects","sort_order":48,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RADIO","unified":"1F4FB","non_qualified":null,"docomo":null,"au":"E5B9","softbank":"E128","google":"FE81F","image":"1f4fb.png","sheet_x":27,"sheet_y":20,"short_name":"radio","short_names":["radio"],"text":null,"texts":null,"category":"Objects","sort_order":18,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"VIDEOCASSETTE","unified":"1F4FC","non_qualified":null,"docomo":null,"au":"E580","softbank":"E129","google":"FE820","image":"1f4fc.png","sheet_x":27,"sheet_y":21,"short_name":"vhs","short_names":["vhs"],"text":null,"texts":null,"category":"Objects","sort_order":52,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F4FD-FE0F","non_qualified":"1F4FD","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4fd-fe0f.png","sheet_x":27,"sheet_y":22,"short_name":"film_projector","short_names":["film_projector"],"text":null,"texts":null,"category":"Objects","sort_order":46,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"PRAYER BEADS","unified":"1F4FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f4ff.png","sheet_x":27,"sheet_y":23,"short_name":"prayer_beads","short_names":["prayer_beads"],"text":null,"texts":null,"category":"Smileys & People","sort_order":470,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"TWISTED RIGHTWARDS ARROWS","unified":"1F500","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f500.png","sheet_x":27,"sheet_y":24,"short_name":"twisted_rightwards_arrows","short_names":["twisted_rightwards_arrows"],"text":null,"texts":null,"category":"Symbols","sort_order":73,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS","unified":"1F501","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f501.png","sheet_x":27,"sheet_y":25,"short_name":"repeat","short_names":["repeat"],"text":null,"texts":null,"category":"Symbols","sort_order":74,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY","unified":"1F502","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f502.png","sheet_x":27,"sheet_y":26,"short_name":"repeat_one","short_names":["repeat_one"],"text":null,"texts":null,"category":"Symbols","sort_order":75,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS","unified":"1F503","non_qualified":null,"docomo":"E735","au":"EB0D","softbank":null,"google":"FEB91","image":"1f503.png","sheet_x":27,"sheet_y":27,"short_name":"arrows_clockwise","short_names":["arrows_clockwise"],"text":null,"texts":null,"category":"Symbols","sort_order":41,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS","unified":"1F504","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f504.png","sheet_x":27,"sheet_y":28,"short_name":"arrows_counterclockwise","short_names":["arrows_counterclockwise"],"text":null,"texts":null,"category":"Symbols","sort_order":42,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LOW BRIGHTNESS SYMBOL","unified":"1F505","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f505.png","sheet_x":27,"sheet_y":29,"short_name":"low_brightness","short_names":["low_brightness"],"text":null,"texts":null,"category":"Symbols","sort_order":92,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HIGH BRIGHTNESS SYMBOL","unified":"1F506","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f506.png","sheet_x":27,"sheet_y":30,"short_name":"high_brightness","short_names":["high_brightness"],"text":null,"texts":null,"category":"Symbols","sort_order":93,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPEAKER WITH CANCELLATION STROKE","unified":"1F507","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f507.png","sheet_x":27,"sheet_y":31,"short_name":"mute","short_names":["mute"],"text":null,"texts":null,"category":"Objects","sort_order":1,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPEAKER","unified":"1F508","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f508.png","sheet_x":27,"sheet_y":32,"short_name":"speaker","short_names":["speaker"],"text":null,"texts":null,"category":"Objects","sort_order":2,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPEAKER WITH ONE SOUND WAVE","unified":"1F509","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f509.png","sheet_x":27,"sheet_y":33,"short_name":"sound","short_names":["sound"],"text":null,"texts":null,"category":"Objects","sort_order":3,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPEAKER WITH THREE SOUND WAVES","unified":"1F50A","non_qualified":null,"docomo":null,"au":"E511","softbank":"E141","google":"FE821","image":"1f50a.png","sheet_x":27,"sheet_y":34,"short_name":"loud_sound","short_names":["loud_sound"],"text":null,"texts":null,"category":"Objects","sort_order":4,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BATTERY","unified":"1F50B","non_qualified":null,"docomo":null,"au":"E584","softbank":null,"google":"FE4FC","image":"1f50b.png","sheet_x":27,"sheet_y":35,"short_name":"battery","short_names":["battery"],"text":null,"texts":null,"category":"Objects","sort_order":31,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ELECTRIC PLUG","unified":"1F50C","non_qualified":null,"docomo":null,"au":"E589","softbank":null,"google":"FE4FE","image":"1f50c.png","sheet_x":27,"sheet_y":36,"short_name":"electric_plug","short_names":["electric_plug"],"text":null,"texts":null,"category":"Objects","sort_order":32,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEFT-POINTING MAGNIFYING GLASS","unified":"1F50D","non_qualified":null,"docomo":"E6DC","au":"E518","softbank":"E114","google":"FEB85","image":"1f50d.png","sheet_x":27,"sheet_y":37,"short_name":"mag","short_names":["mag"],"text":null,"texts":null,"category":"Objects","sort_order":53,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RIGHT-POINTING MAGNIFYING GLASS","unified":"1F50E","non_qualified":null,"docomo":"E6DC","au":"EB05","softbank":null,"google":"FEB8D","image":"1f50e.png","sheet_x":27,"sheet_y":38,"short_name":"mag_right","short_names":["mag_right"],"text":null,"texts":null,"category":"Objects","sort_order":54,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LOCK WITH INK PEN","unified":"1F50F","non_qualified":null,"docomo":"E6D9","au":"EB0C","softbank":null,"google":"FEB90","image":"1f50f.png","sheet_x":27,"sheet_y":39,"short_name":"lock_with_ink_pen","short_names":["lock_with_ink_pen"],"text":null,"texts":null,"category":"Objects","sort_order":132,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOSED LOCK WITH KEY","unified":"1F510","non_qualified":null,"docomo":"E6D9","au":"EAFC","softbank":null,"google":"FEB8A","image":"1f510.png","sheet_x":27,"sheet_y":40,"short_name":"closed_lock_with_key","short_names":["closed_lock_with_key"],"text":null,"texts":null,"category":"Objects","sort_order":133,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KEY","unified":"1F511","non_qualified":null,"docomo":"E6D9","au":"E519","softbank":"E03F","google":"FEB82","image":"1f511.png","sheet_x":27,"sheet_y":41,"short_name":"key","short_names":["key"],"text":null,"texts":null,"category":"Objects","sort_order":134,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LOCK","unified":"1F512","non_qualified":null,"docomo":"E6D9","au":"E51C","softbank":"E144","google":"FEB86","image":"1f512.png","sheet_x":27,"sheet_y":42,"short_name":"lock","short_names":["lock"],"text":null,"texts":null,"category":"Objects","sort_order":130,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"OPEN LOCK","unified":"1F513","non_qualified":null,"docomo":"E6D9","au":"E51C","softbank":"E145","google":"FEB87","image":"1f513.png","sheet_x":27,"sheet_y":43,"short_name":"unlock","short_names":["unlock"],"text":null,"texts":null,"category":"Objects","sort_order":131,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BELL","unified":"1F514","non_qualified":null,"docomo":"E713","au":"E512","softbank":"E325","google":"FE4F2","image":"1f514.png","sheet_x":27,"sheet_y":44,"short_name":"bell","short_names":["bell"],"text":null,"texts":null,"category":"Objects","sort_order":8,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BELL WITH CANCELLATION STROKE","unified":"1F515","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f515.png","sheet_x":27,"sheet_y":45,"short_name":"no_bell","short_names":["no_bell"],"text":null,"texts":null,"category":"Objects","sort_order":9,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BOOKMARK","unified":"1F516","non_qualified":null,"docomo":null,"au":"EB07","softbank":null,"google":"FEB8F","image":"1f516.png","sheet_x":27,"sheet_y":46,"short_name":"bookmark","short_names":["bookmark"],"text":null,"texts":null,"category":"Objects","sort_order":74,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LINK SYMBOL","unified":"1F517","non_qualified":null,"docomo":null,"au":"E58A","softbank":null,"google":"FEB4B","image":"1f517.png","sheet_x":27,"sheet_y":47,"short_name":"link","short_names":["link"],"text":null,"texts":null,"category":"Objects","sort_order":150,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RADIO BUTTON","unified":"1F518","non_qualified":null,"docomo":null,"au":"EB04","softbank":null,"google":"FEB8C","image":"1f518.png","sheet_x":27,"sheet_y":48,"short_name":"radio_button","short_names":["radio_button"],"text":null,"texts":null,"category":"Symbols","sort_order":200,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BACK WITH LEFTWARDS ARROW ABOVE","unified":"1F519","non_qualified":null,"docomo":null,"au":"EB06","softbank":null,"google":"FEB8E","image":"1f519.png","sheet_x":27,"sheet_y":49,"short_name":"back","short_names":["back"],"text":null,"texts":null,"category":"Symbols","sort_order":43,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"END WITH LEFTWARDS ARROW ABOVE","unified":"1F51A","non_qualified":null,"docomo":"E6B9","au":null,"softbank":null,"google":"FE01A","image":"1f51a.png","sheet_x":27,"sheet_y":50,"short_name":"end","short_names":["end"],"text":null,"texts":null,"category":"Symbols","sort_order":44,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE","unified":"1F51B","non_qualified":null,"docomo":"E6B8","au":null,"softbank":null,"google":"FE019","image":"1f51b.png","sheet_x":27,"sheet_y":51,"short_name":"on","short_names":["on"],"text":null,"texts":null,"category":"Symbols","sort_order":45,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SOON WITH RIGHTWARDS ARROW ABOVE","unified":"1F51C","non_qualified":null,"docomo":"E6B7","au":null,"softbank":null,"google":"FE018","image":"1f51c.png","sheet_x":27,"sheet_y":52,"short_name":"soon","short_names":["soon"],"text":null,"texts":null,"category":"Symbols","sort_order":46,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TOP WITH UPWARDS ARROW ABOVE","unified":"1F51D","non_qualified":null,"docomo":null,"au":null,"softbank":"E24C","google":"FEB42","image":"1f51d.png","sheet_x":28,"sheet_y":0,"short_name":"top","short_names":["top"],"text":null,"texts":null,"category":"Symbols","sort_order":47,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NO ONE UNDER EIGHTEEN SYMBOL","unified":"1F51E","non_qualified":null,"docomo":null,"au":"EA83","softbank":"E207","google":"FEB25","image":"1f51e.png","sheet_x":28,"sheet_y":1,"short_name":"underage","short_names":["underage"],"text":null,"texts":null,"category":"Symbols","sort_order":24,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KEYCAP TEN","unified":"1F51F","non_qualified":null,"docomo":null,"au":"E52B","softbank":null,"google":"FE83B","image":"1f51f.png","sheet_x":28,"sheet_y":2,"short_name":"keycap_ten","short_names":["keycap_ten"],"text":null,"texts":null,"category":"Symbols","sort_order":144,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"INPUT SYMBOL FOR LATIN CAPITAL LETTERS","unified":"1F520","non_qualified":null,"docomo":null,"au":"EAFD","softbank":null,"google":"FEB7C","image":"1f520.png","sheet_x":28,"sheet_y":3,"short_name":"capital_abcd","short_names":["capital_abcd"],"text":null,"texts":null,"category":"Symbols","sort_order":146,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"INPUT SYMBOL FOR LATIN SMALL LETTERS","unified":"1F521","non_qualified":null,"docomo":null,"au":"EAFE","softbank":null,"google":"FEB7D","image":"1f521.png","sheet_x":28,"sheet_y":4,"short_name":"abcd","short_names":["abcd"],"text":null,"texts":null,"category":"Symbols","sort_order":147,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"INPUT SYMBOL FOR NUMBERS","unified":"1F522","non_qualified":null,"docomo":null,"au":"EAFF","softbank":null,"google":"FEB7E","image":"1f522.png","sheet_x":28,"sheet_y":5,"short_name":"1234","short_names":["1234"],"text":null,"texts":null,"category":"Symbols","sort_order":148,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"INPUT SYMBOL FOR SYMBOLS","unified":"1F523","non_qualified":null,"docomo":null,"au":"EB00","softbank":null,"google":"FEB7F","image":"1f523.png","sheet_x":28,"sheet_y":6,"short_name":"symbols","short_names":["symbols"],"text":null,"texts":null,"category":"Symbols","sort_order":149,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"INPUT SYMBOL FOR LATIN LETTERS","unified":"1F524","non_qualified":null,"docomo":null,"au":"EB55","softbank":null,"google":"FEB80","image":"1f524.png","sheet_x":28,"sheet_y":7,"short_name":"abc","short_names":["abc"],"text":null,"texts":null,"category":"Symbols","sort_order":150,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FIRE","unified":"1F525","non_qualified":null,"docomo":null,"au":"E47B","softbank":"E11D","google":"FE4F6","image":"1f525.png","sheet_x":28,"sheet_y":8,"short_name":"fire","short_names":["fire"],"text":null,"texts":null,"category":"Travel & Places","sort_order":200,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ELECTRIC TORCH","unified":"1F526","non_qualified":null,"docomo":"E6FB","au":"E583","softbank":null,"google":"FE4FB","image":"1f526.png","sheet_x":28,"sheet_y":9,"short_name":"flashlight","short_names":["flashlight"],"text":null,"texts":null,"category":"Objects","sort_order":57,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WRENCH","unified":"1F527","non_qualified":null,"docomo":"E718","au":"E587","softbank":null,"google":"FE4C9","image":"1f527.png","sheet_x":28,"sheet_y":10,"short_name":"wrench","short_names":["wrench"],"text":null,"texts":null,"category":"Objects","sort_order":145,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HAMMER","unified":"1F528","non_qualified":null,"docomo":null,"au":"E5CB","softbank":"E116","google":"FE4CA","image":"1f528.png","sheet_x":28,"sheet_y":11,"short_name":"hammer","short_names":["hammer"],"text":null,"texts":null,"category":"Objects","sort_order":136,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NUT AND BOLT","unified":"1F529","non_qualified":null,"docomo":null,"au":"E581","softbank":null,"google":"FE4CB","image":"1f529.png","sheet_x":28,"sheet_y":12,"short_name":"nut_and_bolt","short_names":["nut_and_bolt"],"text":null,"texts":null,"category":"Objects","sort_order":146,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HOCHO","unified":"1F52A","non_qualified":null,"docomo":null,"au":"E57F","softbank":null,"google":"FE4FA","image":"1f52a.png","sheet_x":28,"sheet_y":13,"short_name":"hocho","short_names":["hocho","knife"],"text":null,"texts":null,"category":"Food & Drink","sort_order":107,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PISTOL","unified":"1F52B","non_qualified":null,"docomo":null,"au":"E50A","softbank":"E113","google":"FE4F5","image":"1f52b.png","sheet_x":28,"sheet_y":14,"short_name":"gun","short_names":["gun"],"text":null,"texts":null,"category":"Objects","sort_order":142,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MICROSCOPE","unified":"1F52C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f52c.png","sheet_x":28,"sheet_y":15,"short_name":"microscope","short_names":["microscope"],"text":null,"texts":null,"category":"Objects","sort_order":158,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TELESCOPE","unified":"1F52D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f52d.png","sheet_x":28,"sheet_y":16,"short_name":"telescope","short_names":["telescope"],"text":null,"texts":null,"category":"Objects","sort_order":159,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CRYSTAL BALL","unified":"1F52E","non_qualified":null,"docomo":null,"au":"EA8F","softbank":null,"google":"FE4F7","image":"1f52e.png","sheet_x":28,"sheet_y":17,"short_name":"crystal_ball","short_names":["crystal_ball"],"text":null,"texts":null,"category":"Activities","sort_order":56,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SIX POINTED STAR WITH MIDDLE DOT","unified":"1F52F","non_qualified":null,"docomo":null,"au":"EA8F","softbank":"E23E","google":"FE4F8","image":"1f52f.png","sheet_x":28,"sheet_y":18,"short_name":"six_pointed_star","short_names":["six_pointed_star"],"text":null,"texts":null,"category":"Symbols","sort_order":59,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"JAPANESE SYMBOL FOR BEGINNER","unified":"1F530","non_qualified":null,"docomo":null,"au":"E480","softbank":"E209","google":"FE044","image":"1f530.png","sheet_x":28,"sheet_y":19,"short_name":"beginner","short_names":["beginner"],"text":null,"texts":null,"category":"Symbols","sort_order":105,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TRIDENT EMBLEM","unified":"1F531","non_qualified":null,"docomo":"E71A","au":"E5C9","softbank":"E031","google":"FE4D2","image":"1f531.png","sheet_x":28,"sheet_y":20,"short_name":"trident","short_names":["trident"],"text":null,"texts":null,"category":"Symbols","sort_order":103,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK SQUARE BUTTON","unified":"1F532","non_qualified":null,"docomo":"E69C","au":"E54B","softbank":"E21A","google":"FEB64","image":"1f532.png","sheet_x":28,"sheet_y":21,"short_name":"black_square_button","short_names":["black_square_button"],"text":null,"texts":null,"category":"Symbols","sort_order":201,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE SQUARE BUTTON","unified":"1F533","non_qualified":null,"docomo":"E69C","au":"E54B","softbank":"E21B","google":"FEB67","image":"1f533.png","sheet_x":28,"sheet_y":22,"short_name":"white_square_button","short_names":["white_square_button"],"text":null,"texts":null,"category":"Symbols","sort_order":202,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LARGE RED CIRCLE","unified":"1F534","non_qualified":null,"docomo":"E69C","au":"E54A","softbank":"E219","google":"FEB63","image":"1f534.png","sheet_x":28,"sheet_y":23,"short_name":"red_circle","short_names":["red_circle"],"text":null,"texts":null,"category":"Symbols","sort_order":205,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LARGE BLUE CIRCLE","unified":"1F535","non_qualified":null,"docomo":"E69C","au":"E54B","softbank":null,"google":"FEB64","image":"1f535.png","sheet_x":28,"sheet_y":24,"short_name":"large_blue_circle","short_names":["large_blue_circle"],"text":null,"texts":null,"category":"Symbols","sort_order":206,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LARGE ORANGE DIAMOND","unified":"1F536","non_qualified":null,"docomo":null,"au":"E546","softbank":null,"google":"FEB73","image":"1f536.png","sheet_x":28,"sheet_y":25,"short_name":"large_orange_diamond","short_names":["large_orange_diamond"],"text":null,"texts":null,"category":"Symbols","sort_order":193,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LARGE BLUE DIAMOND","unified":"1F537","non_qualified":null,"docomo":null,"au":"E547","softbank":null,"google":"FEB74","image":"1f537.png","sheet_x":28,"sheet_y":26,"short_name":"large_blue_diamond","short_names":["large_blue_diamond"],"text":null,"texts":null,"category":"Symbols","sort_order":194,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMALL ORANGE DIAMOND","unified":"1F538","non_qualified":null,"docomo":null,"au":"E536","softbank":null,"google":"FEB75","image":"1f538.png","sheet_x":28,"sheet_y":27,"short_name":"small_orange_diamond","short_names":["small_orange_diamond"],"text":null,"texts":null,"category":"Symbols","sort_order":195,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMALL BLUE DIAMOND","unified":"1F539","non_qualified":null,"docomo":null,"au":"E537","softbank":null,"google":"FEB76","image":"1f539.png","sheet_x":28,"sheet_y":28,"short_name":"small_blue_diamond","short_names":["small_blue_diamond"],"text":null,"texts":null,"category":"Symbols","sort_order":196,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"UP-POINTING RED TRIANGLE","unified":"1F53A","non_qualified":null,"docomo":null,"au":"E55A","softbank":null,"google":"FEB78","image":"1f53a.png","sheet_x":28,"sheet_y":29,"short_name":"small_red_triangle","short_names":["small_red_triangle"],"text":null,"texts":null,"category":"Symbols","sort_order":197,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DOWN-POINTING RED TRIANGLE","unified":"1F53B","non_qualified":null,"docomo":null,"au":"E55B","softbank":null,"google":"FEB79","image":"1f53b.png","sheet_x":28,"sheet_y":30,"short_name":"small_red_triangle_down","short_names":["small_red_triangle_down"],"text":null,"texts":null,"category":"Symbols","sort_order":198,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"UP-POINTING SMALL RED TRIANGLE","unified":"1F53C","non_qualified":null,"docomo":null,"au":"E543","softbank":null,"google":"FEB01","image":"1f53c.png","sheet_x":28,"sheet_y":31,"short_name":"arrow_up_small","short_names":["arrow_up_small"],"text":null,"texts":null,"category":"Symbols","sort_order":83,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DOWN-POINTING SMALL RED TRIANGLE","unified":"1F53D","non_qualified":null,"docomo":null,"au":"E542","softbank":null,"google":"FEB00","image":"1f53d.png","sheet_x":28,"sheet_y":32,"short_name":"arrow_down_small","short_names":["arrow_down_small"],"text":null,"texts":null,"category":"Symbols","sort_order":85,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F549-FE0F","non_qualified":"1F549","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f549-fe0f.png","sheet_x":28,"sheet_y":33,"short_name":"om_symbol","short_names":["om_symbol"],"text":null,"texts":null,"category":"Symbols","sort_order":50,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F54A-FE0F","non_qualified":"1F54A","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f54a-fe0f.png","sheet_x":28,"sheet_y":34,"short_name":"dove_of_peace","short_names":["dove_of_peace"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":62,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"KAABA","unified":"1F54B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f54b.png","sheet_x":28,"sheet_y":35,"short_name":"kaaba","short_names":["kaaba"],"text":null,"texts":null,"category":"Travel & Places","sort_order":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"MOSQUE","unified":"1F54C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f54c.png","sheet_x":28,"sheet_y":36,"short_name":"mosque","short_names":["mosque"],"text":null,"texts":null,"category":"Travel & Places","sort_order":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SYNAGOGUE","unified":"1F54D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f54d.png","sheet_x":28,"sheet_y":37,"short_name":"synagogue","short_names":["synagogue"],"text":null,"texts":null,"category":"Travel & Places","sort_order":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"MENORAH WITH NINE BRANCHES","unified":"1F54E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f54e.png","sheet_x":28,"sheet_y":38,"short_name":"menorah_with_nine_branches","short_names":["menorah_with_nine_branches"],"text":null,"texts":null,"category":"Symbols","sort_order":58,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CLOCK FACE ONE OCLOCK","unified":"1F550","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E024","google":"FE01E","image":"1f550.png","sheet_x":28,"sheet_y":39,"short_name":"clock1","short_names":["clock1"],"text":null,"texts":null,"category":"Travel & Places","sort_order":136,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE TWO OCLOCK","unified":"1F551","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E025","google":"FE01F","image":"1f551.png","sheet_x":28,"sheet_y":40,"short_name":"clock2","short_names":["clock2"],"text":null,"texts":null,"category":"Travel & Places","sort_order":138,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE THREE OCLOCK","unified":"1F552","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E026","google":"FE020","image":"1f552.png","sheet_x":28,"sheet_y":41,"short_name":"clock3","short_names":["clock3"],"text":null,"texts":null,"category":"Travel & Places","sort_order":140,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE FOUR OCLOCK","unified":"1F553","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E027","google":"FE021","image":"1f553.png","sheet_x":28,"sheet_y":42,"short_name":"clock4","short_names":["clock4"],"text":null,"texts":null,"category":"Travel & Places","sort_order":142,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE FIVE OCLOCK","unified":"1F554","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E028","google":"FE022","image":"1f554.png","sheet_x":28,"sheet_y":43,"short_name":"clock5","short_names":["clock5"],"text":null,"texts":null,"category":"Travel & Places","sort_order":144,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE SIX OCLOCK","unified":"1F555","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E029","google":"FE023","image":"1f555.png","sheet_x":28,"sheet_y":44,"short_name":"clock6","short_names":["clock6"],"text":null,"texts":null,"category":"Travel & Places","sort_order":146,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE SEVEN OCLOCK","unified":"1F556","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E02A","google":"FE024","image":"1f556.png","sheet_x":28,"sheet_y":45,"short_name":"clock7","short_names":["clock7"],"text":null,"texts":null,"category":"Travel & Places","sort_order":148,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE EIGHT OCLOCK","unified":"1F557","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E02B","google":"FE025","image":"1f557.png","sheet_x":28,"sheet_y":46,"short_name":"clock8","short_names":["clock8"],"text":null,"texts":null,"category":"Travel & Places","sort_order":150,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE NINE OCLOCK","unified":"1F558","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E02C","google":"FE026","image":"1f558.png","sheet_x":28,"sheet_y":47,"short_name":"clock9","short_names":["clock9"],"text":null,"texts":null,"category":"Travel & Places","sort_order":152,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE TEN OCLOCK","unified":"1F559","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E02D","google":"FE027","image":"1f559.png","sheet_x":28,"sheet_y":48,"short_name":"clock10","short_names":["clock10"],"text":null,"texts":null,"category":"Travel & Places","sort_order":154,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE ELEVEN OCLOCK","unified":"1F55A","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E02E","google":"FE028","image":"1f55a.png","sheet_x":28,"sheet_y":49,"short_name":"clock11","short_names":["clock11"],"text":null,"texts":null,"category":"Travel & Places","sort_order":156,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE TWELVE OCLOCK","unified":"1F55B","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":"E02F","google":"FE029","image":"1f55b.png","sheet_x":28,"sheet_y":50,"short_name":"clock12","short_names":["clock12"],"text":null,"texts":null,"category":"Travel & Places","sort_order":134,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE ONE-THIRTY","unified":"1F55C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f55c.png","sheet_x":28,"sheet_y":51,"short_name":"clock130","short_names":["clock130"],"text":null,"texts":null,"category":"Travel & Places","sort_order":137,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE TWO-THIRTY","unified":"1F55D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f55d.png","sheet_x":28,"sheet_y":52,"short_name":"clock230","short_names":["clock230"],"text":null,"texts":null,"category":"Travel & Places","sort_order":139,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE THREE-THIRTY","unified":"1F55E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f55e.png","sheet_x":29,"sheet_y":0,"short_name":"clock330","short_names":["clock330"],"text":null,"texts":null,"category":"Travel & Places","sort_order":141,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE FOUR-THIRTY","unified":"1F55F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f55f.png","sheet_x":29,"sheet_y":1,"short_name":"clock430","short_names":["clock430"],"text":null,"texts":null,"category":"Travel & Places","sort_order":143,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE FIVE-THIRTY","unified":"1F560","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f560.png","sheet_x":29,"sheet_y":2,"short_name":"clock530","short_names":["clock530"],"text":null,"texts":null,"category":"Travel & Places","sort_order":145,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE SIX-THIRTY","unified":"1F561","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f561.png","sheet_x":29,"sheet_y":3,"short_name":"clock630","short_names":["clock630"],"text":null,"texts":null,"category":"Travel & Places","sort_order":147,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE SEVEN-THIRTY","unified":"1F562","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f562.png","sheet_x":29,"sheet_y":4,"short_name":"clock730","short_names":["clock730"],"text":null,"texts":null,"category":"Travel & Places","sort_order":149,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE EIGHT-THIRTY","unified":"1F563","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f563.png","sheet_x":29,"sheet_y":5,"short_name":"clock830","short_names":["clock830"],"text":null,"texts":null,"category":"Travel & Places","sort_order":151,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE NINE-THIRTY","unified":"1F564","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f564.png","sheet_x":29,"sheet_y":6,"short_name":"clock930","short_names":["clock930"],"text":null,"texts":null,"category":"Travel & Places","sort_order":153,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE TEN-THIRTY","unified":"1F565","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f565.png","sheet_x":29,"sheet_y":7,"short_name":"clock1030","short_names":["clock1030"],"text":null,"texts":null,"category":"Travel & Places","sort_order":155,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE ELEVEN-THIRTY","unified":"1F566","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f566.png","sheet_x":29,"sheet_y":8,"short_name":"clock1130","short_names":["clock1130"],"text":null,"texts":null,"category":"Travel & Places","sort_order":157,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOCK FACE TWELVE-THIRTY","unified":"1F567","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f567.png","sheet_x":29,"sheet_y":9,"short_name":"clock1230","short_names":["clock1230"],"text":null,"texts":null,"category":"Travel & Places","sort_order":135,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F56F-FE0F","non_qualified":"1F56F","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f56f-fe0f.png","sheet_x":29,"sheet_y":10,"short_name":"candle","short_names":["candle"],"text":null,"texts":null,"category":"Objects","sort_order":55,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F570-FE0F","non_qualified":"1F570","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f570-fe0f.png","sheet_x":29,"sheet_y":11,"short_name":"mantelpiece_clock","short_names":["mantelpiece_clock"],"text":null,"texts":null,"category":"Travel & Places","sort_order":133,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F573-FE0F","non_qualified":"1F573","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f573-fe0f.png","sheet_x":29,"sheet_y":12,"short_name":"hole","short_names":["hole"],"text":null,"texts":null,"category":"Smileys & People","sort_order":436,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F574-FE0F","non_qualified":"1F574","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f574-fe0f.png","sheet_x":29,"sheet_y":13,"short_name":"man_in_business_suit_levitating","short_names":["man_in_business_suit_levitating"],"text":null,"texts":null,"category":"Smileys & People","sort_order":274,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F574-1F3FB","non_qualified":null,"image":"1f574-1f3fb.png","sheet_x":29,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F574-1F3FC","non_qualified":null,"image":"1f574-1f3fc.png","sheet_x":29,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F574-1F3FD","non_qualified":null,"image":"1f574-1f3fd.png","sheet_x":29,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F574-1F3FE","non_qualified":null,"image":"1f574-1f3fe.png","sheet_x":29,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F574-1F3FF","non_qualified":null,"image":"1f574-1f3ff.png","sheet_x":29,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F575-FE0F-200D-2640-FE0F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f575-fe0f-200d-2640-fe0f.png","sheet_x":29,"sheet_y":19,"short_name":"female-detective","short_names":["female-detective"],"text":null,"texts":null,"category":"Smileys & People","sort_order":161,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F575-1F3FB-200D-2640-FE0F","non_qualified":"1F575-1F3FB-200D-2640","image":"1f575-1f3fb-200d-2640-fe0f.png","sheet_x":29,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F575-1F3FC-200D-2640-FE0F","non_qualified":"1F575-1F3FC-200D-2640","image":"1f575-1f3fc-200d-2640-fe0f.png","sheet_x":29,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F575-1F3FD-200D-2640-FE0F","non_qualified":"1F575-1F3FD-200D-2640","image":"1f575-1f3fd-200d-2640-fe0f.png","sheet_x":29,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F575-1F3FE-200D-2640-FE0F","non_qualified":"1F575-1F3FE-200D-2640","image":"1f575-1f3fe-200d-2640-fe0f.png","sheet_x":29,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F575-1F3FF-200D-2640-FE0F","non_qualified":"1F575-1F3FF-200D-2640","image":"1f575-1f3ff-200d-2640-fe0f.png","sheet_x":29,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F575-FE0F-200D-2642-FE0F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f575-fe0f-200d-2642-fe0f.png","sheet_x":29,"sheet_y":25,"short_name":"male-detective","short_names":["male-detective"],"text":null,"texts":null,"category":"Smileys & People","sort_order":160,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F575-1F3FB-200D-2642-FE0F","non_qualified":"1F575-1F3FB-200D-2642","image":"1f575-1f3fb-200d-2642-fe0f.png","sheet_x":29,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F575-1F3FC-200D-2642-FE0F","non_qualified":"1F575-1F3FC-200D-2642","image":"1f575-1f3fc-200d-2642-fe0f.png","sheet_x":29,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F575-1F3FD-200D-2642-FE0F","non_qualified":"1F575-1F3FD-200D-2642","image":"1f575-1f3fd-200d-2642-fe0f.png","sheet_x":29,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F575-1F3FE-200D-2642-FE0F","non_qualified":"1F575-1F3FE-200D-2642","image":"1f575-1f3fe-200d-2642-fe0f.png","sheet_x":29,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F575-1F3FF-200D-2642-FE0F","non_qualified":"1F575-1F3FF-200D-2642","image":"1f575-1f3ff-200d-2642-fe0f.png","sheet_x":29,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F575-FE0F"},{"name":null,"unified":"1F575-FE0F","non_qualified":"1F575","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f575-fe0f.png","sheet_x":29,"sheet_y":31,"short_name":"sleuth_or_spy","short_names":["sleuth_or_spy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":159,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F575-1F3FB","non_qualified":null,"image":"1f575-1f3fb.png","sheet_x":29,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F575-1F3FC","non_qualified":null,"image":"1f575-1f3fc.png","sheet_x":29,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F575-1F3FD","non_qualified":null,"image":"1f575-1f3fd.png","sheet_x":29,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F575-1F3FE","non_qualified":null,"image":"1f575-1f3fe.png","sheet_x":29,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F575-1F3FF","non_qualified":null,"image":"1f575-1f3ff.png","sheet_x":29,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoleted_by":"1F575-FE0F-200D-2642-FE0F"},{"name":null,"unified":"1F576-FE0F","non_qualified":"1F576","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f576-fe0f.png","sheet_x":29,"sheet_y":37,"short_name":"dark_sunglasses","short_names":["dark_sunglasses"],"text":null,"texts":null,"category":"Smileys & People","sort_order":438,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F577-FE0F","non_qualified":"1F577","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f577-fe0f.png","sheet_x":29,"sheet_y":38,"short_name":"spider","short_names":["spider"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":98,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F578-FE0F","non_qualified":"1F578","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f578-fe0f.png","sheet_x":29,"sheet_y":39,"short_name":"spider_web","short_names":["spider_web"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":99,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F579-FE0F","non_qualified":"1F579","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f579-fe0f.png","sheet_x":29,"sheet_y":40,"short_name":"joystick","short_names":["joystick"],"text":null,"texts":null,"category":"Activities","sort_order":59,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"MAN DANCING","unified":"1F57A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f57a.png","sheet_x":29,"sheet_y":41,"short_name":"man_dancing","short_names":["man_dancing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":259,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F57A-1F3FB","non_qualified":null,"image":"1f57a-1f3fb.png","sheet_x":29,"sheet_y":42,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F57A-1F3FC","non_qualified":null,"image":"1f57a-1f3fc.png","sheet_x":29,"sheet_y":43,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F57A-1F3FD","non_qualified":null,"image":"1f57a-1f3fd.png","sheet_x":29,"sheet_y":44,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F57A-1F3FE","non_qualified":null,"image":"1f57a-1f3fe.png","sheet_x":29,"sheet_y":45,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F57A-1F3FF","non_qualified":null,"image":"1f57a-1f3ff.png","sheet_x":29,"sheet_y":46,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F587-FE0F","non_qualified":"1F587","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f587-fe0f.png","sheet_x":29,"sheet_y":47,"short_name":"linked_paperclips","short_names":["linked_paperclips"],"text":null,"texts":null,"category":"Objects","sort_order":123,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F58A-FE0F","non_qualified":"1F58A","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f58a-fe0f.png","sheet_x":29,"sheet_y":48,"short_name":"lower_left_ballpoint_pen","short_names":["lower_left_ballpoint_pen"],"text":null,"texts":null,"category":"Objects","sort_order":103,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F58B-FE0F","non_qualified":"1F58B","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f58b-fe0f.png","sheet_x":29,"sheet_y":49,"short_name":"lower_left_fountain_pen","short_names":["lower_left_fountain_pen"],"text":null,"texts":null,"category":"Objects","sort_order":102,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F58C-FE0F","non_qualified":"1F58C","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f58c-fe0f.png","sheet_x":29,"sheet_y":50,"short_name":"lower_left_paintbrush","short_names":["lower_left_paintbrush"],"text":null,"texts":null,"category":"Objects","sort_order":104,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F58D-FE0F","non_qualified":"1F58D","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f58d-fe0f.png","sheet_x":29,"sheet_y":51,"short_name":"lower_left_crayon","short_names":["lower_left_crayon"],"text":null,"texts":null,"category":"Objects","sort_order":105,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F590-FE0F","non_qualified":"1F590","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f590-fe0f.png","sheet_x":29,"sheet_y":52,"short_name":"raised_hand_with_fingers_splayed","short_names":["raised_hand_with_fingers_splayed"],"text":null,"texts":null,"category":"Smileys & People","sort_order":375,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F590-1F3FB","non_qualified":null,"image":"1f590-1f3fb.png","sheet_x":30,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F590-1F3FC","non_qualified":null,"image":"1f590-1f3fc.png","sheet_x":30,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F590-1F3FD","non_qualified":null,"image":"1f590-1f3fd.png","sheet_x":30,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F590-1F3FE","non_qualified":null,"image":"1f590-1f3fe.png","sheet_x":30,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F590-1F3FF","non_qualified":null,"image":"1f590-1f3ff.png","sheet_x":30,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"REVERSED HAND WITH MIDDLE FINGER EXTENDED","unified":"1F595","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f595.png","sheet_x":30,"sheet_y":5,"short_name":"middle_finger","short_names":["middle_finger","reversed_hand_with_middle_finger_extended"],"text":null,"texts":null,"category":"Smileys & People","sort_order":368,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F595-1F3FB","non_qualified":null,"image":"1f595-1f3fb.png","sheet_x":30,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F595-1F3FC","non_qualified":null,"image":"1f595-1f3fc.png","sheet_x":30,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F595-1F3FD","non_qualified":null,"image":"1f595-1f3fd.png","sheet_x":30,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F595-1F3FE","non_qualified":null,"image":"1f595-1f3fe.png","sheet_x":30,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F595-1F3FF","non_qualified":null,"image":"1f595-1f3ff.png","sheet_x":30,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS","unified":"1F596","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f596.png","sheet_x":30,"sheet_y":11,"short_name":"spock-hand","short_names":["spock-hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":372,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F596-1F3FB","non_qualified":null,"image":"1f596-1f3fb.png","sheet_x":30,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F596-1F3FC","non_qualified":null,"image":"1f596-1f3fc.png","sheet_x":30,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F596-1F3FD","non_qualified":null,"image":"1f596-1f3fd.png","sheet_x":30,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F596-1F3FE","non_qualified":null,"image":"1f596-1f3fe.png","sheet_x":30,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F596-1F3FF","non_qualified":null,"image":"1f596-1f3ff.png","sheet_x":30,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"BLACK HEART","unified":"1F5A4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5a4.png","sheet_x":30,"sheet_y":17,"short_name":"black_heart","short_names":["black_heart"],"text":null,"texts":null,"category":"Smileys & People","sort_order":419,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5A5-FE0F","non_qualified":"1F5A5","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5a5-fe0f.png","sheet_x":30,"sheet_y":18,"short_name":"desktop_computer","short_names":["desktop_computer"],"text":null,"texts":null,"category":"Objects","sort_order":34,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5A8-FE0F","non_qualified":"1F5A8","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5a8-fe0f.png","sheet_x":30,"sheet_y":19,"short_name":"printer","short_names":["printer"],"text":null,"texts":null,"category":"Objects","sort_order":35,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5B1-FE0F","non_qualified":"1F5B1","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5b1-fe0f.png","sheet_x":30,"sheet_y":20,"short_name":"three_button_mouse","short_names":["three_button_mouse"],"text":null,"texts":null,"category":"Objects","sort_order":37,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5B2-FE0F","non_qualified":"1F5B2","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5b2-fe0f.png","sheet_x":30,"sheet_y":21,"short_name":"trackball","short_names":["trackball"],"text":null,"texts":null,"category":"Objects","sort_order":38,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5BC-FE0F","non_qualified":"1F5BC","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5bc-fe0f.png","sheet_x":30,"sheet_y":22,"short_name":"frame_with_picture","short_names":["frame_with_picture"],"text":null,"texts":null,"category":"Activities","sort_order":73,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5C2-FE0F","non_qualified":"1F5C2","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5c2-fe0f.png","sheet_x":30,"sheet_y":23,"short_name":"card_index_dividers","short_names":["card_index_dividers"],"text":null,"texts":null,"category":"Objects","sort_order":110,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5C3-FE0F","non_qualified":"1F5C3","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5c3-fe0f.png","sheet_x":30,"sheet_y":24,"short_name":"card_file_box","short_names":["card_file_box"],"text":null,"texts":null,"category":"Objects","sort_order":127,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5C4-FE0F","non_qualified":"1F5C4","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5c4-fe0f.png","sheet_x":30,"sheet_y":25,"short_name":"file_cabinet","short_names":["file_cabinet"],"text":null,"texts":null,"category":"Objects","sort_order":128,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5D1-FE0F","non_qualified":"1F5D1","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5d1-fe0f.png","sheet_x":30,"sheet_y":26,"short_name":"wastebasket","short_names":["wastebasket"],"text":null,"texts":null,"category":"Objects","sort_order":129,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5D2-FE0F","non_qualified":"1F5D2","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5d2-fe0f.png","sheet_x":30,"sheet_y":27,"short_name":"spiral_note_pad","short_names":["spiral_note_pad"],"text":null,"texts":null,"category":"Objects","sort_order":113,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5D3-FE0F","non_qualified":"1F5D3","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5d3-fe0f.png","sheet_x":30,"sheet_y":28,"short_name":"spiral_calendar_pad","short_names":["spiral_calendar_pad"],"text":null,"texts":null,"category":"Objects","sort_order":114,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5DC-FE0F","non_qualified":"1F5DC","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5dc-fe0f.png","sheet_x":30,"sheet_y":29,"short_name":"compression","short_names":["compression"],"text":null,"texts":null,"category":"Objects","sort_order":148,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5DD-FE0F","non_qualified":"1F5DD","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5dd-fe0f.png","sheet_x":30,"sheet_y":30,"short_name":"old_key","short_names":["old_key"],"text":null,"texts":null,"category":"Objects","sort_order":135,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5DE-FE0F","non_qualified":"1F5DE","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5de-fe0f.png","sheet_x":30,"sheet_y":31,"short_name":"rolled_up_newspaper","short_names":["rolled_up_newspaper"],"text":null,"texts":null,"category":"Objects","sort_order":72,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5E1-FE0F","non_qualified":"1F5E1","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5e1-fe0f.png","sheet_x":30,"sheet_y":32,"short_name":"dagger_knife","short_names":["dagger_knife"],"text":null,"texts":null,"category":"Objects","sort_order":140,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5E3-FE0F","non_qualified":"1F5E3","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5e3-fe0f.png","sheet_x":30,"sheet_y":33,"short_name":"speaking_head_in_silhouette","short_names":["speaking_head_in_silhouette"],"text":null,"texts":null,"category":"Smileys & People","sort_order":275,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5E8-FE0F","non_qualified":"1F5E8","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5e8-fe0f.png","sheet_x":30,"sheet_y":34,"short_name":"left_speech_bubble","short_names":["left_speech_bubble"],"text":null,"texts":null,"category":"Smileys & People","sort_order":433,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5EF-FE0F","non_qualified":"1F5EF","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5ef-fe0f.png","sheet_x":30,"sheet_y":35,"short_name":"right_anger_bubble","short_names":["right_anger_bubble"],"text":null,"texts":null,"category":"Smileys & People","sort_order":434,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5F3-FE0F","non_qualified":"1F5F3","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5f3-fe0f.png","sheet_x":30,"sheet_y":36,"short_name":"ballot_box_with_ballot","short_names":["ballot_box_with_ballot"],"text":null,"texts":null,"category":"Objects","sort_order":99,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F5FA-FE0F","non_qualified":"1F5FA","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f5fa-fe0f.png","sheet_x":30,"sheet_y":37,"short_name":"world_map","short_names":["world_map"],"text":null,"texts":null,"category":"Travel & Places","sort_order":5,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"MOUNT FUJI","unified":"1F5FB","non_qualified":null,"docomo":"E740","au":"E5BD","softbank":"E03B","google":"FE4C3","image":"1f5fb.png","sheet_x":30,"sheet_y":38,"short_name":"mount_fuji","short_names":["mount_fuji"],"text":null,"texts":null,"category":"Travel & Places","sort_order":11,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TOKYO TOWER","unified":"1F5FC","non_qualified":null,"docomo":null,"au":"E4C0","softbank":"E509","google":"FE4C4","image":"1f5fc.png","sheet_x":30,"sheet_y":39,"short_name":"tokyo_tower","short_names":["tokyo_tower"],"text":null,"texts":null,"category":"Travel & Places","sort_order":39,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"STATUE OF LIBERTY","unified":"1F5FD","non_qualified":null,"docomo":null,"au":null,"softbank":"E51D","google":"FE4C6","image":"1f5fd.png","sheet_x":30,"sheet_y":40,"short_name":"statue_of_liberty","short_names":["statue_of_liberty"],"text":null,"texts":null,"category":"Travel & Places","sort_order":40,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SILHOUETTE OF JAPAN","unified":"1F5FE","non_qualified":null,"docomo":null,"au":"E572","softbank":null,"google":"FE4C7","image":"1f5fe.png","sheet_x":30,"sheet_y":41,"short_name":"japan","short_names":["japan"],"text":null,"texts":null,"category":"Travel & Places","sort_order":6,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOYAI","unified":"1F5FF","non_qualified":null,"docomo":null,"au":"EB6C","softbank":null,"google":"FE4C8","image":"1f5ff.png","sheet_x":30,"sheet_y":42,"short_name":"moyai","short_names":["moyai"],"text":null,"texts":null,"category":"Objects","sort_order":181,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GRINNING FACE","unified":"1F600","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f600.png","sheet_x":30,"sheet_y":43,"short_name":"grinning","short_names":["grinning"],"text":":D","texts":null,"category":"Smileys & People","sort_order":1,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GRINNING FACE WITH SMILING EYES","unified":"1F601","non_qualified":null,"docomo":"E753","au":"EB80","softbank":"E404","google":"FE333","image":"1f601.png","sheet_x":30,"sheet_y":44,"short_name":"grin","short_names":["grin"],"text":null,"texts":null,"category":"Smileys & People","sort_order":2,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITH TEARS OF JOY","unified":"1F602","non_qualified":null,"docomo":"E72A","au":"EB64","softbank":"E412","google":"FE334","image":"1f602.png","sheet_x":30,"sheet_y":45,"short_name":"joy","short_names":["joy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":3,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING FACE WITH OPEN MOUTH","unified":"1F603","non_qualified":null,"docomo":"E6F0","au":"E471","softbank":"E057","google":"FE330","image":"1f603.png","sheet_x":30,"sheet_y":46,"short_name":"smiley","short_names":["smiley"],"text":":)","texts":["=)","=-)"],"category":"Smileys & People","sort_order":5,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING FACE WITH OPEN MOUTH AND SMILING EYES","unified":"1F604","non_qualified":null,"docomo":"E6F0","au":"E471","softbank":"E415","google":"FE338","image":"1f604.png","sheet_x":30,"sheet_y":47,"short_name":"smile","short_names":["smile"],"text":":)","texts":["C:","c:",":D",":-D"],"category":"Smileys & People","sort_order":6,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING FACE WITH OPEN MOUTH AND COLD SWEAT","unified":"1F605","non_qualified":null,"docomo":"E722","au":"E471-E5B1","softbank":null,"google":"FE331","image":"1f605.png","sheet_x":30,"sheet_y":48,"short_name":"sweat_smile","short_names":["sweat_smile"],"text":null,"texts":null,"category":"Smileys & People","sort_order":7,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES","unified":"1F606","non_qualified":null,"docomo":"E72A","au":"EAC5","softbank":null,"google":"FE332","image":"1f606.png","sheet_x":30,"sheet_y":49,"short_name":"laughing","short_names":["laughing","satisfied"],"text":null,"texts":[":>",":->"],"category":"Smileys & People","sort_order":8,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING FACE WITH HALO","unified":"1F607","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f607.png","sheet_x":30,"sheet_y":50,"short_name":"innocent","short_names":["innocent"],"text":null,"texts":null,"category":"Smileys & People","sort_order":80,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING FACE WITH HORNS","unified":"1F608","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f608.png","sheet_x":30,"sheet_y":51,"short_name":"smiling_imp","short_names":["smiling_imp"],"text":null,"texts":null,"category":"Smileys & People","sort_order":90,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WINKING FACE","unified":"1F609","non_qualified":null,"docomo":"E729","au":"E5C3","softbank":"E405","google":"FE347","image":"1f609.png","sheet_x":30,"sheet_y":52,"short_name":"wink","short_names":["wink"],"text":";)","texts":[";)",";-)"],"category":"Smileys & People","sort_order":9,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING FACE WITH SMILING EYES","unified":"1F60A","non_qualified":null,"docomo":"E6F0","au":"EACD","softbank":"E056","google":"FE335","image":"1f60a.png","sheet_x":31,"sheet_y":0,"short_name":"blush","short_names":["blush"],"text":":)","texts":null,"category":"Smileys & People","sort_order":10,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE SAVOURING DELICIOUS FOOD","unified":"1F60B","non_qualified":null,"docomo":"E752","au":"EACD","softbank":null,"google":"FE32B","image":"1f60b.png","sheet_x":31,"sheet_y":1,"short_name":"yum","short_names":["yum"],"text":null,"texts":null,"category":"Smileys & People","sort_order":11,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RELIEVED FACE","unified":"1F60C","non_qualified":null,"docomo":"E721","au":"EAC5","softbank":"E40A","google":"FE33E","image":"1f60c.png","sheet_x":31,"sheet_y":2,"short_name":"relieved","short_names":["relieved"],"text":null,"texts":null,"category":"Smileys & People","sort_order":38,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING FACE WITH HEART-SHAPED EYES","unified":"1F60D","non_qualified":null,"docomo":"E726","au":"E5C4","softbank":"E106","google":"FE327","image":"1f60d.png","sheet_x":31,"sheet_y":3,"short_name":"heart_eyes","short_names":["heart_eyes"],"text":null,"texts":null,"category":"Smileys & People","sort_order":13,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING FACE WITH SUNGLASSES","unified":"1F60E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f60e.png","sheet_x":31,"sheet_y":4,"short_name":"sunglasses","short_names":["sunglasses"],"text":null,"texts":["8)"],"category":"Smileys & People","sort_order":12,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMIRKING FACE","unified":"1F60F","non_qualified":null,"docomo":"E72C","au":"EABF","softbank":"E402","google":"FE343","image":"1f60f.png","sheet_x":31,"sheet_y":5,"short_name":"smirk","short_names":["smirk"],"text":null,"texts":null,"category":"Smileys & People","sort_order":29,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEUTRAL FACE","unified":"1F610","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f610.png","sheet_x":31,"sheet_y":6,"short_name":"neutral_face","short_names":["neutral_face"],"text":null,"texts":[":|",":-|"],"category":"Smileys & People","sort_order":25,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EXPRESSIONLESS FACE","unified":"1F611","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f611.png","sheet_x":31,"sheet_y":7,"short_name":"expressionless","short_names":["expressionless"],"text":null,"texts":null,"category":"Smileys & People","sort_order":26,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"UNAMUSED FACE","unified":"1F612","non_qualified":null,"docomo":"E725","au":"EAC9","softbank":"E40E","google":"FE326","image":"1f612.png","sheet_x":31,"sheet_y":8,"short_name":"unamused","short_names":["unamused"],"text":":(","texts":null,"category":"Smileys & People","sort_order":43,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITH COLD SWEAT","unified":"1F613","non_qualified":null,"docomo":"E723","au":"E5C6","softbank":"E108","google":"FE344","image":"1f613.png","sheet_x":31,"sheet_y":9,"short_name":"sweat","short_names":["sweat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":44,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PENSIVE FACE","unified":"1F614","non_qualified":null,"docomo":"E720","au":"EAC0","softbank":"E403","google":"FE340","image":"1f614.png","sheet_x":31,"sheet_y":10,"short_name":"pensive","short_names":["pensive"],"text":null,"texts":null,"category":"Smileys & People","sort_order":45,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CONFUSED FACE","unified":"1F615","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f615.png","sheet_x":31,"sheet_y":11,"short_name":"confused","short_names":["confused"],"text":null,"texts":[":\\",":-\\",":\/",":-\/"],"category":"Smileys & People","sort_order":46,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CONFOUNDED FACE","unified":"1F616","non_qualified":null,"docomo":"E6F3","au":"EAC3","softbank":"E407","google":"FE33F","image":"1f616.png","sheet_x":31,"sheet_y":12,"short_name":"confounded","short_names":["confounded"],"text":null,"texts":null,"category":"Smileys & People","sort_order":52,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KISSING FACE","unified":"1F617","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f617.png","sheet_x":31,"sheet_y":13,"short_name":"kissing","short_names":["kissing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":16,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE THROWING A KISS","unified":"1F618","non_qualified":null,"docomo":"E726","au":"EACF","softbank":"E418","google":"FE32C","image":"1f618.png","sheet_x":31,"sheet_y":14,"short_name":"kissing_heart","short_names":["kissing_heart"],"text":null,"texts":[":*",":-*"],"category":"Smileys & People","sort_order":14,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KISSING FACE WITH SMILING EYES","unified":"1F619","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f619.png","sheet_x":31,"sheet_y":15,"short_name":"kissing_smiling_eyes","short_names":["kissing_smiling_eyes"],"text":null,"texts":null,"category":"Smileys & People","sort_order":17,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KISSING FACE WITH CLOSED EYES","unified":"1F61A","non_qualified":null,"docomo":"E726","au":"EACE","softbank":"E417","google":"FE32D","image":"1f61a.png","sheet_x":31,"sheet_y":16,"short_name":"kissing_closed_eyes","short_names":["kissing_closed_eyes"],"text":null,"texts":null,"category":"Smileys & People","sort_order":18,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITH STUCK-OUT TONGUE","unified":"1F61B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f61b.png","sheet_x":31,"sheet_y":17,"short_name":"stuck_out_tongue","short_names":["stuck_out_tongue"],"text":":p","texts":[":p",":-p",":P",":-P",":b",":-b"],"category":"Smileys & People","sort_order":39,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITH STUCK-OUT TONGUE AND WINKING EYE","unified":"1F61C","non_qualified":null,"docomo":"E728","au":"E4E7","softbank":"E105","google":"FE329","image":"1f61c.png","sheet_x":31,"sheet_y":18,"short_name":"stuck_out_tongue_winking_eye","short_names":["stuck_out_tongue_winking_eye"],"text":";p","texts":[";p",";-p",";b",";-b",";P",";-P"],"category":"Smileys & People","sort_order":40,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES","unified":"1F61D","non_qualified":null,"docomo":"E728","au":"E4E7","softbank":"E409","google":"FE32A","image":"1f61d.png","sheet_x":31,"sheet_y":19,"short_name":"stuck_out_tongue_closed_eyes","short_names":["stuck_out_tongue_closed_eyes"],"text":null,"texts":null,"category":"Smileys & People","sort_order":41,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DISAPPOINTED FACE","unified":"1F61E","non_qualified":null,"docomo":"E6F2","au":"EAC0","softbank":"E058","google":"FE323","image":"1f61e.png","sheet_x":31,"sheet_y":20,"short_name":"disappointed","short_names":["disappointed"],"text":":(","texts":["):",":(",":-("],"category":"Smileys & People","sort_order":53,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WORRIED FACE","unified":"1F61F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f61f.png","sheet_x":31,"sheet_y":21,"short_name":"worried","short_names":["worried"],"text":null,"texts":null,"category":"Smileys & People","sort_order":54,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ANGRY FACE","unified":"1F620","non_qualified":null,"docomo":"E6F1","au":"E472","softbank":"E059","google":"FE320","image":"1f620.png","sheet_x":31,"sheet_y":22,"short_name":"angry","short_names":["angry"],"text":null,"texts":[">:(",">:-("],"category":"Smileys & People","sort_order":72,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POUTING FACE","unified":"1F621","non_qualified":null,"docomo":"E724","au":"EB5D","softbank":"E416","google":"FE33D","image":"1f621.png","sheet_x":31,"sheet_y":23,"short_name":"rage","short_names":["rage"],"text":null,"texts":null,"category":"Smileys & People","sort_order":71,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CRYING FACE","unified":"1F622","non_qualified":null,"docomo":"E72E","au":"EB69","softbank":"E413","google":"FE339","image":"1f622.png","sheet_x":31,"sheet_y":24,"short_name":"cry","short_names":["cry"],"text":":'(","texts":[":'("],"category":"Smileys & People","sort_order":56,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PERSEVERING FACE","unified":"1F623","non_qualified":null,"docomo":"E72B","au":"EAC2","softbank":"E406","google":"FE33C","image":"1f623.png","sheet_x":31,"sheet_y":25,"short_name":"persevere","short_names":["persevere"],"text":null,"texts":null,"category":"Smileys & People","sort_order":30,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITH LOOK OF TRIUMPH","unified":"1F624","non_qualified":null,"docomo":"E753","au":"EAC1","softbank":null,"google":"FE328","image":"1f624.png","sheet_x":31,"sheet_y":26,"short_name":"triumph","short_names":["triumph"],"text":null,"texts":null,"category":"Smileys & People","sort_order":55,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DISAPPOINTED BUT RELIEVED FACE","unified":"1F625","non_qualified":null,"docomo":"E723","au":"E5C6","softbank":"E401","google":"FE345","image":"1f625.png","sheet_x":31,"sheet_y":27,"short_name":"disappointed_relieved","short_names":["disappointed_relieved"],"text":null,"texts":null,"category":"Smileys & People","sort_order":31,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FROWNING FACE WITH OPEN MOUTH","unified":"1F626","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f626.png","sheet_x":31,"sheet_y":28,"short_name":"frowning","short_names":["frowning"],"text":null,"texts":null,"category":"Smileys & People","sort_order":58,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ANGUISHED FACE","unified":"1F627","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f627.png","sheet_x":31,"sheet_y":29,"short_name":"anguished","short_names":["anguished"],"text":null,"texts":["D:"],"category":"Smileys & People","sort_order":59,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FEARFUL FACE","unified":"1F628","non_qualified":null,"docomo":"E757","au":"EAC6","softbank":"E40B","google":"FE33B","image":"1f628.png","sheet_x":31,"sheet_y":30,"short_name":"fearful","short_names":["fearful"],"text":null,"texts":null,"category":"Smileys & People","sort_order":60,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WEARY FACE","unified":"1F629","non_qualified":null,"docomo":"E6F3","au":"EB67","softbank":null,"google":"FE321","image":"1f629.png","sheet_x":31,"sheet_y":31,"short_name":"weary","short_names":["weary"],"text":null,"texts":null,"category":"Smileys & People","sort_order":61,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SLEEPY FACE","unified":"1F62A","non_qualified":null,"docomo":"E701","au":"EAC4","softbank":"E408","google":"FE342","image":"1f62a.png","sheet_x":31,"sheet_y":32,"short_name":"sleepy","short_names":["sleepy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":35,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TIRED FACE","unified":"1F62B","non_qualified":null,"docomo":"E72B","au":"E474","softbank":null,"google":"FE346","image":"1f62b.png","sheet_x":31,"sheet_y":33,"short_name":"tired_face","short_names":["tired_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":36,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GRIMACING FACE","unified":"1F62C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f62c.png","sheet_x":31,"sheet_y":34,"short_name":"grimacing","short_names":["grimacing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":63,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LOUDLY CRYING FACE","unified":"1F62D","non_qualified":null,"docomo":"E72D","au":"E473","softbank":"E411","google":"FE33A","image":"1f62d.png","sheet_x":31,"sheet_y":35,"short_name":"sob","short_names":["sob"],"text":":'(","texts":null,"category":"Smileys & People","sort_order":57,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITH OPEN MOUTH","unified":"1F62E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f62e.png","sheet_x":31,"sheet_y":36,"short_name":"open_mouth","short_names":["open_mouth"],"text":null,"texts":[":o",":-o",":O",":-O"],"category":"Smileys & People","sort_order":32,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HUSHED FACE","unified":"1F62F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f62f.png","sheet_x":31,"sheet_y":37,"short_name":"hushed","short_names":["hushed"],"text":null,"texts":null,"category":"Smileys & People","sort_order":34,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITH OPEN MOUTH AND COLD SWEAT","unified":"1F630","non_qualified":null,"docomo":"E723","au":"EACB","softbank":"E40F","google":"FE325","image":"1f630.png","sheet_x":31,"sheet_y":38,"short_name":"cold_sweat","short_names":["cold_sweat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":64,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE SCREAMING IN FEAR","unified":"1F631","non_qualified":null,"docomo":"E757","au":"E5C5","softbank":"E107","google":"FE341","image":"1f631.png","sheet_x":31,"sheet_y":39,"short_name":"scream","short_names":["scream"],"text":null,"texts":null,"category":"Smileys & People","sort_order":65,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ASTONISHED FACE","unified":"1F632","non_qualified":null,"docomo":"E6F4","au":"EACA","softbank":"E410","google":"FE322","image":"1f632.png","sheet_x":31,"sheet_y":40,"short_name":"astonished","short_names":["astonished"],"text":null,"texts":null,"category":"Smileys & People","sort_order":49,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FLUSHED FACE","unified":"1F633","non_qualified":null,"docomo":"E72A","au":"EAC8","softbank":"E40D","google":"FE32F","image":"1f633.png","sheet_x":31,"sheet_y":41,"short_name":"flushed","short_names":["flushed"],"text":null,"texts":null,"category":"Smileys & People","sort_order":68,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SLEEPING FACE","unified":"1F634","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f634.png","sheet_x":31,"sheet_y":42,"short_name":"sleeping","short_names":["sleeping"],"text":null,"texts":null,"category":"Smileys & People","sort_order":37,"added_in":"6.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DIZZY FACE","unified":"1F635","non_qualified":null,"docomo":"E6F4","au":"E5AE","softbank":null,"google":"FE324","image":"1f635.png","sheet_x":31,"sheet_y":43,"short_name":"dizzy_face","short_names":["dizzy_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":70,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITHOUT MOUTH","unified":"1F636","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f636.png","sheet_x":31,"sheet_y":44,"short_name":"no_mouth","short_names":["no_mouth"],"text":null,"texts":null,"category":"Smileys & People","sort_order":27,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FACE WITH MEDICAL MASK","unified":"1F637","non_qualified":null,"docomo":null,"au":"EAC7","softbank":"E40C","google":"FE32E","image":"1f637.png","sheet_x":31,"sheet_y":45,"short_name":"mask","short_names":["mask"],"text":null,"texts":null,"category":"Smileys & People","sort_order":74,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GRINNING CAT FACE WITH SMILING EYES","unified":"1F638","non_qualified":null,"docomo":"E753","au":"EB7F","softbank":null,"google":"FE349","image":"1f638.png","sheet_x":31,"sheet_y":46,"short_name":"smile_cat","short_names":["smile_cat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":103,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CAT FACE WITH TEARS OF JOY","unified":"1F639","non_qualified":null,"docomo":"E72A","au":"EB63","softbank":null,"google":"FE34A","image":"1f639.png","sheet_x":31,"sheet_y":47,"short_name":"joy_cat","short_names":["joy_cat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":104,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING CAT FACE WITH OPEN MOUTH","unified":"1F63A","non_qualified":null,"docomo":"E6F0","au":"EB61","softbank":null,"google":"FE348","image":"1f63a.png","sheet_x":31,"sheet_y":48,"short_name":"smiley_cat","short_names":["smiley_cat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":102,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMILING CAT FACE WITH HEART-SHAPED EYES","unified":"1F63B","non_qualified":null,"docomo":"E726","au":"EB65","softbank":null,"google":"FE34C","image":"1f63b.png","sheet_x":31,"sheet_y":49,"short_name":"heart_eyes_cat","short_names":["heart_eyes_cat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":105,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CAT FACE WITH WRY SMILE","unified":"1F63C","non_qualified":null,"docomo":"E753","au":"EB6A","softbank":null,"google":"FE34F","image":"1f63c.png","sheet_x":31,"sheet_y":50,"short_name":"smirk_cat","short_names":["smirk_cat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":106,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"KISSING CAT FACE WITH CLOSED EYES","unified":"1F63D","non_qualified":null,"docomo":"E726","au":"EB60","softbank":null,"google":"FE34B","image":"1f63d.png","sheet_x":31,"sheet_y":51,"short_name":"kissing_cat","short_names":["kissing_cat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":107,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POUTING CAT FACE","unified":"1F63E","non_qualified":null,"docomo":"E724","au":"EB5E","softbank":null,"google":"FE34E","image":"1f63e.png","sheet_x":31,"sheet_y":52,"short_name":"pouting_cat","short_names":["pouting_cat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":110,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CRYING CAT FACE","unified":"1F63F","non_qualified":null,"docomo":"E72E","au":"EB68","softbank":null,"google":"FE34D","image":"1f63f.png","sheet_x":32,"sheet_y":0,"short_name":"crying_cat_face","short_names":["crying_cat_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":109,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WEARY CAT FACE","unified":"1F640","non_qualified":null,"docomo":"E6F3","au":"EB66","softbank":null,"google":"FE350","image":"1f640.png","sheet_x":32,"sheet_y":1,"short_name":"scream_cat","short_names":["scream_cat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":108,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SLIGHTLY FROWNING FACE","unified":"1F641","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f641.png","sheet_x":32,"sheet_y":2,"short_name":"slightly_frowning_face","short_names":["slightly_frowning_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":51,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SLIGHTLY SMILING FACE","unified":"1F642","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f642.png","sheet_x":32,"sheet_y":3,"short_name":"slightly_smiling_face","short_names":["slightly_smiling_face"],"text":null,"texts":[":)","(:",":-)"],"category":"Smileys & People","sort_order":20,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"UPSIDE-DOWN FACE","unified":"1F643","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f643.png","sheet_x":32,"sheet_y":4,"short_name":"upside_down_face","short_names":["upside_down_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FACE WITH ROLLING EYES","unified":"1F644","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f644.png","sheet_x":32,"sheet_y":5,"short_name":"face_with_rolling_eyes","short_names":["face_with_rolling_eyes"],"text":null,"texts":null,"category":"Smileys & People","sort_order":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F645-200D-2640-FE0F","non_qualified":"1F645-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f645-200d-2640-fe0f.png","sheet_x":32,"sheet_y":6,"short_name":"woman-gesturing-no","short_names":["woman-gesturing-no"],"text":null,"texts":null,"category":"Smileys & People","sort_order":227,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F645-1F3FB-200D-2640-FE0F","non_qualified":"1F645-1F3FB-200D-2640","image":"1f645-1f3fb-200d-2640-fe0f.png","sheet_x":32,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F645-1F3FC-200D-2640-FE0F","non_qualified":"1F645-1F3FC-200D-2640","image":"1f645-1f3fc-200d-2640-fe0f.png","sheet_x":32,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F645-1F3FD-200D-2640-FE0F","non_qualified":"1F645-1F3FD-200D-2640","image":"1f645-1f3fd-200d-2640-fe0f.png","sheet_x":32,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F645-1F3FE-200D-2640-FE0F","non_qualified":"1F645-1F3FE-200D-2640","image":"1f645-1f3fe-200d-2640-fe0f.png","sheet_x":32,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F645-1F3FF-200D-2640-FE0F","non_qualified":"1F645-1F3FF-200D-2640","image":"1f645-1f3ff-200d-2640-fe0f.png","sheet_x":32,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F645"},{"name":null,"unified":"1F645-200D-2642-FE0F","non_qualified":"1F645-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f645-200d-2642-fe0f.png","sheet_x":32,"sheet_y":12,"short_name":"man-gesturing-no","short_names":["man-gesturing-no"],"text":null,"texts":null,"category":"Smileys & People","sort_order":226,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F645-1F3FB-200D-2642-FE0F","non_qualified":"1F645-1F3FB-200D-2642","image":"1f645-1f3fb-200d-2642-fe0f.png","sheet_x":32,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F645-1F3FC-200D-2642-FE0F","non_qualified":"1F645-1F3FC-200D-2642","image":"1f645-1f3fc-200d-2642-fe0f.png","sheet_x":32,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F645-1F3FD-200D-2642-FE0F","non_qualified":"1F645-1F3FD-200D-2642","image":"1f645-1f3fd-200d-2642-fe0f.png","sheet_x":32,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F645-1F3FE-200D-2642-FE0F","non_qualified":"1F645-1F3FE-200D-2642","image":"1f645-1f3fe-200d-2642-fe0f.png","sheet_x":32,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F645-1F3FF-200D-2642-FE0F","non_qualified":"1F645-1F3FF-200D-2642","image":"1f645-1f3ff-200d-2642-fe0f.png","sheet_x":32,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"FACE WITH NO GOOD GESTURE","unified":"1F645","non_qualified":null,"docomo":"E72F","au":"EAD7","softbank":"E423","google":"FE351","image":"1f645.png","sheet_x":32,"sheet_y":18,"short_name":"no_good","short_names":["no_good"],"text":null,"texts":null,"category":"Smileys & People","sort_order":225,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F645-1F3FB","non_qualified":null,"image":"1f645-1f3fb.png","sheet_x":32,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F645-1F3FC","non_qualified":null,"image":"1f645-1f3fc.png","sheet_x":32,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F645-1F3FD","non_qualified":null,"image":"1f645-1f3fd.png","sheet_x":32,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F645-1F3FE","non_qualified":null,"image":"1f645-1f3fe.png","sheet_x":32,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F645-1F3FF","non_qualified":null,"image":"1f645-1f3ff.png","sheet_x":32,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F645-200D-2640-FE0F"},{"name":null,"unified":"1F646-200D-2640-FE0F","non_qualified":"1F646-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f646-200d-2640-fe0f.png","sheet_x":32,"sheet_y":24,"short_name":"woman-gesturing-ok","short_names":["woman-gesturing-ok"],"text":null,"texts":null,"category":"Smileys & People","sort_order":230,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F646-1F3FB-200D-2640-FE0F","non_qualified":"1F646-1F3FB-200D-2640","image":"1f646-1f3fb-200d-2640-fe0f.png","sheet_x":32,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F646-1F3FC-200D-2640-FE0F","non_qualified":"1F646-1F3FC-200D-2640","image":"1f646-1f3fc-200d-2640-fe0f.png","sheet_x":32,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F646-1F3FD-200D-2640-FE0F","non_qualified":"1F646-1F3FD-200D-2640","image":"1f646-1f3fd-200d-2640-fe0f.png","sheet_x":32,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F646-1F3FE-200D-2640-FE0F","non_qualified":"1F646-1F3FE-200D-2640","image":"1f646-1f3fe-200d-2640-fe0f.png","sheet_x":32,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F646-1F3FF-200D-2640-FE0F","non_qualified":"1F646-1F3FF-200D-2640","image":"1f646-1f3ff-200d-2640-fe0f.png","sheet_x":32,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F646"},{"name":null,"unified":"1F646-200D-2642-FE0F","non_qualified":"1F646-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f646-200d-2642-fe0f.png","sheet_x":32,"sheet_y":30,"short_name":"man-gesturing-ok","short_names":["man-gesturing-ok"],"text":null,"texts":null,"category":"Smileys & People","sort_order":229,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F646-1F3FB-200D-2642-FE0F","non_qualified":"1F646-1F3FB-200D-2642","image":"1f646-1f3fb-200d-2642-fe0f.png","sheet_x":32,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F646-1F3FC-200D-2642-FE0F","non_qualified":"1F646-1F3FC-200D-2642","image":"1f646-1f3fc-200d-2642-fe0f.png","sheet_x":32,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F646-1F3FD-200D-2642-FE0F","non_qualified":"1F646-1F3FD-200D-2642","image":"1f646-1f3fd-200d-2642-fe0f.png","sheet_x":32,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F646-1F3FE-200D-2642-FE0F","non_qualified":"1F646-1F3FE-200D-2642","image":"1f646-1f3fe-200d-2642-fe0f.png","sheet_x":32,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F646-1F3FF-200D-2642-FE0F","non_qualified":"1F646-1F3FF-200D-2642","image":"1f646-1f3ff-200d-2642-fe0f.png","sheet_x":32,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"FACE WITH OK GESTURE","unified":"1F646","non_qualified":null,"docomo":"E70B","au":"EAD8","softbank":"E424","google":"FE352","image":"1f646.png","sheet_x":32,"sheet_y":36,"short_name":"ok_woman","short_names":["ok_woman"],"text":null,"texts":null,"category":"Smileys & People","sort_order":228,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F646-1F3FB","non_qualified":null,"image":"1f646-1f3fb.png","sheet_x":32,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F646-1F3FC","non_qualified":null,"image":"1f646-1f3fc.png","sheet_x":32,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F646-1F3FD","non_qualified":null,"image":"1f646-1f3fd.png","sheet_x":32,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F646-1F3FE","non_qualified":null,"image":"1f646-1f3fe.png","sheet_x":32,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F646-1F3FF","non_qualified":null,"image":"1f646-1f3ff.png","sheet_x":32,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F646-200D-2640-FE0F"},{"name":null,"unified":"1F647-200D-2640-FE0F","non_qualified":"1F647-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f647-200d-2640-fe0f.png","sheet_x":32,"sheet_y":42,"short_name":"woman-bowing","short_names":["woman-bowing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":239,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F647-1F3FB-200D-2640-FE0F","non_qualified":"1F647-1F3FB-200D-2640","image":"1f647-1f3fb-200d-2640-fe0f.png","sheet_x":32,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F647-1F3FC-200D-2640-FE0F","non_qualified":"1F647-1F3FC-200D-2640","image":"1f647-1f3fc-200d-2640-fe0f.png","sheet_x":32,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F647-1F3FD-200D-2640-FE0F","non_qualified":"1F647-1F3FD-200D-2640","image":"1f647-1f3fd-200d-2640-fe0f.png","sheet_x":32,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F647-1F3FE-200D-2640-FE0F","non_qualified":"1F647-1F3FE-200D-2640","image":"1f647-1f3fe-200d-2640-fe0f.png","sheet_x":32,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F647-1F3FF-200D-2640-FE0F","non_qualified":"1F647-1F3FF-200D-2640","image":"1f647-1f3ff-200d-2640-fe0f.png","sheet_x":32,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F647-200D-2642-FE0F","non_qualified":"1F647-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f647-200d-2642-fe0f.png","sheet_x":32,"sheet_y":48,"short_name":"man-bowing","short_names":["man-bowing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":238,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F647-1F3FB-200D-2642-FE0F","non_qualified":"1F647-1F3FB-200D-2642","image":"1f647-1f3fb-200d-2642-fe0f.png","sheet_x":32,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F647-1F3FC-200D-2642-FE0F","non_qualified":"1F647-1F3FC-200D-2642","image":"1f647-1f3fc-200d-2642-fe0f.png","sheet_x":32,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F647-1F3FD-200D-2642-FE0F","non_qualified":"1F647-1F3FD-200D-2642","image":"1f647-1f3fd-200d-2642-fe0f.png","sheet_x":32,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F647-1F3FE-200D-2642-FE0F","non_qualified":"1F647-1F3FE-200D-2642","image":"1f647-1f3fe-200d-2642-fe0f.png","sheet_x":32,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F647-1F3FF-200D-2642-FE0F","non_qualified":"1F647-1F3FF-200D-2642","image":"1f647-1f3ff-200d-2642-fe0f.png","sheet_x":33,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F647"},{"name":"PERSON BOWING DEEPLY","unified":"1F647","non_qualified":null,"docomo":null,"au":"EAD9","softbank":"E426","google":"FE353","image":"1f647.png","sheet_x":33,"sheet_y":1,"short_name":"bow","short_names":["bow"],"text":null,"texts":null,"category":"Smileys & People","sort_order":237,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F647-1F3FB","non_qualified":null,"image":"1f647-1f3fb.png","sheet_x":33,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F647-1F3FC","non_qualified":null,"image":"1f647-1f3fc.png","sheet_x":33,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F647-1F3FD","non_qualified":null,"image":"1f647-1f3fd.png","sheet_x":33,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F647-1F3FE","non_qualified":null,"image":"1f647-1f3fe.png","sheet_x":33,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F647-1F3FF","non_qualified":null,"image":"1f647-1f3ff.png","sheet_x":33,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F647-200D-2642-FE0F"},{"name":"SEE-NO-EVIL MONKEY","unified":"1F648","non_qualified":null,"docomo":null,"au":"EB50","softbank":null,"google":"FE354","image":"1f648.png","sheet_x":33,"sheet_y":7,"short_name":"see_no_evil","short_names":["see_no_evil"],"text":null,"texts":null,"category":"Smileys & People","sort_order":111,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEAR-NO-EVIL MONKEY","unified":"1F649","non_qualified":null,"docomo":null,"au":"EB52","softbank":null,"google":"FE356","image":"1f649.png","sheet_x":33,"sheet_y":8,"short_name":"hear_no_evil","short_names":["hear_no_evil"],"text":null,"texts":null,"category":"Smileys & People","sort_order":112,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPEAK-NO-EVIL MONKEY","unified":"1F64A","non_qualified":null,"docomo":null,"au":"EB51","softbank":null,"google":"FE355","image":"1f64a.png","sheet_x":33,"sheet_y":9,"short_name":"speak_no_evil","short_names":["speak_no_evil"],"text":null,"texts":null,"category":"Smileys & People","sort_order":113,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F64B-200D-2640-FE0F","non_qualified":"1F64B-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f64b-200d-2640-fe0f.png","sheet_x":33,"sheet_y":10,"short_name":"woman-raising-hand","short_names":["woman-raising-hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":236,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F64B-1F3FB-200D-2640-FE0F","non_qualified":"1F64B-1F3FB-200D-2640","image":"1f64b-1f3fb-200d-2640-fe0f.png","sheet_x":33,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F64B-1F3FC-200D-2640-FE0F","non_qualified":"1F64B-1F3FC-200D-2640","image":"1f64b-1f3fc-200d-2640-fe0f.png","sheet_x":33,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F64B-1F3FD-200D-2640-FE0F","non_qualified":"1F64B-1F3FD-200D-2640","image":"1f64b-1f3fd-200d-2640-fe0f.png","sheet_x":33,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F64B-1F3FE-200D-2640-FE0F","non_qualified":"1F64B-1F3FE-200D-2640","image":"1f64b-1f3fe-200d-2640-fe0f.png","sheet_x":33,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F64B-1F3FF-200D-2640-FE0F","non_qualified":"1F64B-1F3FF-200D-2640","image":"1f64b-1f3ff-200d-2640-fe0f.png","sheet_x":33,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F64B"},{"name":null,"unified":"1F64B-200D-2642-FE0F","non_qualified":"1F64B-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f64b-200d-2642-fe0f.png","sheet_x":33,"sheet_y":16,"short_name":"man-raising-hand","short_names":["man-raising-hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":235,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F64B-1F3FB-200D-2642-FE0F","non_qualified":"1F64B-1F3FB-200D-2642","image":"1f64b-1f3fb-200d-2642-fe0f.png","sheet_x":33,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F64B-1F3FC-200D-2642-FE0F","non_qualified":"1F64B-1F3FC-200D-2642","image":"1f64b-1f3fc-200d-2642-fe0f.png","sheet_x":33,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F64B-1F3FD-200D-2642-FE0F","non_qualified":"1F64B-1F3FD-200D-2642","image":"1f64b-1f3fd-200d-2642-fe0f.png","sheet_x":33,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F64B-1F3FE-200D-2642-FE0F","non_qualified":"1F64B-1F3FE-200D-2642","image":"1f64b-1f3fe-200d-2642-fe0f.png","sheet_x":33,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F64B-1F3FF-200D-2642-FE0F","non_qualified":"1F64B-1F3FF-200D-2642","image":"1f64b-1f3ff-200d-2642-fe0f.png","sheet_x":33,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"HAPPY PERSON RAISING ONE HAND","unified":"1F64B","non_qualified":null,"docomo":null,"au":"EB85","softbank":null,"google":"FE357","image":"1f64b.png","sheet_x":33,"sheet_y":22,"short_name":"raising_hand","short_names":["raising_hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":234,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F64B-1F3FB","non_qualified":null,"image":"1f64b-1f3fb.png","sheet_x":33,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F64B-1F3FC","non_qualified":null,"image":"1f64b-1f3fc.png","sheet_x":33,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F64B-1F3FD","non_qualified":null,"image":"1f64b-1f3fd.png","sheet_x":33,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F64B-1F3FE","non_qualified":null,"image":"1f64b-1f3fe.png","sheet_x":33,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F64B-1F3FF","non_qualified":null,"image":"1f64b-1f3ff.png","sheet_x":33,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F64B-200D-2640-FE0F"},{"name":"PERSON RAISING BOTH HANDS IN CELEBRATION","unified":"1F64C","non_qualified":null,"docomo":null,"au":"EB86","softbank":"E427","google":"FE358","image":"1f64c.png","sheet_x":33,"sheet_y":28,"short_name":"raised_hands","short_names":["raised_hands"],"text":null,"texts":null,"category":"Smileys & People","sort_order":390,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F64C-1F3FB","non_qualified":null,"image":"1f64c-1f3fb.png","sheet_x":33,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F64C-1F3FC","non_qualified":null,"image":"1f64c-1f3fc.png","sheet_x":33,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F64C-1F3FD","non_qualified":null,"image":"1f64c-1f3fd.png","sheet_x":33,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F64C-1F3FE","non_qualified":null,"image":"1f64c-1f3fe.png","sheet_x":33,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F64C-1F3FF","non_qualified":null,"image":"1f64c-1f3ff.png","sheet_x":33,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"1F64D-200D-2640-FE0F","non_qualified":"1F64D-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f64d-200d-2640-fe0f.png","sheet_x":33,"sheet_y":34,"short_name":"woman-frowning","short_names":["woman-frowning"],"text":null,"texts":null,"category":"Smileys & People","sort_order":221,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F64D-1F3FB-200D-2640-FE0F","non_qualified":"1F64D-1F3FB-200D-2640","image":"1f64d-1f3fb-200d-2640-fe0f.png","sheet_x":33,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F64D-1F3FC-200D-2640-FE0F","non_qualified":"1F64D-1F3FC-200D-2640","image":"1f64d-1f3fc-200d-2640-fe0f.png","sheet_x":33,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F64D-1F3FD-200D-2640-FE0F","non_qualified":"1F64D-1F3FD-200D-2640","image":"1f64d-1f3fd-200d-2640-fe0f.png","sheet_x":33,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F64D-1F3FE-200D-2640-FE0F","non_qualified":"1F64D-1F3FE-200D-2640","image":"1f64d-1f3fe-200d-2640-fe0f.png","sheet_x":33,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F64D-1F3FF-200D-2640-FE0F","non_qualified":"1F64D-1F3FF-200D-2640","image":"1f64d-1f3ff-200d-2640-fe0f.png","sheet_x":33,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F64D"},{"name":null,"unified":"1F64D-200D-2642-FE0F","non_qualified":"1F64D-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f64d-200d-2642-fe0f.png","sheet_x":33,"sheet_y":40,"short_name":"man-frowning","short_names":["man-frowning"],"text":null,"texts":null,"category":"Smileys & People","sort_order":220,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F64D-1F3FB-200D-2642-FE0F","non_qualified":"1F64D-1F3FB-200D-2642","image":"1f64d-1f3fb-200d-2642-fe0f.png","sheet_x":33,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F64D-1F3FC-200D-2642-FE0F","non_qualified":"1F64D-1F3FC-200D-2642","image":"1f64d-1f3fc-200d-2642-fe0f.png","sheet_x":33,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F64D-1F3FD-200D-2642-FE0F","non_qualified":"1F64D-1F3FD-200D-2642","image":"1f64d-1f3fd-200d-2642-fe0f.png","sheet_x":33,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F64D-1F3FE-200D-2642-FE0F","non_qualified":"1F64D-1F3FE-200D-2642","image":"1f64d-1f3fe-200d-2642-fe0f.png","sheet_x":33,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F64D-1F3FF-200D-2642-FE0F","non_qualified":"1F64D-1F3FF-200D-2642","image":"1f64d-1f3ff-200d-2642-fe0f.png","sheet_x":33,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"PERSON FROWNING","unified":"1F64D","non_qualified":null,"docomo":"E6F3","au":"EB87","softbank":null,"google":"FE359","image":"1f64d.png","sheet_x":33,"sheet_y":46,"short_name":"person_frowning","short_names":["person_frowning"],"text":null,"texts":null,"category":"Smileys & People","sort_order":219,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F64D-1F3FB","non_qualified":null,"image":"1f64d-1f3fb.png","sheet_x":33,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F64D-1F3FC","non_qualified":null,"image":"1f64d-1f3fc.png","sheet_x":33,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F64D-1F3FD","non_qualified":null,"image":"1f64d-1f3fd.png","sheet_x":33,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F64D-1F3FE","non_qualified":null,"image":"1f64d-1f3fe.png","sheet_x":33,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F64D-1F3FF","non_qualified":null,"image":"1f64d-1f3ff.png","sheet_x":33,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F64D-200D-2640-FE0F"},{"name":null,"unified":"1F64E-200D-2640-FE0F","non_qualified":"1F64E-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f64e-200d-2640-fe0f.png","sheet_x":33,"sheet_y":52,"short_name":"woman-pouting","short_names":["woman-pouting"],"text":null,"texts":null,"category":"Smileys & People","sort_order":224,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F64E-1F3FB-200D-2640-FE0F","non_qualified":"1F64E-1F3FB-200D-2640","image":"1f64e-1f3fb-200d-2640-fe0f.png","sheet_x":34,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F64E-1F3FC-200D-2640-FE0F","non_qualified":"1F64E-1F3FC-200D-2640","image":"1f64e-1f3fc-200d-2640-fe0f.png","sheet_x":34,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F64E-1F3FD-200D-2640-FE0F","non_qualified":"1F64E-1F3FD-200D-2640","image":"1f64e-1f3fd-200d-2640-fe0f.png","sheet_x":34,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F64E-1F3FE-200D-2640-FE0F","non_qualified":"1F64E-1F3FE-200D-2640","image":"1f64e-1f3fe-200d-2640-fe0f.png","sheet_x":34,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F64E-1F3FF-200D-2640-FE0F","non_qualified":"1F64E-1F3FF-200D-2640","image":"1f64e-1f3ff-200d-2640-fe0f.png","sheet_x":34,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F64E"},{"name":null,"unified":"1F64E-200D-2642-FE0F","non_qualified":"1F64E-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f64e-200d-2642-fe0f.png","sheet_x":34,"sheet_y":5,"short_name":"man-pouting","short_names":["man-pouting"],"text":null,"texts":null,"category":"Smileys & People","sort_order":223,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F64E-1F3FB-200D-2642-FE0F","non_qualified":"1F64E-1F3FB-200D-2642","image":"1f64e-1f3fb-200d-2642-fe0f.png","sheet_x":34,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F64E-1F3FC-200D-2642-FE0F","non_qualified":"1F64E-1F3FC-200D-2642","image":"1f64e-1f3fc-200d-2642-fe0f.png","sheet_x":34,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F64E-1F3FD-200D-2642-FE0F","non_qualified":"1F64E-1F3FD-200D-2642","image":"1f64e-1f3fd-200d-2642-fe0f.png","sheet_x":34,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F64E-1F3FE-200D-2642-FE0F","non_qualified":"1F64E-1F3FE-200D-2642","image":"1f64e-1f3fe-200d-2642-fe0f.png","sheet_x":34,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F64E-1F3FF-200D-2642-FE0F","non_qualified":"1F64E-1F3FF-200D-2642","image":"1f64e-1f3ff-200d-2642-fe0f.png","sheet_x":34,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"PERSON WITH POUTING FACE","unified":"1F64E","non_qualified":null,"docomo":"E6F1","au":"EB88","softbank":null,"google":"FE35A","image":"1f64e.png","sheet_x":34,"sheet_y":11,"short_name":"person_with_pouting_face","short_names":["person_with_pouting_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":222,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F64E-1F3FB","non_qualified":null,"image":"1f64e-1f3fb.png","sheet_x":34,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F64E-1F3FC","non_qualified":null,"image":"1f64e-1f3fc.png","sheet_x":34,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F64E-1F3FD","non_qualified":null,"image":"1f64e-1f3fd.png","sheet_x":34,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F64E-1F3FE","non_qualified":null,"image":"1f64e-1f3fe.png","sheet_x":34,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F64E-1F3FF","non_qualified":null,"image":"1f64e-1f3ff.png","sheet_x":34,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F64E-200D-2640-FE0F"},{"name":"PERSON WITH FOLDED HANDS","unified":"1F64F","non_qualified":null,"docomo":null,"au":"EAD2","softbank":"E41D","google":"FE35B","image":"1f64f.png","sheet_x":34,"sheet_y":17,"short_name":"pray","short_names":["pray"],"text":null,"texts":null,"category":"Smileys & People","sort_order":392,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F64F-1F3FB","non_qualified":null,"image":"1f64f-1f3fb.png","sheet_x":34,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F64F-1F3FC","non_qualified":null,"image":"1f64f-1f3fc.png","sheet_x":34,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F64F-1F3FD","non_qualified":null,"image":"1f64f-1f3fd.png","sheet_x":34,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F64F-1F3FE","non_qualified":null,"image":"1f64f-1f3fe.png","sheet_x":34,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F64F-1F3FF","non_qualified":null,"image":"1f64f-1f3ff.png","sheet_x":34,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"ROCKET","unified":"1F680","non_qualified":null,"docomo":null,"au":"E5C8","softbank":"E10D","google":"FE7ED","image":"1f680.png","sheet_x":34,"sheet_y":23,"short_name":"rocket","short_names":["rocket"],"text":null,"texts":null,"category":"Travel & Places","sort_order":123,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HELICOPTER","unified":"1F681","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f681.png","sheet_x":34,"sheet_y":24,"short_name":"helicopter","short_names":["helicopter"],"text":null,"texts":null,"category":"Travel & Places","sort_order":118,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"STEAM LOCOMOTIVE","unified":"1F682","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f682.png","sheet_x":34,"sheet_y":25,"short_name":"steam_locomotive","short_names":["steam_locomotive"],"text":null,"texts":null,"category":"Travel & Places","sort_order":63,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RAILWAY CAR","unified":"1F683","non_qualified":null,"docomo":"E65B","au":"E4B5","softbank":"E01E","google":"FE7DF","image":"1f683.png","sheet_x":34,"sheet_y":26,"short_name":"railway_car","short_names":["railway_car"],"text":null,"texts":null,"category":"Travel & Places","sort_order":64,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HIGH-SPEED TRAIN","unified":"1F684","non_qualified":null,"docomo":"E65D","au":"E4B0","softbank":"E435","google":"FE7E2","image":"1f684.png","sheet_x":34,"sheet_y":27,"short_name":"bullettrain_side","short_names":["bullettrain_side"],"text":null,"texts":null,"category":"Travel & Places","sort_order":65,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HIGH-SPEED TRAIN WITH BULLET NOSE","unified":"1F685","non_qualified":null,"docomo":"E65D","au":"E4B0","softbank":"E01F","google":"FE7E3","image":"1f685.png","sheet_x":34,"sheet_y":28,"short_name":"bullettrain_front","short_names":["bullettrain_front"],"text":null,"texts":null,"category":"Travel & Places","sort_order":66,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TRAIN","unified":"1F686","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f686.png","sheet_x":34,"sheet_y":29,"short_name":"train2","short_names":["train2"],"text":null,"texts":null,"category":"Travel & Places","sort_order":67,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"METRO","unified":"1F687","non_qualified":null,"docomo":"E65C","au":"E5BC","softbank":"E434","google":"FE7E0","image":"1f687.png","sheet_x":34,"sheet_y":30,"short_name":"metro","short_names":["metro"],"text":null,"texts":null,"category":"Travel & Places","sort_order":68,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LIGHT RAIL","unified":"1F688","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f688.png","sheet_x":34,"sheet_y":31,"short_name":"light_rail","short_names":["light_rail"],"text":null,"texts":null,"category":"Travel & Places","sort_order":69,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"STATION","unified":"1F689","non_qualified":null,"docomo":null,"au":"EB6D","softbank":"E039","google":"FE7EC","image":"1f689.png","sheet_x":34,"sheet_y":32,"short_name":"station","short_names":["station"],"text":null,"texts":null,"category":"Travel & Places","sort_order":70,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TRAM","unified":"1F68A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f68a.png","sheet_x":34,"sheet_y":33,"short_name":"tram","short_names":["tram"],"text":null,"texts":null,"category":"Travel & Places","sort_order":71,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TRAM CAR","unified":"1F68B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f68b.png","sheet_x":34,"sheet_y":34,"short_name":"train","short_names":["train"],"text":null,"texts":null,"category":"Travel & Places","sort_order":74,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BUS","unified":"1F68C","non_qualified":null,"docomo":"E660","au":"E4AF","softbank":"E159","google":"FE7E6","image":"1f68c.png","sheet_x":34,"sheet_y":35,"short_name":"bus","short_names":["bus"],"text":null,"texts":null,"category":"Travel & Places","sort_order":75,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ONCOMING BUS","unified":"1F68D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f68d.png","sheet_x":34,"sheet_y":36,"short_name":"oncoming_bus","short_names":["oncoming_bus"],"text":null,"texts":null,"category":"Travel & Places","sort_order":76,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TROLLEYBUS","unified":"1F68E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f68e.png","sheet_x":34,"sheet_y":37,"short_name":"trolleybus","short_names":["trolleybus"],"text":null,"texts":null,"category":"Travel & Places","sort_order":77,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BUS STOP","unified":"1F68F","non_qualified":null,"docomo":null,"au":"E4A7","softbank":"E150","google":"FE7E7","image":"1f68f.png","sheet_x":34,"sheet_y":38,"short_name":"busstop","short_names":["busstop"],"text":null,"texts":null,"category":"Travel & Places","sort_order":95,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MINIBUS","unified":"1F690","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f690.png","sheet_x":34,"sheet_y":39,"short_name":"minibus","short_names":["minibus"],"text":null,"texts":null,"category":"Travel & Places","sort_order":78,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"AMBULANCE","unified":"1F691","non_qualified":null,"docomo":null,"au":"EAE0","softbank":"E431","google":"FE7F3","image":"1f691.png","sheet_x":34,"sheet_y":40,"short_name":"ambulance","short_names":["ambulance"],"text":null,"texts":null,"category":"Travel & Places","sort_order":79,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FIRE ENGINE","unified":"1F692","non_qualified":null,"docomo":null,"au":"EADF","softbank":"E430","google":"FE7F2","image":"1f692.png","sheet_x":34,"sheet_y":41,"short_name":"fire_engine","short_names":["fire_engine"],"text":null,"texts":null,"category":"Travel & Places","sort_order":80,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POLICE CAR","unified":"1F693","non_qualified":null,"docomo":null,"au":"EAE1","softbank":"E432","google":"FE7F4","image":"1f693.png","sheet_x":34,"sheet_y":42,"short_name":"police_car","short_names":["police_car"],"text":null,"texts":null,"category":"Travel & Places","sort_order":81,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ONCOMING POLICE CAR","unified":"1F694","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f694.png","sheet_x":34,"sheet_y":43,"short_name":"oncoming_police_car","short_names":["oncoming_police_car"],"text":null,"texts":null,"category":"Travel & Places","sort_order":82,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TAXI","unified":"1F695","non_qualified":null,"docomo":"E65E","au":"E4B1","softbank":"E15A","google":"FE7EF","image":"1f695.png","sheet_x":34,"sheet_y":44,"short_name":"taxi","short_names":["taxi"],"text":null,"texts":null,"category":"Travel & Places","sort_order":83,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ONCOMING TAXI","unified":"1F696","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f696.png","sheet_x":34,"sheet_y":45,"short_name":"oncoming_taxi","short_names":["oncoming_taxi"],"text":null,"texts":null,"category":"Travel & Places","sort_order":84,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"AUTOMOBILE","unified":"1F697","non_qualified":null,"docomo":"E65E","au":"E4B1","softbank":"E01B","google":"FE7E4","image":"1f697.png","sheet_x":34,"sheet_y":46,"short_name":"car","short_names":["car","red_car"],"text":null,"texts":null,"category":"Travel & Places","sort_order":85,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ONCOMING AUTOMOBILE","unified":"1F698","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f698.png","sheet_x":34,"sheet_y":47,"short_name":"oncoming_automobile","short_names":["oncoming_automobile"],"text":null,"texts":null,"category":"Travel & Places","sort_order":86,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RECREATIONAL VEHICLE","unified":"1F699","non_qualified":null,"docomo":"E65F","au":"E4B1","softbank":"E42E","google":"FE7E5","image":"1f699.png","sheet_x":34,"sheet_y":48,"short_name":"blue_car","short_names":["blue_car"],"text":null,"texts":null,"category":"Travel & Places","sort_order":87,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DELIVERY TRUCK","unified":"1F69A","non_qualified":null,"docomo":null,"au":"E4B2","softbank":"E42F","google":"FE7F1","image":"1f69a.png","sheet_x":34,"sheet_y":49,"short_name":"truck","short_names":["truck"],"text":null,"texts":null,"category":"Travel & Places","sort_order":88,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ARTICULATED LORRY","unified":"1F69B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f69b.png","sheet_x":34,"sheet_y":50,"short_name":"articulated_lorry","short_names":["articulated_lorry"],"text":null,"texts":null,"category":"Travel & Places","sort_order":89,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TRACTOR","unified":"1F69C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f69c.png","sheet_x":34,"sheet_y":51,"short_name":"tractor","short_names":["tractor"],"text":null,"texts":null,"category":"Travel & Places","sort_order":90,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MONORAIL","unified":"1F69D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f69d.png","sheet_x":34,"sheet_y":52,"short_name":"monorail","short_names":["monorail"],"text":null,"texts":null,"category":"Travel & Places","sort_order":72,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOUNTAIN RAILWAY","unified":"1F69E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f69e.png","sheet_x":35,"sheet_y":0,"short_name":"mountain_railway","short_names":["mountain_railway"],"text":null,"texts":null,"category":"Travel & Places","sort_order":73,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SUSPENSION RAILWAY","unified":"1F69F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f69f.png","sheet_x":35,"sheet_y":1,"short_name":"suspension_railway","short_names":["suspension_railway"],"text":null,"texts":null,"category":"Travel & Places","sort_order":119,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MOUNTAIN CABLEWAY","unified":"1F6A0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6a0.png","sheet_x":35,"sheet_y":2,"short_name":"mountain_cableway","short_names":["mountain_cableway"],"text":null,"texts":null,"category":"Travel & Places","sort_order":120,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"AERIAL TRAMWAY","unified":"1F6A1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6a1.png","sheet_x":35,"sheet_y":3,"short_name":"aerial_tramway","short_names":["aerial_tramway"],"text":null,"texts":null,"category":"Travel & Places","sort_order":121,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SHIP","unified":"1F6A2","non_qualified":null,"docomo":"E661","au":"EA82","softbank":"E202","google":"FE7E8","image":"1f6a2.png","sheet_x":35,"sheet_y":4,"short_name":"ship","short_names":["ship"],"text":null,"texts":null,"category":"Travel & Places","sort_order":112,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F6A3-200D-2640-FE0F","non_qualified":"1F6A3-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6a3-200d-2640-fe0f.png","sheet_x":35,"sheet_y":5,"short_name":"woman-rowing-boat","short_names":["woman-rowing-boat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":290,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F6A3-1F3FB-200D-2640-FE0F","non_qualified":"1F6A3-1F3FB-200D-2640","image":"1f6a3-1f3fb-200d-2640-fe0f.png","sheet_x":35,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F6A3-1F3FC-200D-2640-FE0F","non_qualified":"1F6A3-1F3FC-200D-2640","image":"1f6a3-1f3fc-200d-2640-fe0f.png","sheet_x":35,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F6A3-1F3FD-200D-2640-FE0F","non_qualified":"1F6A3-1F3FD-200D-2640","image":"1f6a3-1f3fd-200d-2640-fe0f.png","sheet_x":35,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F6A3-1F3FE-200D-2640-FE0F","non_qualified":"1F6A3-1F3FE-200D-2640","image":"1f6a3-1f3fe-200d-2640-fe0f.png","sheet_x":35,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F6A3-1F3FF-200D-2640-FE0F","non_qualified":"1F6A3-1F3FF-200D-2640","image":"1f6a3-1f3ff-200d-2640-fe0f.png","sheet_x":35,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F6A3-200D-2642-FE0F","non_qualified":"1F6A3-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6a3-200d-2642-fe0f.png","sheet_x":35,"sheet_y":11,"short_name":"man-rowing-boat","short_names":["man-rowing-boat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":289,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F6A3-1F3FB-200D-2642-FE0F","non_qualified":"1F6A3-1F3FB-200D-2642","image":"1f6a3-1f3fb-200d-2642-fe0f.png","sheet_x":35,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F6A3-1F3FC-200D-2642-FE0F","non_qualified":"1F6A3-1F3FC-200D-2642","image":"1f6a3-1f3fc-200d-2642-fe0f.png","sheet_x":35,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F6A3-1F3FD-200D-2642-FE0F","non_qualified":"1F6A3-1F3FD-200D-2642","image":"1f6a3-1f3fd-200d-2642-fe0f.png","sheet_x":35,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F6A3-1F3FE-200D-2642-FE0F","non_qualified":"1F6A3-1F3FE-200D-2642","image":"1f6a3-1f3fe-200d-2642-fe0f.png","sheet_x":35,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F6A3-1F3FF-200D-2642-FE0F","non_qualified":"1F6A3-1F3FF-200D-2642","image":"1f6a3-1f3ff-200d-2642-fe0f.png","sheet_x":35,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F6A3"},{"name":"ROWBOAT","unified":"1F6A3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6a3.png","sheet_x":35,"sheet_y":17,"short_name":"rowboat","short_names":["rowboat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":288,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F6A3-1F3FB","non_qualified":null,"image":"1f6a3-1f3fb.png","sheet_x":35,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F6A3-1F3FC","non_qualified":null,"image":"1f6a3-1f3fc.png","sheet_x":35,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F6A3-1F3FD","non_qualified":null,"image":"1f6a3-1f3fd.png","sheet_x":35,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F6A3-1F3FE","non_qualified":null,"image":"1f6a3-1f3fe.png","sheet_x":35,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F6A3-1F3FF","non_qualified":null,"image":"1f6a3-1f3ff.png","sheet_x":35,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoleted_by":"1F6A3-200D-2642-FE0F"},{"name":"SPEEDBOAT","unified":"1F6A4","non_qualified":null,"docomo":"E6A3","au":"E4B4","softbank":"E135","google":"FE7EE","image":"1f6a4.png","sheet_x":35,"sheet_y":23,"short_name":"speedboat","short_names":["speedboat"],"text":null,"texts":null,"category":"Travel & Places","sort_order":108,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HORIZONTAL TRAFFIC LIGHT","unified":"1F6A5","non_qualified":null,"docomo":"E66D","au":"E46A","softbank":"E14E","google":"FE7F7","image":"1f6a5.png","sheet_x":35,"sheet_y":24,"short_name":"traffic_light","short_names":["traffic_light"],"text":null,"texts":null,"category":"Travel & Places","sort_order":101,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"VERTICAL TRAFFIC LIGHT","unified":"1F6A6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6a6.png","sheet_x":35,"sheet_y":25,"short_name":"vertical_traffic_light","short_names":["vertical_traffic_light"],"text":null,"texts":null,"category":"Travel & Places","sort_order":102,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CONSTRUCTION SIGN","unified":"1F6A7","non_qualified":null,"docomo":null,"au":"E5D7","softbank":"E137","google":"FE7F8","image":"1f6a7.png","sheet_x":35,"sheet_y":26,"short_name":"construction","short_names":["construction"],"text":null,"texts":null,"category":"Travel & Places","sort_order":104,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POLICE CARS REVOLVING LIGHT","unified":"1F6A8","non_qualified":null,"docomo":null,"au":"EB73","softbank":null,"google":"FE7F9","image":"1f6a8.png","sheet_x":35,"sheet_y":27,"short_name":"rotating_light","short_names":["rotating_light"],"text":null,"texts":null,"category":"Travel & Places","sort_order":100,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TRIANGULAR FLAG ON POST","unified":"1F6A9","non_qualified":null,"docomo":"E6DE","au":"EB2C","softbank":null,"google":"FEB22","image":"1f6a9.png","sheet_x":35,"sheet_y":28,"short_name":"triangular_flag_on_post","short_names":["triangular_flag_on_post"],"text":null,"texts":null,"category":"Flags","sort_order":2,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DOOR","unified":"1F6AA","non_qualified":null,"docomo":"E714","au":null,"softbank":null,"google":"FE4F3","image":"1f6aa.png","sheet_x":35,"sheet_y":29,"short_name":"door","short_names":["door"],"text":null,"texts":null,"category":"Objects","sort_order":163,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NO ENTRY SIGN","unified":"1F6AB","non_qualified":null,"docomo":"E738","au":"E541","softbank":null,"google":"FEB48","image":"1f6ab.png","sheet_x":35,"sheet_y":30,"short_name":"no_entry_sign","short_names":["no_entry_sign"],"text":null,"texts":null,"category":"Symbols","sort_order":17,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SMOKING SYMBOL","unified":"1F6AC","non_qualified":null,"docomo":"E67F","au":"E47D","softbank":"E30E","google":"FEB1E","image":"1f6ac.png","sheet_x":35,"sheet_y":31,"short_name":"smoking","short_names":["smoking"],"text":null,"texts":null,"category":"Objects","sort_order":178,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NO SMOKING SYMBOL","unified":"1F6AD","non_qualified":null,"docomo":"E680","au":"E47E","softbank":"E208","google":"FEB1F","image":"1f6ad.png","sheet_x":35,"sheet_y":32,"short_name":"no_smoking","short_names":["no_smoking"],"text":null,"texts":null,"category":"Symbols","sort_order":19,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PUT LITTER IN ITS PLACE SYMBOL","unified":"1F6AE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6ae.png","sheet_x":35,"sheet_y":33,"short_name":"put_litter_in_its_place","short_names":["put_litter_in_its_place"],"text":null,"texts":null,"category":"Symbols","sort_order":2,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DO NOT LITTER SYMBOL","unified":"1F6AF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6af.png","sheet_x":35,"sheet_y":34,"short_name":"do_not_litter","short_names":["do_not_litter"],"text":null,"texts":null,"category":"Symbols","sort_order":20,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"POTABLE WATER SYMBOL","unified":"1F6B0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b0.png","sheet_x":35,"sheet_y":35,"short_name":"potable_water","short_names":["potable_water"],"text":null,"texts":null,"category":"Symbols","sort_order":3,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NON-POTABLE WATER SYMBOL","unified":"1F6B1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b1.png","sheet_x":35,"sheet_y":36,"short_name":"non-potable_water","short_names":["non-potable_water"],"text":null,"texts":null,"category":"Symbols","sort_order":21,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BICYCLE","unified":"1F6B2","non_qualified":null,"docomo":"E71D","au":"E4AE","softbank":"E136","google":"FE7EB","image":"1f6b2.png","sheet_x":35,"sheet_y":37,"short_name":"bike","short_names":["bike"],"text":null,"texts":null,"category":"Travel & Places","sort_order":91,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NO BICYCLES","unified":"1F6B3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b3.png","sheet_x":35,"sheet_y":38,"short_name":"no_bicycles","short_names":["no_bicycles"],"text":null,"texts":null,"category":"Symbols","sort_order":18,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F6B4-200D-2640-FE0F","non_qualified":"1F6B4-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b4-200d-2640-fe0f.png","sheet_x":35,"sheet_y":39,"short_name":"woman-biking","short_names":["woman-biking"],"text":null,"texts":null,"category":"Smileys & People","sort_order":302,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F6B4-1F3FB-200D-2640-FE0F","non_qualified":"1F6B4-1F3FB-200D-2640","image":"1f6b4-1f3fb-200d-2640-fe0f.png","sheet_x":35,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F6B4-1F3FC-200D-2640-FE0F","non_qualified":"1F6B4-1F3FC-200D-2640","image":"1f6b4-1f3fc-200d-2640-fe0f.png","sheet_x":35,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F6B4-1F3FD-200D-2640-FE0F","non_qualified":"1F6B4-1F3FD-200D-2640","image":"1f6b4-1f3fd-200d-2640-fe0f.png","sheet_x":35,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F6B4-1F3FE-200D-2640-FE0F","non_qualified":"1F6B4-1F3FE-200D-2640","image":"1f6b4-1f3fe-200d-2640-fe0f.png","sheet_x":35,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F6B4-1F3FF-200D-2640-FE0F","non_qualified":"1F6B4-1F3FF-200D-2640","image":"1f6b4-1f3ff-200d-2640-fe0f.png","sheet_x":35,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F6B4-200D-2642-FE0F","non_qualified":"1F6B4-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b4-200d-2642-fe0f.png","sheet_x":35,"sheet_y":45,"short_name":"man-biking","short_names":["man-biking"],"text":null,"texts":null,"category":"Smileys & People","sort_order":301,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F6B4-1F3FB-200D-2642-FE0F","non_qualified":"1F6B4-1F3FB-200D-2642","image":"1f6b4-1f3fb-200d-2642-fe0f.png","sheet_x":35,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F6B4-1F3FC-200D-2642-FE0F","non_qualified":"1F6B4-1F3FC-200D-2642","image":"1f6b4-1f3fc-200d-2642-fe0f.png","sheet_x":35,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F6B4-1F3FD-200D-2642-FE0F","non_qualified":"1F6B4-1F3FD-200D-2642","image":"1f6b4-1f3fd-200d-2642-fe0f.png","sheet_x":35,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F6B4-1F3FE-200D-2642-FE0F","non_qualified":"1F6B4-1F3FE-200D-2642","image":"1f6b4-1f3fe-200d-2642-fe0f.png","sheet_x":35,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F6B4-1F3FF-200D-2642-FE0F","non_qualified":"1F6B4-1F3FF-200D-2642","image":"1f6b4-1f3ff-200d-2642-fe0f.png","sheet_x":35,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F6B4"},{"name":"BICYCLIST","unified":"1F6B4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b4.png","sheet_x":35,"sheet_y":51,"short_name":"bicyclist","short_names":["bicyclist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":300,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F6B4-1F3FB","non_qualified":null,"image":"1f6b4-1f3fb.png","sheet_x":35,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F6B4-1F3FC","non_qualified":null,"image":"1f6b4-1f3fc.png","sheet_x":36,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F6B4-1F3FD","non_qualified":null,"image":"1f6b4-1f3fd.png","sheet_x":36,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F6B4-1F3FE","non_qualified":null,"image":"1f6b4-1f3fe.png","sheet_x":36,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F6B4-1F3FF","non_qualified":null,"image":"1f6b4-1f3ff.png","sheet_x":36,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F6B4-200D-2642-FE0F"},{"name":null,"unified":"1F6B5-200D-2640-FE0F","non_qualified":"1F6B5-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b5-200d-2640-fe0f.png","sheet_x":36,"sheet_y":4,"short_name":"woman-mountain-biking","short_names":["woman-mountain-biking"],"text":null,"texts":null,"category":"Smileys & People","sort_order":305,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F6B5-1F3FB-200D-2640-FE0F","non_qualified":"1F6B5-1F3FB-200D-2640","image":"1f6b5-1f3fb-200d-2640-fe0f.png","sheet_x":36,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F6B5-1F3FC-200D-2640-FE0F","non_qualified":"1F6B5-1F3FC-200D-2640","image":"1f6b5-1f3fc-200d-2640-fe0f.png","sheet_x":36,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F6B5-1F3FD-200D-2640-FE0F","non_qualified":"1F6B5-1F3FD-200D-2640","image":"1f6b5-1f3fd-200d-2640-fe0f.png","sheet_x":36,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F6B5-1F3FE-200D-2640-FE0F","non_qualified":"1F6B5-1F3FE-200D-2640","image":"1f6b5-1f3fe-200d-2640-fe0f.png","sheet_x":36,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F6B5-1F3FF-200D-2640-FE0F","non_qualified":"1F6B5-1F3FF-200D-2640","image":"1f6b5-1f3ff-200d-2640-fe0f.png","sheet_x":36,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F6B5-200D-2642-FE0F","non_qualified":"1F6B5-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b5-200d-2642-fe0f.png","sheet_x":36,"sheet_y":10,"short_name":"man-mountain-biking","short_names":["man-mountain-biking"],"text":null,"texts":null,"category":"Smileys & People","sort_order":304,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F6B5-1F3FB-200D-2642-FE0F","non_qualified":"1F6B5-1F3FB-200D-2642","image":"1f6b5-1f3fb-200d-2642-fe0f.png","sheet_x":36,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F6B5-1F3FC-200D-2642-FE0F","non_qualified":"1F6B5-1F3FC-200D-2642","image":"1f6b5-1f3fc-200d-2642-fe0f.png","sheet_x":36,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F6B5-1F3FD-200D-2642-FE0F","non_qualified":"1F6B5-1F3FD-200D-2642","image":"1f6b5-1f3fd-200d-2642-fe0f.png","sheet_x":36,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F6B5-1F3FE-200D-2642-FE0F","non_qualified":"1F6B5-1F3FE-200D-2642","image":"1f6b5-1f3fe-200d-2642-fe0f.png","sheet_x":36,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F6B5-1F3FF-200D-2642-FE0F","non_qualified":"1F6B5-1F3FF-200D-2642","image":"1f6b5-1f3ff-200d-2642-fe0f.png","sheet_x":36,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F6B5"},{"name":"MOUNTAIN BICYCLIST","unified":"1F6B5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b5.png","sheet_x":36,"sheet_y":16,"short_name":"mountain_bicyclist","short_names":["mountain_bicyclist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":303,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F6B5-1F3FB","non_qualified":null,"image":"1f6b5-1f3fb.png","sheet_x":36,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F6B5-1F3FC","non_qualified":null,"image":"1f6b5-1f3fc.png","sheet_x":36,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F6B5-1F3FD","non_qualified":null,"image":"1f6b5-1f3fd.png","sheet_x":36,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F6B5-1F3FE","non_qualified":null,"image":"1f6b5-1f3fe.png","sheet_x":36,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F6B5-1F3FF","non_qualified":null,"image":"1f6b5-1f3ff.png","sheet_x":36,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F6B5-200D-2642-FE0F"},{"name":null,"unified":"1F6B6-200D-2640-FE0F","non_qualified":"1F6B6-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b6-200d-2640-fe0f.png","sheet_x":36,"sheet_y":22,"short_name":"woman-walking","short_names":["woman-walking"],"text":null,"texts":null,"category":"Smileys & People","sort_order":254,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F6B6-1F3FB-200D-2640-FE0F","non_qualified":"1F6B6-1F3FB-200D-2640","image":"1f6b6-1f3fb-200d-2640-fe0f.png","sheet_x":36,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F6B6-1F3FC-200D-2640-FE0F","non_qualified":"1F6B6-1F3FC-200D-2640","image":"1f6b6-1f3fc-200d-2640-fe0f.png","sheet_x":36,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F6B6-1F3FD-200D-2640-FE0F","non_qualified":"1F6B6-1F3FD-200D-2640","image":"1f6b6-1f3fd-200d-2640-fe0f.png","sheet_x":36,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F6B6-1F3FE-200D-2640-FE0F","non_qualified":"1F6B6-1F3FE-200D-2640","image":"1f6b6-1f3fe-200d-2640-fe0f.png","sheet_x":36,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F6B6-1F3FF-200D-2640-FE0F","non_qualified":"1F6B6-1F3FF-200D-2640","image":"1f6b6-1f3ff-200d-2640-fe0f.png","sheet_x":36,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F6B6-200D-2642-FE0F","non_qualified":"1F6B6-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b6-200d-2642-fe0f.png","sheet_x":36,"sheet_y":28,"short_name":"man-walking","short_names":["man-walking"],"text":null,"texts":null,"category":"Smileys & People","sort_order":253,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F6B6-1F3FB-200D-2642-FE0F","non_qualified":"1F6B6-1F3FB-200D-2642","image":"1f6b6-1f3fb-200d-2642-fe0f.png","sheet_x":36,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F6B6-1F3FC-200D-2642-FE0F","non_qualified":"1F6B6-1F3FC-200D-2642","image":"1f6b6-1f3fc-200d-2642-fe0f.png","sheet_x":36,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F6B6-1F3FD-200D-2642-FE0F","non_qualified":"1F6B6-1F3FD-200D-2642","image":"1f6b6-1f3fd-200d-2642-fe0f.png","sheet_x":36,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F6B6-1F3FE-200D-2642-FE0F","non_qualified":"1F6B6-1F3FE-200D-2642","image":"1f6b6-1f3fe-200d-2642-fe0f.png","sheet_x":36,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F6B6-1F3FF-200D-2642-FE0F","non_qualified":"1F6B6-1F3FF-200D-2642","image":"1f6b6-1f3ff-200d-2642-fe0f.png","sheet_x":36,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"1F6B6"},{"name":"PEDESTRIAN","unified":"1F6B6","non_qualified":null,"docomo":"E733","au":"EB72","softbank":"E201","google":"FE7F0","image":"1f6b6.png","sheet_x":36,"sheet_y":34,"short_name":"walking","short_names":["walking"],"text":null,"texts":null,"category":"Smileys & People","sort_order":252,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F6B6-1F3FB","non_qualified":null,"image":"1f6b6-1f3fb.png","sheet_x":36,"sheet_y":35,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FC":{"unified":"1F6B6-1F3FC","non_qualified":null,"image":"1f6b6-1f3fc.png","sheet_x":36,"sheet_y":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FD":{"unified":"1F6B6-1F3FD","non_qualified":null,"image":"1f6b6-1f3fd.png","sheet_x":36,"sheet_y":37,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FE":{"unified":"1F6B6-1F3FE","non_qualified":null,"image":"1f6b6-1f3fe.png","sheet_x":36,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true},"1F3FF":{"unified":"1F6B6-1F3FF","non_qualified":null,"image":"1f6b6-1f3ff.png","sheet_x":36,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":true}},"obsoleted_by":"1F6B6-200D-2642-FE0F"},{"name":"NO PEDESTRIANS","unified":"1F6B7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b7.png","sheet_x":36,"sheet_y":40,"short_name":"no_pedestrians","short_names":["no_pedestrians"],"text":null,"texts":null,"category":"Symbols","sort_order":22,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CHILDREN CROSSING","unified":"1F6B8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6b8.png","sheet_x":36,"sheet_y":41,"short_name":"children_crossing","short_names":["children_crossing"],"text":null,"texts":null,"category":"Symbols","sort_order":15,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MENS SYMBOL","unified":"1F6B9","non_qualified":null,"docomo":null,"au":null,"softbank":"E138","google":"FEB33","image":"1f6b9.png","sheet_x":36,"sheet_y":42,"short_name":"mens","short_names":["mens"],"text":null,"texts":null,"category":"Symbols","sort_order":5,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WOMENS SYMBOL","unified":"1F6BA","non_qualified":null,"docomo":null,"au":null,"softbank":"E139","google":"FEB34","image":"1f6ba.png","sheet_x":36,"sheet_y":43,"short_name":"womens","short_names":["womens"],"text":null,"texts":null,"category":"Symbols","sort_order":6,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RESTROOM","unified":"1F6BB","non_qualified":null,"docomo":"E66E","au":"E4A5","softbank":"E151","google":"FE506","image":"1f6bb.png","sheet_x":36,"sheet_y":44,"short_name":"restroom","short_names":["restroom"],"text":null,"texts":null,"category":"Symbols","sort_order":7,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BABY SYMBOL","unified":"1F6BC","non_qualified":null,"docomo":null,"au":"EB18","softbank":"E13A","google":"FEB35","image":"1f6bc.png","sheet_x":36,"sheet_y":45,"short_name":"baby_symbol","short_names":["baby_symbol"],"text":null,"texts":null,"category":"Symbols","sort_order":8,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TOILET","unified":"1F6BD","non_qualified":null,"docomo":"E66E","au":"E4A5","softbank":"E140","google":"FE507","image":"1f6bd.png","sheet_x":36,"sheet_y":46,"short_name":"toilet","short_names":["toilet"],"text":null,"texts":null,"category":"Objects","sort_order":166,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WATER CLOSET","unified":"1F6BE","non_qualified":null,"docomo":"E66E","au":"E4A5","softbank":"E309","google":"FE508","image":"1f6be.png","sheet_x":36,"sheet_y":47,"short_name":"wc","short_names":["wc"],"text":null,"texts":null,"category":"Symbols","sort_order":9,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SHOWER","unified":"1F6BF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6bf.png","sheet_x":36,"sheet_y":48,"short_name":"shower","short_names":["shower"],"text":null,"texts":null,"category":"Objects","sort_order":167,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BATH","unified":"1F6C0","non_qualified":null,"docomo":"E6F7","au":"E5D8","softbank":"E13F","google":"FE505","image":"1f6c0.png","sheet_x":36,"sheet_y":49,"short_name":"bath","short_names":["bath"],"text":null,"texts":null,"category":"Smileys & People","sort_order":272,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"1F6C0-1F3FB","non_qualified":null,"image":"1f6c0-1f3fb.png","sheet_x":36,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F6C0-1F3FC","non_qualified":null,"image":"1f6c0-1f3fc.png","sheet_x":36,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F6C0-1F3FD","non_qualified":null,"image":"1f6c0-1f3fd.png","sheet_x":36,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F6C0-1F3FE","non_qualified":null,"image":"1f6c0-1f3fe.png","sheet_x":37,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F6C0-1F3FF","non_qualified":null,"image":"1f6c0-1f3ff.png","sheet_x":37,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"BATHTUB","unified":"1F6C1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6c1.png","sheet_x":37,"sheet_y":2,"short_name":"bathtub","short_names":["bathtub"],"text":null,"texts":null,"category":"Objects","sort_order":168,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PASSPORT CONTROL","unified":"1F6C2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6c2.png","sheet_x":37,"sheet_y":3,"short_name":"passport_control","short_names":["passport_control"],"text":null,"texts":null,"category":"Symbols","sort_order":10,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CUSTOMS","unified":"1F6C3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6c3.png","sheet_x":37,"sheet_y":4,"short_name":"customs","short_names":["customs"],"text":null,"texts":null,"category":"Symbols","sort_order":11,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BAGGAGE CLAIM","unified":"1F6C4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6c4.png","sheet_x":37,"sheet_y":5,"short_name":"baggage_claim","short_names":["baggage_claim"],"text":null,"texts":null,"category":"Symbols","sort_order":12,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEFT LUGGAGE","unified":"1F6C5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6c5.png","sheet_x":37,"sheet_y":6,"short_name":"left_luggage","short_names":["left_luggage"],"text":null,"texts":null,"category":"Symbols","sort_order":13,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"1F6CB-FE0F","non_qualified":"1F6CB","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6cb-fe0f.png","sheet_x":37,"sheet_y":7,"short_name":"couch_and_lamp","short_names":["couch_and_lamp"],"text":null,"texts":null,"category":"Objects","sort_order":165,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SLEEPING ACCOMMODATION","unified":"1F6CC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6cc.png","sheet_x":37,"sheet_y":8,"short_name":"sleeping_accommodation","short_names":["sleeping_accommodation"],"text":null,"texts":null,"category":"Smileys & People","sort_order":273,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F6CC-1F3FB","non_qualified":null,"image":"1f6cc-1f3fb.png","sheet_x":37,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F6CC-1F3FC","non_qualified":null,"image":"1f6cc-1f3fc.png","sheet_x":37,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F6CC-1F3FD","non_qualified":null,"image":"1f6cc-1f3fd.png","sheet_x":37,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F6CC-1F3FE","non_qualified":null,"image":"1f6cc-1f3fe.png","sheet_x":37,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F6CC-1F3FF","non_qualified":null,"image":"1f6cc-1f3ff.png","sheet_x":37,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F6CD-FE0F","non_qualified":"1F6CD","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6cd-fe0f.png","sheet_x":37,"sheet_y":14,"short_name":"shopping_bags","short_names":["shopping_bags"],"text":null,"texts":null,"category":"Smileys & People","sort_order":455,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6CE-FE0F","non_qualified":"1F6CE","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6ce-fe0f.png","sheet_x":37,"sheet_y":15,"short_name":"bellhop_bell","short_names":["bellhop_bell"],"text":null,"texts":null,"category":"Travel & Places","sort_order":125,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6CF-FE0F","non_qualified":"1F6CF","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6cf-fe0f.png","sheet_x":37,"sheet_y":16,"short_name":"bed","short_names":["bed"],"text":null,"texts":null,"category":"Objects","sort_order":164,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"PLACE OF WORSHIP","unified":"1F6D0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6d0.png","sheet_x":37,"sheet_y":17,"short_name":"place_of_worship","short_names":["place_of_worship"],"text":null,"texts":null,"category":"Symbols","sort_order":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"OCTAGONAL SIGN","unified":"1F6D1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6d1.png","sheet_x":37,"sheet_y":18,"short_name":"octagonal_sign","short_names":["octagonal_sign"],"text":null,"texts":null,"category":"Travel & Places","sort_order":103,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SHOPPING TROLLEY","unified":"1F6D2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6d2.png","sheet_x":37,"sheet_y":19,"short_name":"shopping_trolley","short_names":["shopping_trolley"],"text":null,"texts":null,"category":"Objects","sort_order":177,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6E0-FE0F","non_qualified":"1F6E0","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6e0-fe0f.png","sheet_x":37,"sheet_y":20,"short_name":"hammer_and_wrench","short_names":["hammer_and_wrench"],"text":null,"texts":null,"category":"Objects","sort_order":139,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6E1-FE0F","non_qualified":"1F6E1","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6e1-fe0f.png","sheet_x":37,"sheet_y":21,"short_name":"shield","short_names":["shield"],"text":null,"texts":null,"category":"Objects","sort_order":144,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6E2-FE0F","non_qualified":"1F6E2","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6e2-fe0f.png","sheet_x":37,"sheet_y":22,"short_name":"oil_drum","short_names":["oil_drum"],"text":null,"texts":null,"category":"Travel & Places","sort_order":98,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6E3-FE0F","non_qualified":"1F6E3","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6e3-fe0f.png","sheet_x":37,"sheet_y":23,"short_name":"motorway","short_names":["motorway"],"text":null,"texts":null,"category":"Travel & Places","sort_order":96,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6E4-FE0F","non_qualified":"1F6E4","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6e4-fe0f.png","sheet_x":37,"sheet_y":24,"short_name":"railway_track","short_names":["railway_track"],"text":null,"texts":null,"category":"Travel & Places","sort_order":97,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6E5-FE0F","non_qualified":"1F6E5","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6e5-fe0f.png","sheet_x":37,"sheet_y":25,"short_name":"motor_boat","short_names":["motor_boat"],"text":null,"texts":null,"category":"Travel & Places","sort_order":111,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6E9-FE0F","non_qualified":"1F6E9","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6e9-fe0f.png","sheet_x":37,"sheet_y":26,"short_name":"small_airplane","short_names":["small_airplane"],"text":null,"texts":null,"category":"Travel & Places","sort_order":114,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"AIRPLANE DEPARTURE","unified":"1F6EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6eb.png","sheet_x":37,"sheet_y":27,"short_name":"airplane_departure","short_names":["airplane_departure"],"text":null,"texts":null,"category":"Travel & Places","sort_order":115,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"AIRPLANE ARRIVING","unified":"1F6EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6ec.png","sheet_x":37,"sheet_y":28,"short_name":"airplane_arriving","short_names":["airplane_arriving"],"text":null,"texts":null,"category":"Travel & Places","sort_order":116,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6F0-FE0F","non_qualified":"1F6F0","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6f0-fe0f.png","sheet_x":37,"sheet_y":29,"short_name":"satellite","short_names":["satellite"],"text":null,"texts":null,"category":"Travel & Places","sort_order":122,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F6F3-FE0F","non_qualified":"1F6F3","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6f3-fe0f.png","sheet_x":37,"sheet_y":30,"short_name":"passenger_ship","short_names":["passenger_ship"],"text":null,"texts":null,"category":"Travel & Places","sort_order":109,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SCOOTER","unified":"1F6F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6f4.png","sheet_x":37,"sheet_y":31,"short_name":"scooter","short_names":["scooter"],"text":null,"texts":null,"category":"Travel & Places","sort_order":92,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"MOTOR SCOOTER","unified":"1F6F5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6f5.png","sheet_x":37,"sheet_y":32,"short_name":"motor_scooter","short_names":["motor_scooter"],"text":null,"texts":null,"category":"Travel & Places","sort_order":94,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CANOE","unified":"1F6F6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6f6.png","sheet_x":37,"sheet_y":33,"short_name":"canoe","short_names":["canoe"],"text":null,"texts":null,"category":"Travel & Places","sort_order":107,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SLED","unified":"1F6F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6f7.png","sheet_x":37,"sheet_y":34,"short_name":"sled","short_names":["sled"],"text":null,"texts":null,"category":"Activities","sort_order":52,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FLYING SAUCER","unified":"1F6F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6f8.png","sheet_x":37,"sheet_y":35,"short_name":"flying_saucer","short_names":["flying_saucer"],"text":null,"texts":null,"category":"Travel & Places","sort_order":124,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SKATEBOARD","unified":"1F6F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f6f9.png","sheet_x":37,"sheet_y":36,"short_name":"skateboard","short_names":["skateboard"],"text":null,"texts":null,"category":"Travel & Places","sort_order":93,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"ZIPPER-MOUTH FACE","unified":"1F910","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f910.png","sheet_x":37,"sheet_y":37,"short_name":"zipper_mouth_face","short_names":["zipper_mouth_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"MONEY-MOUTH FACE","unified":"1F911","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f911.png","sheet_x":37,"sheet_y":38,"short_name":"money_mouth_face","short_names":["money_mouth_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FACE WITH THERMOMETER","unified":"1F912","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f912.png","sheet_x":37,"sheet_y":39,"short_name":"face_with_thermometer","short_names":["face_with_thermometer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":75,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"NERD FACE","unified":"1F913","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f913.png","sheet_x":37,"sheet_y":40,"short_name":"nerd_face","short_names":["nerd_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":89,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"THINKING FACE","unified":"1F914","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f914.png","sheet_x":37,"sheet_y":41,"short_name":"thinking_face","short_names":["thinking_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FACE WITH HEAD-BANDAGE","unified":"1F915","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f915.png","sheet_x":37,"sheet_y":42,"short_name":"face_with_head_bandage","short_names":["face_with_head_bandage"],"text":null,"texts":null,"category":"Smileys & People","sort_order":76,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"ROBOT FACE","unified":"1F916","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f916.png","sheet_x":37,"sheet_y":43,"short_name":"robot_face","short_names":["robot_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":100,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"HUGGING FACE","unified":"1F917","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f917.png","sheet_x":37,"sheet_y":44,"short_name":"hugging_face","short_names":["hugging_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SIGN OF THE HORNS","unified":"1F918","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f918.png","sheet_x":37,"sheet_y":45,"short_name":"the_horns","short_names":["the_horns","sign_of_the_horns"],"text":null,"texts":null,"category":"Smileys & People","sort_order":373,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F918-1F3FB","non_qualified":null,"image":"1f918-1f3fb.png","sheet_x":37,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F918-1F3FC","non_qualified":null,"image":"1f918-1f3fc.png","sheet_x":37,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F918-1F3FD","non_qualified":null,"image":"1f918-1f3fd.png","sheet_x":37,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F918-1F3FE","non_qualified":null,"image":"1f918-1f3fe.png","sheet_x":37,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F918-1F3FF","non_qualified":null,"image":"1f918-1f3ff.png","sheet_x":37,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"CALL ME HAND","unified":"1F919","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f919.png","sheet_x":37,"sheet_y":51,"short_name":"call_me_hand","short_names":["call_me_hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":374,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F919-1F3FB","non_qualified":null,"image":"1f919-1f3fb.png","sheet_x":37,"sheet_y":52,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F919-1F3FC","non_qualified":null,"image":"1f919-1f3fc.png","sheet_x":38,"sheet_y":0,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F919-1F3FD","non_qualified":null,"image":"1f919-1f3fd.png","sheet_x":38,"sheet_y":1,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F919-1F3FE","non_qualified":null,"image":"1f919-1f3fe.png","sheet_x":38,"sheet_y":2,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F919-1F3FF","non_qualified":null,"image":"1f919-1f3ff.png","sheet_x":38,"sheet_y":3,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"RAISED BACK OF HAND","unified":"1F91A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f91a.png","sheet_x":38,"sheet_y":4,"short_name":"raised_back_of_hand","short_names":["raised_back_of_hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":384,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F91A-1F3FB","non_qualified":null,"image":"1f91a-1f3fb.png","sheet_x":38,"sheet_y":5,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F91A-1F3FC","non_qualified":null,"image":"1f91a-1f3fc.png","sheet_x":38,"sheet_y":6,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F91A-1F3FD","non_qualified":null,"image":"1f91a-1f3fd.png","sheet_x":38,"sheet_y":7,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F91A-1F3FE","non_qualified":null,"image":"1f91a-1f3fe.png","sheet_x":38,"sheet_y":8,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F91A-1F3FF","non_qualified":null,"image":"1f91a-1f3ff.png","sheet_x":38,"sheet_y":9,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"LEFT-FACING FIST","unified":"1F91B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f91b.png","sheet_x":38,"sheet_y":10,"short_name":"left-facing_fist","short_names":["left-facing_fist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":382,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F91B-1F3FB","non_qualified":null,"image":"1f91b-1f3fb.png","sheet_x":38,"sheet_y":11,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F91B-1F3FC","non_qualified":null,"image":"1f91b-1f3fc.png","sheet_x":38,"sheet_y":12,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F91B-1F3FD","non_qualified":null,"image":"1f91b-1f3fd.png","sheet_x":38,"sheet_y":13,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F91B-1F3FE","non_qualified":null,"image":"1f91b-1f3fe.png","sheet_x":38,"sheet_y":14,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F91B-1F3FF","non_qualified":null,"image":"1f91b-1f3ff.png","sheet_x":38,"sheet_y":15,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"RIGHT-FACING FIST","unified":"1F91C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f91c.png","sheet_x":38,"sheet_y":16,"short_name":"right-facing_fist","short_names":["right-facing_fist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":383,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F91C-1F3FB","non_qualified":null,"image":"1f91c-1f3fb.png","sheet_x":38,"sheet_y":17,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F91C-1F3FC","non_qualified":null,"image":"1f91c-1f3fc.png","sheet_x":38,"sheet_y":18,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F91C-1F3FD","non_qualified":null,"image":"1f91c-1f3fd.png","sheet_x":38,"sheet_y":19,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F91C-1F3FE","non_qualified":null,"image":"1f91c-1f3fe.png","sheet_x":38,"sheet_y":20,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F91C-1F3FF","non_qualified":null,"image":"1f91c-1f3ff.png","sheet_x":38,"sheet_y":21,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"HANDSHAKE","unified":"1F91D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f91d.png","sheet_x":38,"sheet_y":22,"short_name":"handshake","short_names":["handshake"],"text":null,"texts":null,"category":"Smileys & People","sort_order":393,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"HAND WITH INDEX AND MIDDLE FINGERS CROSSED","unified":"1F91E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f91e.png","sheet_x":38,"sheet_y":23,"short_name":"crossed_fingers","short_names":["crossed_fingers","hand_with_index_and_middle_fingers_crossed"],"text":null,"texts":null,"category":"Smileys & People","sort_order":371,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F91E-1F3FB","non_qualified":null,"image":"1f91e-1f3fb.png","sheet_x":38,"sheet_y":24,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F91E-1F3FC","non_qualified":null,"image":"1f91e-1f3fc.png","sheet_x":38,"sheet_y":25,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F91E-1F3FD","non_qualified":null,"image":"1f91e-1f3fd.png","sheet_x":38,"sheet_y":26,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F91E-1F3FE","non_qualified":null,"image":"1f91e-1f3fe.png","sheet_x":38,"sheet_y":27,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F91E-1F3FF","non_qualified":null,"image":"1f91e-1f3ff.png","sheet_x":38,"sheet_y":28,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"I LOVE YOU HAND SIGN","unified":"1F91F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f91f.png","sheet_x":38,"sheet_y":29,"short_name":"i_love_you_hand_sign","short_names":["i_love_you_hand_sign"],"text":null,"texts":null,"category":"Smileys & People","sort_order":386,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F91F-1F3FB","non_qualified":null,"image":"1f91f-1f3fb.png","sheet_x":38,"sheet_y":30,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F91F-1F3FC","non_qualified":null,"image":"1f91f-1f3fc.png","sheet_x":38,"sheet_y":31,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F91F-1F3FD","non_qualified":null,"image":"1f91f-1f3fd.png","sheet_x":38,"sheet_y":32,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F91F-1F3FE","non_qualified":null,"image":"1f91f-1f3fe.png","sheet_x":38,"sheet_y":33,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F91F-1F3FF","non_qualified":null,"image":"1f91f-1f3ff.png","sheet_x":38,"sheet_y":34,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"FACE WITH COWBOY HAT","unified":"1F920","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f920.png","sheet_x":38,"sheet_y":35,"short_name":"face_with_cowboy_hat","short_names":["face_with_cowboy_hat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":81,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CLOWN FACE","unified":"1F921","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f921.png","sheet_x":38,"sheet_y":36,"short_name":"clown_face","short_names":["clown_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":92,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"NAUSEATED FACE","unified":"1F922","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f922.png","sheet_x":38,"sheet_y":37,"short_name":"nauseated_face","short_names":["nauseated_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":77,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"ROLLING ON THE FLOOR LAUGHING","unified":"1F923","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f923.png","sheet_x":38,"sheet_y":38,"short_name":"rolling_on_the_floor_laughing","short_names":["rolling_on_the_floor_laughing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":4,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"DROOLING FACE","unified":"1F924","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f924.png","sheet_x":38,"sheet_y":39,"short_name":"drooling_face","short_names":["drooling_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":42,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"LYING FACE","unified":"1F925","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f925.png","sheet_x":38,"sheet_y":40,"short_name":"lying_face","short_names":["lying_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":85,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F926-200D-2640-FE0F","non_qualified":"1F926-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f926-200d-2640-fe0f.png","sheet_x":38,"sheet_y":41,"short_name":"woman-facepalming","short_names":["woman-facepalming"],"text":null,"texts":null,"category":"Smileys & People","sort_order":242,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F926-1F3FB-200D-2640-FE0F","non_qualified":"1F926-1F3FB-200D-2640","image":"1f926-1f3fb-200d-2640-fe0f.png","sheet_x":38,"sheet_y":42,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F926-1F3FC-200D-2640-FE0F","non_qualified":"1F926-1F3FC-200D-2640","image":"1f926-1f3fc-200d-2640-fe0f.png","sheet_x":38,"sheet_y":43,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F926-1F3FD-200D-2640-FE0F","non_qualified":"1F926-1F3FD-200D-2640","image":"1f926-1f3fd-200d-2640-fe0f.png","sheet_x":38,"sheet_y":44,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F926-1F3FE-200D-2640-FE0F","non_qualified":"1F926-1F3FE-200D-2640","image":"1f926-1f3fe-200d-2640-fe0f.png","sheet_x":38,"sheet_y":45,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F926-1F3FF-200D-2640-FE0F","non_qualified":"1F926-1F3FF-200D-2640","image":"1f926-1f3ff-200d-2640-fe0f.png","sheet_x":38,"sheet_y":46,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F926-200D-2642-FE0F","non_qualified":"1F926-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f926-200d-2642-fe0f.png","sheet_x":38,"sheet_y":47,"short_name":"man-facepalming","short_names":["man-facepalming"],"text":null,"texts":null,"category":"Smileys & People","sort_order":241,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F926-1F3FB-200D-2642-FE0F","non_qualified":"1F926-1F3FB-200D-2642","image":"1f926-1f3fb-200d-2642-fe0f.png","sheet_x":38,"sheet_y":48,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F926-1F3FC-200D-2642-FE0F","non_qualified":"1F926-1F3FC-200D-2642","image":"1f926-1f3fc-200d-2642-fe0f.png","sheet_x":38,"sheet_y":49,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F926-1F3FD-200D-2642-FE0F","non_qualified":"1F926-1F3FD-200D-2642","image":"1f926-1f3fd-200d-2642-fe0f.png","sheet_x":38,"sheet_y":50,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F926-1F3FE-200D-2642-FE0F","non_qualified":"1F926-1F3FE-200D-2642","image":"1f926-1f3fe-200d-2642-fe0f.png","sheet_x":38,"sheet_y":51,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F926-1F3FF-200D-2642-FE0F","non_qualified":"1F926-1F3FF-200D-2642","image":"1f926-1f3ff-200d-2642-fe0f.png","sheet_x":38,"sheet_y":52,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"FACE PALM","unified":"1F926","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f926.png","sheet_x":39,"sheet_y":0,"short_name":"face_palm","short_names":["face_palm"],"text":null,"texts":null,"category":"Smileys & People","sort_order":240,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F926-1F3FB","non_qualified":null,"image":"1f926-1f3fb.png","sheet_x":39,"sheet_y":1,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F926-1F3FC","non_qualified":null,"image":"1f926-1f3fc.png","sheet_x":39,"sheet_y":2,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F926-1F3FD","non_qualified":null,"image":"1f926-1f3fd.png","sheet_x":39,"sheet_y":3,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F926-1F3FE","non_qualified":null,"image":"1f926-1f3fe.png","sheet_x":39,"sheet_y":4,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F926-1F3FF","non_qualified":null,"image":"1f926-1f3ff.png","sheet_x":39,"sheet_y":5,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"SNEEZING FACE","unified":"1F927","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f927.png","sheet_x":39,"sheet_y":6,"short_name":"sneezing_face","short_names":["sneezing_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":79,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FACE WITH ONE EYEBROW RAISED","unified":"1F928","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f928.png","sheet_x":39,"sheet_y":7,"short_name":"face_with_raised_eyebrow","short_names":["face_with_raised_eyebrow","face_with_one_eyebrow_raised"],"text":null,"texts":null,"category":"Smileys & People","sort_order":24,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"GRINNING FACE WITH STAR EYES","unified":"1F929","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f929.png","sheet_x":39,"sheet_y":8,"short_name":"star-struck","short_names":["star-struck","grinning_face_with_star_eyes"],"text":null,"texts":null,"category":"Smileys & People","sort_order":22,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"GRINNING FACE WITH ONE LARGE AND ONE SMALL EYE","unified":"1F92A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f92a.png","sheet_x":39,"sheet_y":9,"short_name":"zany_face","short_names":["zany_face","grinning_face_with_one_large_and_one_small_eye"],"text":null,"texts":null,"category":"Smileys & People","sort_order":69,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FACE WITH FINGER COVERING CLOSED LIPS","unified":"1F92B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f92b.png","sheet_x":39,"sheet_y":10,"short_name":"shushing_face","short_names":["shushing_face","face_with_finger_covering_closed_lips"],"text":null,"texts":null,"category":"Smileys & People","sort_order":86,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SERIOUS FACE WITH SYMBOLS COVERING MOUTH","unified":"1F92C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f92c.png","sheet_x":39,"sheet_y":11,"short_name":"face_with_symbols_on_mouth","short_names":["face_with_symbols_on_mouth","serious_face_with_symbols_covering_mouth"],"text":null,"texts":null,"category":"Smileys & People","sort_order":73,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SMILING FACE WITH SMILING EYES AND HAND COVERING MOUTH","unified":"1F92D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f92d.png","sheet_x":39,"sheet_y":12,"short_name":"face_with_hand_over_mouth","short_names":["face_with_hand_over_mouth","smiling_face_with_smiling_eyes_and_hand_covering_mouth"],"text":null,"texts":null,"category":"Smileys & People","sort_order":87,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FACE WITH OPEN MOUTH VOMITING","unified":"1F92E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f92e.png","sheet_x":39,"sheet_y":13,"short_name":"face_vomiting","short_names":["face_vomiting","face_with_open_mouth_vomiting"],"text":null,"texts":null,"category":"Smileys & People","sort_order":78,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SHOCKED FACE WITH EXPLODING HEAD","unified":"1F92F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f92f.png","sheet_x":39,"sheet_y":14,"short_name":"exploding_head","short_names":["exploding_head","shocked_face_with_exploding_head"],"text":null,"texts":null,"category":"Smileys & People","sort_order":62,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"PREGNANT WOMAN","unified":"1F930","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f930.png","sheet_x":39,"sheet_y":15,"short_name":"pregnant_woman","short_names":["pregnant_woman"],"text":null,"texts":null,"category":"Smileys & People","sort_order":189,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F930-1F3FB","non_qualified":null,"image":"1f930-1f3fb.png","sheet_x":39,"sheet_y":16,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F930-1F3FC","non_qualified":null,"image":"1f930-1f3fc.png","sheet_x":39,"sheet_y":17,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F930-1F3FD","non_qualified":null,"image":"1f930-1f3fd.png","sheet_x":39,"sheet_y":18,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F930-1F3FE","non_qualified":null,"image":"1f930-1f3fe.png","sheet_x":39,"sheet_y":19,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F930-1F3FF","non_qualified":null,"image":"1f930-1f3ff.png","sheet_x":39,"sheet_y":20,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"BREAST-FEEDING","unified":"1F931","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f931.png","sheet_x":39,"sheet_y":21,"short_name":"breast-feeding","short_names":["breast-feeding"],"text":null,"texts":null,"category":"Smileys & People","sort_order":190,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F931-1F3FB","non_qualified":null,"image":"1f931-1f3fb.png","sheet_x":39,"sheet_y":22,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F931-1F3FC","non_qualified":null,"image":"1f931-1f3fc.png","sheet_x":39,"sheet_y":23,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F931-1F3FD","non_qualified":null,"image":"1f931-1f3fd.png","sheet_x":39,"sheet_y":24,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F931-1F3FE","non_qualified":null,"image":"1f931-1f3fe.png","sheet_x":39,"sheet_y":25,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F931-1F3FF","non_qualified":null,"image":"1f931-1f3ff.png","sheet_x":39,"sheet_y":26,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"PALMS UP TOGETHER","unified":"1F932","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f932.png","sheet_x":39,"sheet_y":27,"short_name":"palms_up_together","short_names":["palms_up_together"],"text":null,"texts":null,"category":"Smileys & People","sort_order":391,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F932-1F3FB","non_qualified":null,"image":"1f932-1f3fb.png","sheet_x":39,"sheet_y":28,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F932-1F3FC","non_qualified":null,"image":"1f932-1f3fc.png","sheet_x":39,"sheet_y":29,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F932-1F3FD","non_qualified":null,"image":"1f932-1f3fd.png","sheet_x":39,"sheet_y":30,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F932-1F3FE","non_qualified":null,"image":"1f932-1f3fe.png","sheet_x":39,"sheet_y":31,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F932-1F3FF","non_qualified":null,"image":"1f932-1f3ff.png","sheet_x":39,"sheet_y":32,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"SELFIE","unified":"1F933","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f933.png","sheet_x":39,"sheet_y":33,"short_name":"selfie","short_names":["selfie"],"text":null,"texts":null,"category":"Smileys & People","sort_order":360,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F933-1F3FB","non_qualified":null,"image":"1f933-1f3fb.png","sheet_x":39,"sheet_y":34,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F933-1F3FC","non_qualified":null,"image":"1f933-1f3fc.png","sheet_x":39,"sheet_y":35,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F933-1F3FD","non_qualified":null,"image":"1f933-1f3fd.png","sheet_x":39,"sheet_y":36,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F933-1F3FE","non_qualified":null,"image":"1f933-1f3fe.png","sheet_x":39,"sheet_y":37,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F933-1F3FF","non_qualified":null,"image":"1f933-1f3ff.png","sheet_x":39,"sheet_y":38,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"PRINCE","unified":"1F934","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f934.png","sheet_x":39,"sheet_y":39,"short_name":"prince","short_names":["prince"],"text":null,"texts":null,"category":"Smileys & People","sort_order":168,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F934-1F3FB","non_qualified":null,"image":"1f934-1f3fb.png","sheet_x":39,"sheet_y":40,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F934-1F3FC","non_qualified":null,"image":"1f934-1f3fc.png","sheet_x":39,"sheet_y":41,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F934-1F3FD","non_qualified":null,"image":"1f934-1f3fd.png","sheet_x":39,"sheet_y":42,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F934-1F3FE","non_qualified":null,"image":"1f934-1f3fe.png","sheet_x":39,"sheet_y":43,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F934-1F3FF","non_qualified":null,"image":"1f934-1f3ff.png","sheet_x":39,"sheet_y":44,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"MAN IN TUXEDO","unified":"1F935","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f935.png","sheet_x":39,"sheet_y":45,"short_name":"man_in_tuxedo","short_names":["man_in_tuxedo"],"text":null,"texts":null,"category":"Smileys & People","sort_order":187,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F935-1F3FB","non_qualified":null,"image":"1f935-1f3fb.png","sheet_x":39,"sheet_y":46,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F935-1F3FC","non_qualified":null,"image":"1f935-1f3fc.png","sheet_x":39,"sheet_y":47,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F935-1F3FD","non_qualified":null,"image":"1f935-1f3fd.png","sheet_x":39,"sheet_y":48,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F935-1F3FE","non_qualified":null,"image":"1f935-1f3fe.png","sheet_x":39,"sheet_y":49,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F935-1F3FF","non_qualified":null,"image":"1f935-1f3ff.png","sheet_x":39,"sheet_y":50,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"MOTHER CHRISTMAS","unified":"1F936","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f936.png","sheet_x":39,"sheet_y":51,"short_name":"mrs_claus","short_names":["mrs_claus","mother_christmas"],"text":null,"texts":null,"category":"Smileys & People","sort_order":193,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F936-1F3FB","non_qualified":null,"image":"1f936-1f3fb.png","sheet_x":39,"sheet_y":52,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F936-1F3FC","non_qualified":null,"image":"1f936-1f3fc.png","sheet_x":40,"sheet_y":0,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F936-1F3FD","non_qualified":null,"image":"1f936-1f3fd.png","sheet_x":40,"sheet_y":1,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F936-1F3FE","non_qualified":null,"image":"1f936-1f3fe.png","sheet_x":40,"sheet_y":2,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F936-1F3FF","non_qualified":null,"image":"1f936-1f3ff.png","sheet_x":40,"sheet_y":3,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F937-200D-2640-FE0F","non_qualified":"1F937-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f937-200d-2640-fe0f.png","sheet_x":40,"sheet_y":4,"short_name":"woman-shrugging","short_names":["woman-shrugging"],"text":null,"texts":null,"category":"Smileys & People","sort_order":245,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F937-1F3FB-200D-2640-FE0F","non_qualified":"1F937-1F3FB-200D-2640","image":"1f937-1f3fb-200d-2640-fe0f.png","sheet_x":40,"sheet_y":5,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F937-1F3FC-200D-2640-FE0F","non_qualified":"1F937-1F3FC-200D-2640","image":"1f937-1f3fc-200d-2640-fe0f.png","sheet_x":40,"sheet_y":6,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F937-1F3FD-200D-2640-FE0F","non_qualified":"1F937-1F3FD-200D-2640","image":"1f937-1f3fd-200d-2640-fe0f.png","sheet_x":40,"sheet_y":7,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F937-1F3FE-200D-2640-FE0F","non_qualified":"1F937-1F3FE-200D-2640","image":"1f937-1f3fe-200d-2640-fe0f.png","sheet_x":40,"sheet_y":8,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F937-1F3FF-200D-2640-FE0F","non_qualified":"1F937-1F3FF-200D-2640","image":"1f937-1f3ff-200d-2640-fe0f.png","sheet_x":40,"sheet_y":9,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F937-200D-2642-FE0F","non_qualified":"1F937-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f937-200d-2642-fe0f.png","sheet_x":40,"sheet_y":10,"short_name":"man-shrugging","short_names":["man-shrugging"],"text":null,"texts":null,"category":"Smileys & People","sort_order":244,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F937-1F3FB-200D-2642-FE0F","non_qualified":"1F937-1F3FB-200D-2642","image":"1f937-1f3fb-200d-2642-fe0f.png","sheet_x":40,"sheet_y":11,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F937-1F3FC-200D-2642-FE0F","non_qualified":"1F937-1F3FC-200D-2642","image":"1f937-1f3fc-200d-2642-fe0f.png","sheet_x":40,"sheet_y":12,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F937-1F3FD-200D-2642-FE0F","non_qualified":"1F937-1F3FD-200D-2642","image":"1f937-1f3fd-200d-2642-fe0f.png","sheet_x":40,"sheet_y":13,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F937-1F3FE-200D-2642-FE0F","non_qualified":"1F937-1F3FE-200D-2642","image":"1f937-1f3fe-200d-2642-fe0f.png","sheet_x":40,"sheet_y":14,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F937-1F3FF-200D-2642-FE0F","non_qualified":"1F937-1F3FF-200D-2642","image":"1f937-1f3ff-200d-2642-fe0f.png","sheet_x":40,"sheet_y":15,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"SHRUG","unified":"1F937","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f937.png","sheet_x":40,"sheet_y":16,"short_name":"shrug","short_names":["shrug"],"text":null,"texts":null,"category":"Smileys & People","sort_order":243,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F937-1F3FB","non_qualified":null,"image":"1f937-1f3fb.png","sheet_x":40,"sheet_y":17,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F937-1F3FC","non_qualified":null,"image":"1f937-1f3fc.png","sheet_x":40,"sheet_y":18,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F937-1F3FD","non_qualified":null,"image":"1f937-1f3fd.png","sheet_x":40,"sheet_y":19,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F937-1F3FE","non_qualified":null,"image":"1f937-1f3fe.png","sheet_x":40,"sheet_y":20,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F937-1F3FF","non_qualified":null,"image":"1f937-1f3ff.png","sheet_x":40,"sheet_y":21,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F938-200D-2640-FE0F","non_qualified":"1F938-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f938-200d-2640-fe0f.png","sheet_x":40,"sheet_y":22,"short_name":"woman-cartwheeling","short_names":["woman-cartwheeling"],"text":null,"texts":null,"category":"Smileys & People","sort_order":310,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F938-1F3FB-200D-2640-FE0F","non_qualified":"1F938-1F3FB-200D-2640","image":"1f938-1f3fb-200d-2640-fe0f.png","sheet_x":40,"sheet_y":23,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F938-1F3FC-200D-2640-FE0F","non_qualified":"1F938-1F3FC-200D-2640","image":"1f938-1f3fc-200d-2640-fe0f.png","sheet_x":40,"sheet_y":24,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F938-1F3FD-200D-2640-FE0F","non_qualified":"1F938-1F3FD-200D-2640","image":"1f938-1f3fd-200d-2640-fe0f.png","sheet_x":40,"sheet_y":25,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F938-1F3FE-200D-2640-FE0F","non_qualified":"1F938-1F3FE-200D-2640","image":"1f938-1f3fe-200d-2640-fe0f.png","sheet_x":40,"sheet_y":26,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F938-1F3FF-200D-2640-FE0F","non_qualified":"1F938-1F3FF-200D-2640","image":"1f938-1f3ff-200d-2640-fe0f.png","sheet_x":40,"sheet_y":27,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F938-200D-2642-FE0F","non_qualified":"1F938-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f938-200d-2642-fe0f.png","sheet_x":40,"sheet_y":28,"short_name":"man-cartwheeling","short_names":["man-cartwheeling"],"text":null,"texts":null,"category":"Smileys & People","sort_order":309,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F938-1F3FB-200D-2642-FE0F","non_qualified":"1F938-1F3FB-200D-2642","image":"1f938-1f3fb-200d-2642-fe0f.png","sheet_x":40,"sheet_y":29,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F938-1F3FC-200D-2642-FE0F","non_qualified":"1F938-1F3FC-200D-2642","image":"1f938-1f3fc-200d-2642-fe0f.png","sheet_x":40,"sheet_y":30,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F938-1F3FD-200D-2642-FE0F","non_qualified":"1F938-1F3FD-200D-2642","image":"1f938-1f3fd-200d-2642-fe0f.png","sheet_x":40,"sheet_y":31,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F938-1F3FE-200D-2642-FE0F","non_qualified":"1F938-1F3FE-200D-2642","image":"1f938-1f3fe-200d-2642-fe0f.png","sheet_x":40,"sheet_y":32,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F938-1F3FF-200D-2642-FE0F","non_qualified":"1F938-1F3FF-200D-2642","image":"1f938-1f3ff-200d-2642-fe0f.png","sheet_x":40,"sheet_y":33,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"PERSON DOING CARTWHEEL","unified":"1F938","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f938.png","sheet_x":40,"sheet_y":34,"short_name":"person_doing_cartwheel","short_names":["person_doing_cartwheel"],"text":null,"texts":null,"category":"Smileys & People","sort_order":308,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F938-1F3FB","non_qualified":null,"image":"1f938-1f3fb.png","sheet_x":40,"sheet_y":35,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F938-1F3FC","non_qualified":null,"image":"1f938-1f3fc.png","sheet_x":40,"sheet_y":36,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F938-1F3FD","non_qualified":null,"image":"1f938-1f3fd.png","sheet_x":40,"sheet_y":37,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F938-1F3FE","non_qualified":null,"image":"1f938-1f3fe.png","sheet_x":40,"sheet_y":38,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F938-1F3FF","non_qualified":null,"image":"1f938-1f3ff.png","sheet_x":40,"sheet_y":39,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F939-200D-2640-FE0F","non_qualified":"1F939-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f939-200d-2640-fe0f.png","sheet_x":40,"sheet_y":40,"short_name":"woman-juggling","short_names":["woman-juggling"],"text":null,"texts":null,"category":"Smileys & People","sort_order":322,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F939-1F3FB-200D-2640-FE0F","non_qualified":"1F939-1F3FB-200D-2640","image":"1f939-1f3fb-200d-2640-fe0f.png","sheet_x":40,"sheet_y":41,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F939-1F3FC-200D-2640-FE0F","non_qualified":"1F939-1F3FC-200D-2640","image":"1f939-1f3fc-200d-2640-fe0f.png","sheet_x":40,"sheet_y":42,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F939-1F3FD-200D-2640-FE0F","non_qualified":"1F939-1F3FD-200D-2640","image":"1f939-1f3fd-200d-2640-fe0f.png","sheet_x":40,"sheet_y":43,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F939-1F3FE-200D-2640-FE0F","non_qualified":"1F939-1F3FE-200D-2640","image":"1f939-1f3fe-200d-2640-fe0f.png","sheet_x":40,"sheet_y":44,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F939-1F3FF-200D-2640-FE0F","non_qualified":"1F939-1F3FF-200D-2640","image":"1f939-1f3ff-200d-2640-fe0f.png","sheet_x":40,"sheet_y":45,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F939-200D-2642-FE0F","non_qualified":"1F939-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f939-200d-2642-fe0f.png","sheet_x":40,"sheet_y":46,"short_name":"man-juggling","short_names":["man-juggling"],"text":null,"texts":null,"category":"Smileys & People","sort_order":321,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F939-1F3FB-200D-2642-FE0F","non_qualified":"1F939-1F3FB-200D-2642","image":"1f939-1f3fb-200d-2642-fe0f.png","sheet_x":40,"sheet_y":47,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F939-1F3FC-200D-2642-FE0F","non_qualified":"1F939-1F3FC-200D-2642","image":"1f939-1f3fc-200d-2642-fe0f.png","sheet_x":40,"sheet_y":48,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F939-1F3FD-200D-2642-FE0F","non_qualified":"1F939-1F3FD-200D-2642","image":"1f939-1f3fd-200d-2642-fe0f.png","sheet_x":40,"sheet_y":49,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F939-1F3FE-200D-2642-FE0F","non_qualified":"1F939-1F3FE-200D-2642","image":"1f939-1f3fe-200d-2642-fe0f.png","sheet_x":40,"sheet_y":50,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F939-1F3FF-200D-2642-FE0F","non_qualified":"1F939-1F3FF-200D-2642","image":"1f939-1f3ff-200d-2642-fe0f.png","sheet_x":40,"sheet_y":51,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"JUGGLING","unified":"1F939","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f939.png","sheet_x":40,"sheet_y":52,"short_name":"juggling","short_names":["juggling"],"text":null,"texts":null,"category":"Smileys & People","sort_order":320,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F939-1F3FB","non_qualified":null,"image":"1f939-1f3fb.png","sheet_x":41,"sheet_y":0,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F939-1F3FC","non_qualified":null,"image":"1f939-1f3fc.png","sheet_x":41,"sheet_y":1,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F939-1F3FD","non_qualified":null,"image":"1f939-1f3fd.png","sheet_x":41,"sheet_y":2,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F939-1F3FE","non_qualified":null,"image":"1f939-1f3fe.png","sheet_x":41,"sheet_y":3,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F939-1F3FF","non_qualified":null,"image":"1f939-1f3ff.png","sheet_x":41,"sheet_y":4,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"FENCER","unified":"1F93A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93a.png","sheet_x":41,"sheet_y":5,"short_name":"fencer","short_names":["fencer"],"text":null,"texts":null,"category":"Smileys & People","sort_order":278,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F93C-200D-2640-FE0F","non_qualified":"1F93C-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93c-200d-2640-fe0f.png","sheet_x":41,"sheet_y":6,"short_name":"woman-wrestling","short_names":["woman-wrestling"],"text":null,"texts":null,"category":"Smileys & People","sort_order":313,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F93C-200D-2642-FE0F","non_qualified":"1F93C-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93c-200d-2642-fe0f.png","sheet_x":41,"sheet_y":7,"short_name":"man-wrestling","short_names":["man-wrestling"],"text":null,"texts":null,"category":"Smileys & People","sort_order":312,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"WRESTLERS","unified":"1F93C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93c.png","sheet_x":41,"sheet_y":8,"short_name":"wrestlers","short_names":["wrestlers"],"text":null,"texts":null,"category":"Smileys & People","sort_order":311,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},{"name":null,"unified":"1F93D-200D-2640-FE0F","non_qualified":"1F93D-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93d-200d-2640-fe0f.png","sheet_x":41,"sheet_y":9,"short_name":"woman-playing-water-polo","short_names":["woman-playing-water-polo"],"text":null,"texts":null,"category":"Smileys & People","sort_order":316,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F93D-1F3FB-200D-2640-FE0F","non_qualified":"1F93D-1F3FB-200D-2640","image":"1f93d-1f3fb-200d-2640-fe0f.png","sheet_x":41,"sheet_y":10,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F93D-1F3FC-200D-2640-FE0F","non_qualified":"1F93D-1F3FC-200D-2640","image":"1f93d-1f3fc-200d-2640-fe0f.png","sheet_x":41,"sheet_y":11,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F93D-1F3FD-200D-2640-FE0F","non_qualified":"1F93D-1F3FD-200D-2640","image":"1f93d-1f3fd-200d-2640-fe0f.png","sheet_x":41,"sheet_y":12,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F93D-1F3FE-200D-2640-FE0F","non_qualified":"1F93D-1F3FE-200D-2640","image":"1f93d-1f3fe-200d-2640-fe0f.png","sheet_x":41,"sheet_y":13,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F93D-1F3FF-200D-2640-FE0F","non_qualified":"1F93D-1F3FF-200D-2640","image":"1f93d-1f3ff-200d-2640-fe0f.png","sheet_x":41,"sheet_y":14,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F93D-200D-2642-FE0F","non_qualified":"1F93D-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93d-200d-2642-fe0f.png","sheet_x":41,"sheet_y":15,"short_name":"man-playing-water-polo","short_names":["man-playing-water-polo"],"text":null,"texts":null,"category":"Smileys & People","sort_order":315,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F93D-1F3FB-200D-2642-FE0F","non_qualified":"1F93D-1F3FB-200D-2642","image":"1f93d-1f3fb-200d-2642-fe0f.png","sheet_x":41,"sheet_y":16,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F93D-1F3FC-200D-2642-FE0F","non_qualified":"1F93D-1F3FC-200D-2642","image":"1f93d-1f3fc-200d-2642-fe0f.png","sheet_x":41,"sheet_y":17,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F93D-1F3FD-200D-2642-FE0F","non_qualified":"1F93D-1F3FD-200D-2642","image":"1f93d-1f3fd-200d-2642-fe0f.png","sheet_x":41,"sheet_y":18,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F93D-1F3FE-200D-2642-FE0F","non_qualified":"1F93D-1F3FE-200D-2642","image":"1f93d-1f3fe-200d-2642-fe0f.png","sheet_x":41,"sheet_y":19,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F93D-1F3FF-200D-2642-FE0F","non_qualified":"1F93D-1F3FF-200D-2642","image":"1f93d-1f3ff-200d-2642-fe0f.png","sheet_x":41,"sheet_y":20,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"WATER POLO","unified":"1F93D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93d.png","sheet_x":41,"sheet_y":21,"short_name":"water_polo","short_names":["water_polo"],"text":null,"texts":null,"category":"Smileys & People","sort_order":314,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F93D-1F3FB","non_qualified":null,"image":"1f93d-1f3fb.png","sheet_x":41,"sheet_y":22,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F93D-1F3FC","non_qualified":null,"image":"1f93d-1f3fc.png","sheet_x":41,"sheet_y":23,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F93D-1F3FD","non_qualified":null,"image":"1f93d-1f3fd.png","sheet_x":41,"sheet_y":24,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F93D-1F3FE","non_qualified":null,"image":"1f93d-1f3fe.png","sheet_x":41,"sheet_y":25,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F93D-1F3FF","non_qualified":null,"image":"1f93d-1f3ff.png","sheet_x":41,"sheet_y":26,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F93E-200D-2640-FE0F","non_qualified":"1F93E-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93e-200d-2640-fe0f.png","sheet_x":41,"sheet_y":27,"short_name":"woman-playing-handball","short_names":["woman-playing-handball"],"text":null,"texts":null,"category":"Smileys & People","sort_order":319,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F93E-1F3FB-200D-2640-FE0F","non_qualified":"1F93E-1F3FB-200D-2640","image":"1f93e-1f3fb-200d-2640-fe0f.png","sheet_x":41,"sheet_y":28,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F93E-1F3FC-200D-2640-FE0F","non_qualified":"1F93E-1F3FC-200D-2640","image":"1f93e-1f3fc-200d-2640-fe0f.png","sheet_x":41,"sheet_y":29,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F93E-1F3FD-200D-2640-FE0F","non_qualified":"1F93E-1F3FD-200D-2640","image":"1f93e-1f3fd-200d-2640-fe0f.png","sheet_x":41,"sheet_y":30,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F93E-1F3FE-200D-2640-FE0F","non_qualified":"1F93E-1F3FE-200D-2640","image":"1f93e-1f3fe-200d-2640-fe0f.png","sheet_x":41,"sheet_y":31,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F93E-1F3FF-200D-2640-FE0F","non_qualified":"1F93E-1F3FF-200D-2640","image":"1f93e-1f3ff-200d-2640-fe0f.png","sheet_x":41,"sheet_y":32,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F93E-200D-2642-FE0F","non_qualified":"1F93E-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93e-200d-2642-fe0f.png","sheet_x":41,"sheet_y":33,"short_name":"man-playing-handball","short_names":["man-playing-handball"],"text":null,"texts":null,"category":"Smileys & People","sort_order":318,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F93E-1F3FB-200D-2642-FE0F","non_qualified":"1F93E-1F3FB-200D-2642","image":"1f93e-1f3fb-200d-2642-fe0f.png","sheet_x":41,"sheet_y":34,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F93E-1F3FC-200D-2642-FE0F","non_qualified":"1F93E-1F3FC-200D-2642","image":"1f93e-1f3fc-200d-2642-fe0f.png","sheet_x":41,"sheet_y":35,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F93E-1F3FD-200D-2642-FE0F","non_qualified":"1F93E-1F3FD-200D-2642","image":"1f93e-1f3fd-200d-2642-fe0f.png","sheet_x":41,"sheet_y":36,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F93E-1F3FE-200D-2642-FE0F","non_qualified":"1F93E-1F3FE-200D-2642","image":"1f93e-1f3fe-200d-2642-fe0f.png","sheet_x":41,"sheet_y":37,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F93E-1F3FF-200D-2642-FE0F","non_qualified":"1F93E-1F3FF-200D-2642","image":"1f93e-1f3ff-200d-2642-fe0f.png","sheet_x":41,"sheet_y":38,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"HANDBALL","unified":"1F93E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f93e.png","sheet_x":41,"sheet_y":39,"short_name":"handball","short_names":["handball"],"text":null,"texts":null,"category":"Smileys & People","sort_order":317,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F93E-1F3FB","non_qualified":null,"image":"1f93e-1f3fb.png","sheet_x":41,"sheet_y":40,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F93E-1F3FC","non_qualified":null,"image":"1f93e-1f3fc.png","sheet_x":41,"sheet_y":41,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F93E-1F3FD","non_qualified":null,"image":"1f93e-1f3fd.png","sheet_x":41,"sheet_y":42,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F93E-1F3FE","non_qualified":null,"image":"1f93e-1f3fe.png","sheet_x":41,"sheet_y":43,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F93E-1F3FF","non_qualified":null,"image":"1f93e-1f3ff.png","sheet_x":41,"sheet_y":44,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"WILTED FLOWER","unified":"1F940","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f940.png","sheet_x":41,"sheet_y":45,"short_name":"wilted_flower","short_names":["wilted_flower"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":108,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"DRUM WITH DRUMSTICKS","unified":"1F941","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f941.png","sheet_x":41,"sheet_y":46,"short_name":"drum_with_drumsticks","short_names":["drum_with_drumsticks"],"text":null,"texts":null,"category":"Objects","sort_order":24,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CLINKING GLASSES","unified":"1F942","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f942.png","sheet_x":41,"sheet_y":47,"short_name":"clinking_glasses","short_names":["clinking_glasses"],"text":null,"texts":null,"category":"Food & Drink","sort_order":100,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"TUMBLER GLASS","unified":"1F943","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f943.png","sheet_x":41,"sheet_y":48,"short_name":"tumbler_glass","short_names":["tumbler_glass"],"text":null,"texts":null,"category":"Food & Drink","sort_order":101,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SPOON","unified":"1F944","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f944.png","sheet_x":41,"sheet_y":49,"short_name":"spoon","short_names":["spoon"],"text":null,"texts":null,"category":"Food & Drink","sort_order":106,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"GOAL NET","unified":"1F945","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f945.png","sheet_x":41,"sheet_y":50,"short_name":"goal_net","short_names":["goal_net"],"text":null,"texts":null,"category":"Activities","sort_order":46,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FIRST PLACE MEDAL","unified":"1F947","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f947.png","sheet_x":41,"sheet_y":51,"short_name":"first_place_medal","short_names":["first_place_medal"],"text":null,"texts":null,"category":"Activities","sort_order":25,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SECOND PLACE MEDAL","unified":"1F948","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f948.png","sheet_x":41,"sheet_y":52,"short_name":"second_place_medal","short_names":["second_place_medal"],"text":null,"texts":null,"category":"Activities","sort_order":26,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"THIRD PLACE MEDAL","unified":"1F949","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f949.png","sheet_x":42,"sheet_y":0,"short_name":"third_place_medal","short_names":["third_place_medal"],"text":null,"texts":null,"category":"Activities","sort_order":27,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BOXING GLOVE","unified":"1F94A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f94a.png","sheet_x":42,"sheet_y":1,"short_name":"boxing_glove","short_names":["boxing_glove"],"text":null,"texts":null,"category":"Activities","sort_order":44,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"MARTIAL ARTS UNIFORM","unified":"1F94B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f94b.png","sheet_x":42,"sheet_y":2,"short_name":"martial_arts_uniform","short_names":["martial_arts_uniform"],"text":null,"texts":null,"category":"Activities","sort_order":45,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CURLING STONE","unified":"1F94C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f94c.png","sheet_x":42,"sheet_y":3,"short_name":"curling_stone","short_names":["curling_stone"],"text":null,"texts":null,"category":"Activities","sort_order":53,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"LACROSSE STICK AND BALL","unified":"1F94D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f94d.png","sheet_x":42,"sheet_y":4,"short_name":"lacrosse","short_names":["lacrosse"],"text":null,"texts":null,"category":"Activities","sort_order":41,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"SOFTBALL","unified":"1F94E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f94e.png","sheet_x":42,"sheet_y":5,"short_name":"softball","short_names":["softball"],"text":null,"texts":null,"category":"Activities","sort_order":30,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"FLYING DISC","unified":"1F94F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f94f.png","sheet_x":42,"sheet_y":6,"short_name":"flying_disc","short_names":["flying_disc"],"text":null,"texts":null,"category":"Activities","sort_order":36,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"CROISSANT","unified":"1F950","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f950.png","sheet_x":42,"sheet_y":7,"short_name":"croissant","short_names":["croissant"],"text":null,"texts":null,"category":"Food & Drink","sort_order":31,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"AVOCADO","unified":"1F951","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f951.png","sheet_x":42,"sheet_y":8,"short_name":"avocado","short_names":["avocado"],"text":null,"texts":null,"category":"Food & Drink","sort_order":18,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CUCUMBER","unified":"1F952","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f952.png","sheet_x":42,"sheet_y":9,"short_name":"cucumber","short_names":["cucumber"],"text":null,"texts":null,"category":"Food & Drink","sort_order":24,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BACON","unified":"1F953","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f953.png","sheet_x":42,"sheet_y":10,"short_name":"bacon","short_names":["bacon"],"text":null,"texts":null,"category":"Food & Drink","sort_order":40,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"POTATO","unified":"1F954","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f954.png","sheet_x":42,"sheet_y":11,"short_name":"potato","short_names":["potato"],"text":null,"texts":null,"category":"Food & Drink","sort_order":20,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CARROT","unified":"1F955","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f955.png","sheet_x":42,"sheet_y":12,"short_name":"carrot","short_names":["carrot"],"text":null,"texts":null,"category":"Food & Drink","sort_order":21,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BAGUETTE BREAD","unified":"1F956","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f956.png","sheet_x":42,"sheet_y":13,"short_name":"baguette_bread","short_names":["baguette_bread"],"text":null,"texts":null,"category":"Food & Drink","sort_order":32,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"GREEN SALAD","unified":"1F957","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f957.png","sheet_x":42,"sheet_y":14,"short_name":"green_salad","short_names":["green_salad"],"text":null,"texts":null,"category":"Food & Drink","sort_order":54,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SHALLOW PAN OF FOOD","unified":"1F958","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f958.png","sheet_x":42,"sheet_y":15,"short_name":"shallow_pan_of_food","short_names":["shallow_pan_of_food"],"text":null,"texts":null,"category":"Food & Drink","sort_order":51,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"STUFFED FLATBREAD","unified":"1F959","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f959.png","sheet_x":42,"sheet_y":16,"short_name":"stuffed_flatbread","short_names":["stuffed_flatbread"],"text":null,"texts":null,"category":"Food & Drink","sort_order":48,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"EGG","unified":"1F95A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f95a.png","sheet_x":42,"sheet_y":17,"short_name":"egg","short_names":["egg"],"text":null,"texts":null,"category":"Food & Drink","sort_order":49,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"GLASS OF MILK","unified":"1F95B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f95b.png","sheet_x":42,"sheet_y":18,"short_name":"glass_of_milk","short_names":["glass_of_milk"],"text":null,"texts":null,"category":"Food & Drink","sort_order":90,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"PEANUTS","unified":"1F95C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f95c.png","sheet_x":42,"sheet_y":19,"short_name":"peanuts","short_names":["peanuts"],"text":null,"texts":null,"category":"Food & Drink","sort_order":28,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"KIWIFRUIT","unified":"1F95D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f95d.png","sheet_x":42,"sheet_y":20,"short_name":"kiwifruit","short_names":["kiwifruit"],"text":null,"texts":null,"category":"Food & Drink","sort_order":15,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"PANCAKES","unified":"1F95E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f95e.png","sheet_x":42,"sheet_y":21,"short_name":"pancakes","short_names":["pancakes"],"text":null,"texts":null,"category":"Food & Drink","sort_order":35,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"DUMPLING","unified":"1F95F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f95f.png","sheet_x":42,"sheet_y":22,"short_name":"dumpling","short_names":["dumpling"],"text":null,"texts":null,"category":"Food & Drink","sort_order":72,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FORTUNE COOKIE","unified":"1F960","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f960.png","sheet_x":42,"sheet_y":23,"short_name":"fortune_cookie","short_names":["fortune_cookie"],"text":null,"texts":null,"category":"Food & Drink","sort_order":73,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"TAKEOUT BOX","unified":"1F961","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f961.png","sheet_x":42,"sheet_y":24,"short_name":"takeout_box","short_names":["takeout_box"],"text":null,"texts":null,"category":"Food & Drink","sort_order":74,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CHOPSTICKS","unified":"1F962","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f962.png","sheet_x":42,"sheet_y":25,"short_name":"chopsticks","short_names":["chopsticks"],"text":null,"texts":null,"category":"Food & Drink","sort_order":103,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BOWL WITH SPOON","unified":"1F963","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f963.png","sheet_x":42,"sheet_y":26,"short_name":"bowl_with_spoon","short_names":["bowl_with_spoon"],"text":null,"texts":null,"category":"Food & Drink","sort_order":53,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CUP WITH STRAW","unified":"1F964","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f964.png","sheet_x":42,"sheet_y":27,"short_name":"cup_with_straw","short_names":["cup_with_straw"],"text":null,"texts":null,"category":"Food & Drink","sort_order":102,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"COCONUT","unified":"1F965","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f965.png","sheet_x":42,"sheet_y":28,"short_name":"coconut","short_names":["coconut"],"text":null,"texts":null,"category":"Food & Drink","sort_order":17,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BROCCOLI","unified":"1F966","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f966.png","sheet_x":42,"sheet_y":29,"short_name":"broccoli","short_names":["broccoli"],"text":null,"texts":null,"category":"Food & Drink","sort_order":26,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"PIE","unified":"1F967","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f967.png","sheet_x":42,"sheet_y":30,"short_name":"pie","short_names":["pie"],"text":null,"texts":null,"category":"Food & Drink","sort_order":83,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"PRETZEL","unified":"1F968","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f968.png","sheet_x":42,"sheet_y":31,"short_name":"pretzel","short_names":["pretzel"],"text":null,"texts":null,"category":"Food & Drink","sort_order":33,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CUT OF MEAT","unified":"1F969","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f969.png","sheet_x":42,"sheet_y":32,"short_name":"cut_of_meat","short_names":["cut_of_meat"],"text":null,"texts":null,"category":"Food & Drink","sort_order":39,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SANDWICH","unified":"1F96A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f96a.png","sheet_x":42,"sheet_y":33,"short_name":"sandwich","short_names":["sandwich"],"text":null,"texts":null,"category":"Food & Drink","sort_order":45,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CANNED FOOD","unified":"1F96B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f96b.png","sheet_x":42,"sheet_y":34,"short_name":"canned_food","short_names":["canned_food"],"text":null,"texts":null,"category":"Food & Drink","sort_order":57,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"LEAFY GREEN","unified":"1F96C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f96c.png","sheet_x":42,"sheet_y":35,"short_name":"leafy_green","short_names":["leafy_green"],"text":null,"texts":null,"category":"Food & Drink","sort_order":25,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"MANGO","unified":"1F96D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f96d.png","sheet_x":42,"sheet_y":36,"short_name":"mango","short_names":["mango"],"text":null,"texts":null,"category":"Food & Drink","sort_order":8,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"MOON CAKE","unified":"1F96E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f96e.png","sheet_x":42,"sheet_y":37,"short_name":"moon_cake","short_names":["moon_cake"],"text":null,"texts":null,"category":"Food & Drink","sort_order":70,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"BAGEL","unified":"1F96F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f96f.png","sheet_x":42,"sheet_y":38,"short_name":"bagel","short_names":["bagel"],"text":null,"texts":null,"category":"Food & Drink","sort_order":34,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"SMILING FACE WITH SMILING EYES AND THREE HEARTS","unified":"1F970","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f970.png","sheet_x":42,"sheet_y":39,"short_name":"smiling_face_with_3_hearts","short_names":["smiling_face_with_3_hearts"],"text":null,"texts":null,"category":"Smileys & People","sort_order":15,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"FACE WITH PARTY HORN AND PARTY HAT","unified":"1F973","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f973.png","sheet_x":42,"sheet_y":40,"short_name":"partying_face","short_names":["partying_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":82,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"FACE WITH UNEVEN EYES AND WAVY MOUTH","unified":"1F974","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f974.png","sheet_x":42,"sheet_y":41,"short_name":"woozy_face","short_names":["woozy_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":83,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"OVERHEATED FACE","unified":"1F975","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f975.png","sheet_x":42,"sheet_y":42,"short_name":"hot_face","short_names":["hot_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":66,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"FREEZING FACE","unified":"1F976","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f976.png","sheet_x":42,"sheet_y":43,"short_name":"cold_face","short_names":["cold_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":67,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"FACE WITH PLEADING EYES","unified":"1F97A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f97a.png","sheet_x":42,"sheet_y":44,"short_name":"pleading_face","short_names":["pleading_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":84,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"LAB COAT","unified":"1F97C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f97c.png","sheet_x":42,"sheet_y":45,"short_name":"lab_coat","short_names":["lab_coat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":440,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"GOGGLES","unified":"1F97D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f97d.png","sheet_x":42,"sheet_y":46,"short_name":"goggles","short_names":["goggles"],"text":null,"texts":null,"category":"Smileys & People","sort_order":439,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"HIKING BOOT","unified":"1F97E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f97e.png","sheet_x":42,"sheet_y":47,"short_name":"hiking_boot","short_names":["hiking_boot"],"text":null,"texts":null,"category":"Smileys & People","sort_order":459,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"FLAT SHOE","unified":"1F97F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f97f.png","sheet_x":42,"sheet_y":48,"short_name":"womans_flat_shoe","short_names":["womans_flat_shoe"],"text":null,"texts":null,"category":"Smileys & People","sort_order":460,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"CRAB","unified":"1F980","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f980.png","sheet_x":42,"sheet_y":49,"short_name":"crab","short_names":["crab"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":87,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"LION FACE","unified":"1F981","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f981.png","sheet_x":42,"sheet_y":50,"short_name":"lion_face","short_names":["lion_face"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SCORPION","unified":"1F982","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f982.png","sheet_x":42,"sheet_y":51,"short_name":"scorpion","short_names":["scorpion"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":100,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"TURKEY","unified":"1F983","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f983.png","sheet_x":42,"sheet_y":52,"short_name":"turkey","short_names":["turkey"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":54,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"UNICORN FACE","unified":"1F984","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f984.png","sheet_x":43,"sheet_y":0,"short_name":"unicorn_face","short_names":["unicorn_face"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"EAGLE","unified":"1F985","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f985.png","sheet_x":43,"sheet_y":1,"short_name":"eagle","short_names":["eagle"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":63,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"DUCK","unified":"1F986","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f986.png","sheet_x":43,"sheet_y":2,"short_name":"duck","short_names":["duck"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":64,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BAT","unified":"1F987","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f987.png","sheet_x":43,"sheet_y":3,"short_name":"bat","short_names":["bat"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":47,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SHARK","unified":"1F988","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f988.png","sheet_x":43,"sheet_y":4,"short_name":"shark","short_names":["shark"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":84,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"OWL","unified":"1F989","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f989.png","sheet_x":43,"sheet_y":5,"short_name":"owl","short_names":["owl"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":66,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FOX FACE","unified":"1F98A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f98a.png","sheet_x":43,"sheet_y":6,"short_name":"fox_face","short_names":["fox_face"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":8,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BUTTERFLY","unified":"1F98B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f98b.png","sheet_x":43,"sheet_y":7,"short_name":"butterfly","short_names":["butterfly"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":92,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"DEER","unified":"1F98C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f98c.png","sheet_x":43,"sheet_y":8,"short_name":"deer","short_names":["deer"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":20,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"GORILLA","unified":"1F98D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f98d.png","sheet_x":43,"sheet_y":9,"short_name":"gorilla","short_names":["gorilla"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":3,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"LIZARD","unified":"1F98E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f98e.png","sheet_x":43,"sheet_y":10,"short_name":"lizard","short_names":["lizard"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":72,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"RHINOCEROS","unified":"1F98F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f98f.png","sheet_x":43,"sheet_y":11,"short_name":"rhinoceros","short_names":["rhinoceros"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":37,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SHRIMP","unified":"1F990","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f990.png","sheet_x":43,"sheet_y":12,"short_name":"shrimp","short_names":["shrimp"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":89,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SQUID","unified":"1F991","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f991.png","sheet_x":43,"sheet_y":13,"short_name":"squid","short_names":["squid"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":90,"added_in":"9.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"GIRAFFE FACE","unified":"1F992","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f992.png","sheet_x":43,"sheet_y":14,"short_name":"giraffe_face","short_names":["giraffe_face"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":35,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"ZEBRA FACE","unified":"1F993","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f993.png","sheet_x":43,"sheet_y":15,"short_name":"zebra_face","short_names":["zebra_face"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":19,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"HEDGEHOG","unified":"1F994","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f994.png","sheet_x":43,"sheet_y":16,"short_name":"hedgehog","short_names":["hedgehog"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":46,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SAUROPOD","unified":"1F995","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f995.png","sheet_x":43,"sheet_y":17,"short_name":"sauropod","short_names":["sauropod"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":76,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"T-REX","unified":"1F996","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f996.png","sheet_x":43,"sheet_y":18,"short_name":"t-rex","short_names":["t-rex"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":77,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CRICKET","unified":"1F997","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f997.png","sheet_x":43,"sheet_y":19,"short_name":"cricket","short_names":["cricket"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":97,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"KANGAROO","unified":"1F998","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f998.png","sheet_x":43,"sheet_y":20,"short_name":"kangaroo","short_names":["kangaroo"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":51,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"LLAMA","unified":"1F999","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f999.png","sheet_x":43,"sheet_y":21,"short_name":"llama","short_names":["llama"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":34,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"PEACOCK","unified":"1F99A","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f99a.png","sheet_x":43,"sheet_y":22,"short_name":"peacock","short_names":["peacock"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":67,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"HIPPOPOTAMUS","unified":"1F99B","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f99b.png","sheet_x":43,"sheet_y":23,"short_name":"hippopotamus","short_names":["hippopotamus"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":38,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"PARROT","unified":"1F99C","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f99c.png","sheet_x":43,"sheet_y":24,"short_name":"parrot","short_names":["parrot"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":68,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"RACCOON","unified":"1F99D","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f99d.png","sheet_x":43,"sheet_y":25,"short_name":"raccoon","short_names":["raccoon"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":9,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"LOBSTER","unified":"1F99E","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f99e.png","sheet_x":43,"sheet_y":26,"short_name":"lobster","short_names":["lobster"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":88,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"MOSQUITO","unified":"1F99F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f99f.png","sheet_x":43,"sheet_y":27,"short_name":"mosquito","short_names":["mosquito"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":101,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"MICROBE","unified":"1F9A0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9a0.png","sheet_x":43,"sheet_y":28,"short_name":"microbe","short_names":["microbe"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":102,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"BADGER","unified":"1F9A1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9a1.png","sheet_x":43,"sheet_y":29,"short_name":"badger","short_names":["badger"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":52,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"SWAN","unified":"1F9A2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9a2.png","sheet_x":43,"sheet_y":30,"short_name":"swan","short_names":["swan"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":65,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"BONE","unified":"1F9B4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9b4.png","sheet_x":43,"sheet_y":31,"short_name":"bone","short_names":["bone"],"text":null,"texts":null,"category":"Smileys & People","sort_order":402,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"LEG","unified":"1F9B5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9b5.png","sheet_x":43,"sheet_y":32,"short_name":"leg","short_names":["leg"],"text":null,"texts":null,"category":"Smileys & People","sort_order":362,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9B5-1F3FB","non_qualified":null,"image":"1f9b5-1f3fb.png","sheet_x":43,"sheet_y":33,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9B5-1F3FC","non_qualified":null,"image":"1f9b5-1f3fc.png","sheet_x":43,"sheet_y":34,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9B5-1F3FD","non_qualified":null,"image":"1f9b5-1f3fd.png","sheet_x":43,"sheet_y":35,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9B5-1F3FE","non_qualified":null,"image":"1f9b5-1f3fe.png","sheet_x":43,"sheet_y":36,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9B5-1F3FF","non_qualified":null,"image":"1f9b5-1f3ff.png","sheet_x":43,"sheet_y":37,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"FOOT","unified":"1F9B6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9b6.png","sheet_x":43,"sheet_y":38,"short_name":"foot","short_names":["foot"],"text":null,"texts":null,"category":"Smileys & People","sort_order":363,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9B6-1F3FB","non_qualified":null,"image":"1f9b6-1f3fb.png","sheet_x":43,"sheet_y":39,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9B6-1F3FC","non_qualified":null,"image":"1f9b6-1f3fc.png","sheet_x":43,"sheet_y":40,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9B6-1F3FD","non_qualified":null,"image":"1f9b6-1f3fd.png","sheet_x":43,"sheet_y":41,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9B6-1F3FE","non_qualified":null,"image":"1f9b6-1f3fe.png","sheet_x":43,"sheet_y":42,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9B6-1F3FF","non_qualified":null,"image":"1f9b6-1f3ff.png","sheet_x":43,"sheet_y":43,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"TOOTH","unified":"1F9B7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9b7.png","sheet_x":43,"sheet_y":44,"short_name":"tooth","short_names":["tooth"],"text":null,"texts":null,"category":"Smileys & People","sort_order":403,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":null,"unified":"1F9B8-200D-2640-FE0F","non_qualified":"1F9B8-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9b8-200d-2640-fe0f.png","sheet_x":43,"sheet_y":45,"short_name":"female_superhero","short_names":["female_superhero"],"text":null,"texts":null,"category":"Smileys & People","sort_order":194,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9B8-1F3FB-200D-2640-FE0F","non_qualified":"1F9B8-1F3FB-200D-2640","image":"1f9b8-1f3fb-200d-2640-fe0f.png","sheet_x":43,"sheet_y":46,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9B8-1F3FC-200D-2640-FE0F","non_qualified":"1F9B8-1F3FC-200D-2640","image":"1f9b8-1f3fc-200d-2640-fe0f.png","sheet_x":43,"sheet_y":47,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9B8-1F3FD-200D-2640-FE0F","non_qualified":"1F9B8-1F3FD-200D-2640","image":"1f9b8-1f3fd-200d-2640-fe0f.png","sheet_x":43,"sheet_y":48,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9B8-1F3FE-200D-2640-FE0F","non_qualified":"1F9B8-1F3FE-200D-2640","image":"1f9b8-1f3fe-200d-2640-fe0f.png","sheet_x":43,"sheet_y":49,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9B8-1F3FF-200D-2640-FE0F","non_qualified":"1F9B8-1F3FF-200D-2640","image":"1f9b8-1f3ff-200d-2640-fe0f.png","sheet_x":43,"sheet_y":50,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F9B8-200D-2642-FE0F","non_qualified":"1F9B8-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9b8-200d-2642-fe0f.png","sheet_x":43,"sheet_y":51,"short_name":"male_superhero","short_names":["male_superhero"],"text":null,"texts":null,"category":"Smileys & People","sort_order":195,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9B8-1F3FB-200D-2642-FE0F","non_qualified":"1F9B8-1F3FB-200D-2642","image":"1f9b8-1f3fb-200d-2642-fe0f.png","sheet_x":43,"sheet_y":52,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9B8-1F3FC-200D-2642-FE0F","non_qualified":"1F9B8-1F3FC-200D-2642","image":"1f9b8-1f3fc-200d-2642-fe0f.png","sheet_x":44,"sheet_y":0,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9B8-1F3FD-200D-2642-FE0F","non_qualified":"1F9B8-1F3FD-200D-2642","image":"1f9b8-1f3fd-200d-2642-fe0f.png","sheet_x":44,"sheet_y":1,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9B8-1F3FE-200D-2642-FE0F","non_qualified":"1F9B8-1F3FE-200D-2642","image":"1f9b8-1f3fe-200d-2642-fe0f.png","sheet_x":44,"sheet_y":2,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9B8-1F3FF-200D-2642-FE0F","non_qualified":"1F9B8-1F3FF-200D-2642","image":"1f9b8-1f3ff-200d-2642-fe0f.png","sheet_x":44,"sheet_y":3,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F9B9-200D-2640-FE0F","non_qualified":"1F9B9-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9b9-200d-2640-fe0f.png","sheet_x":44,"sheet_y":4,"short_name":"female_supervillain","short_names":["female_supervillain"],"text":null,"texts":null,"category":"Smileys & People","sort_order":196,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9B9-1F3FB-200D-2640-FE0F","non_qualified":"1F9B9-1F3FB-200D-2640","image":"1f9b9-1f3fb-200d-2640-fe0f.png","sheet_x":44,"sheet_y":5,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9B9-1F3FC-200D-2640-FE0F","non_qualified":"1F9B9-1F3FC-200D-2640","image":"1f9b9-1f3fc-200d-2640-fe0f.png","sheet_x":44,"sheet_y":6,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9B9-1F3FD-200D-2640-FE0F","non_qualified":"1F9B9-1F3FD-200D-2640","image":"1f9b9-1f3fd-200d-2640-fe0f.png","sheet_x":44,"sheet_y":7,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9B9-1F3FE-200D-2640-FE0F","non_qualified":"1F9B9-1F3FE-200D-2640","image":"1f9b9-1f3fe-200d-2640-fe0f.png","sheet_x":44,"sheet_y":8,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9B9-1F3FF-200D-2640-FE0F","non_qualified":"1F9B9-1F3FF-200D-2640","image":"1f9b9-1f3ff-200d-2640-fe0f.png","sheet_x":44,"sheet_y":9,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F9B9-200D-2642-FE0F","non_qualified":"1F9B9-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9b9-200d-2642-fe0f.png","sheet_x":44,"sheet_y":10,"short_name":"male_supervillain","short_names":["male_supervillain"],"text":null,"texts":null,"category":"Smileys & People","sort_order":197,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9B9-1F3FB-200D-2642-FE0F","non_qualified":"1F9B9-1F3FB-200D-2642","image":"1f9b9-1f3fb-200d-2642-fe0f.png","sheet_x":44,"sheet_y":11,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9B9-1F3FC-200D-2642-FE0F","non_qualified":"1F9B9-1F3FC-200D-2642","image":"1f9b9-1f3fc-200d-2642-fe0f.png","sheet_x":44,"sheet_y":12,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9B9-1F3FD-200D-2642-FE0F","non_qualified":"1F9B9-1F3FD-200D-2642","image":"1f9b9-1f3fd-200d-2642-fe0f.png","sheet_x":44,"sheet_y":13,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9B9-1F3FE-200D-2642-FE0F","non_qualified":"1F9B9-1F3FE-200D-2642","image":"1f9b9-1f3fe-200d-2642-fe0f.png","sheet_x":44,"sheet_y":14,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9B9-1F3FF-200D-2642-FE0F","non_qualified":"1F9B9-1F3FF-200D-2642","image":"1f9b9-1f3ff-200d-2642-fe0f.png","sheet_x":44,"sheet_y":15,"added_in":"11.0","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"CHEESE WEDGE","unified":"1F9C0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9c0.png","sheet_x":44,"sheet_y":16,"short_name":"cheese_wedge","short_names":["cheese_wedge"],"text":null,"texts":null,"category":"Food & Drink","sort_order":36,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CUPCAKE","unified":"1F9C1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9c1.png","sheet_x":44,"sheet_y":17,"short_name":"cupcake","short_names":["cupcake"],"text":null,"texts":null,"category":"Food & Drink","sort_order":82,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"SALT SHAKER","unified":"1F9C2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9c2.png","sheet_x":44,"sheet_y":18,"short_name":"salt","short_names":["salt"],"text":null,"texts":null,"category":"Food & Drink","sort_order":56,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"FACE WITH MONOCLE","unified":"1F9D0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d0.png","sheet_x":44,"sheet_y":19,"short_name":"face_with_monocle","short_names":["face_with_monocle"],"text":null,"texts":null,"category":"Smileys & People","sort_order":88,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"ADULT","unified":"1F9D1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d1.png","sheet_x":44,"sheet_y":20,"short_name":"adult","short_names":["adult"],"text":null,"texts":null,"category":"Smileys & People","sort_order":118,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D1-1F3FB","non_qualified":null,"image":"1f9d1-1f3fb.png","sheet_x":44,"sheet_y":21,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F9D1-1F3FC","non_qualified":null,"image":"1f9d1-1f3fc.png","sheet_x":44,"sheet_y":22,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F9D1-1F3FD","non_qualified":null,"image":"1f9d1-1f3fd.png","sheet_x":44,"sheet_y":23,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F9D1-1F3FE","non_qualified":null,"image":"1f9d1-1f3fe.png","sheet_x":44,"sheet_y":24,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F9D1-1F3FF","non_qualified":null,"image":"1f9d1-1f3ff.png","sheet_x":44,"sheet_y":25,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"CHILD","unified":"1F9D2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d2.png","sheet_x":44,"sheet_y":26,"short_name":"child","short_names":["child"],"text":null,"texts":null,"category":"Smileys & People","sort_order":115,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D2-1F3FB","non_qualified":null,"image":"1f9d2-1f3fb.png","sheet_x":44,"sheet_y":27,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F9D2-1F3FC","non_qualified":null,"image":"1f9d2-1f3fc.png","sheet_x":44,"sheet_y":28,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F9D2-1F3FD","non_qualified":null,"image":"1f9d2-1f3fd.png","sheet_x":44,"sheet_y":29,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F9D2-1F3FE","non_qualified":null,"image":"1f9d2-1f3fe.png","sheet_x":44,"sheet_y":30,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F9D2-1F3FF","non_qualified":null,"image":"1f9d2-1f3ff.png","sheet_x":44,"sheet_y":31,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"OLDER ADULT","unified":"1F9D3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d3.png","sheet_x":44,"sheet_y":32,"short_name":"older_adult","short_names":["older_adult"],"text":null,"texts":null,"category":"Smileys & People","sort_order":121,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D3-1F3FB","non_qualified":null,"image":"1f9d3-1f3fb.png","sheet_x":44,"sheet_y":33,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F9D3-1F3FC","non_qualified":null,"image":"1f9d3-1f3fc.png","sheet_x":44,"sheet_y":34,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F9D3-1F3FD","non_qualified":null,"image":"1f9d3-1f3fd.png","sheet_x":44,"sheet_y":35,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F9D3-1F3FE","non_qualified":null,"image":"1f9d3-1f3fe.png","sheet_x":44,"sheet_y":36,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F9D3-1F3FF","non_qualified":null,"image":"1f9d3-1f3ff.png","sheet_x":44,"sheet_y":37,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"BEARDED PERSON","unified":"1F9D4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d4.png","sheet_x":44,"sheet_y":38,"short_name":"bearded_person","short_names":["bearded_person"],"text":null,"texts":null,"category":"Smileys & People","sort_order":175,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D4-1F3FB","non_qualified":null,"image":"1f9d4-1f3fb.png","sheet_x":44,"sheet_y":39,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F9D4-1F3FC","non_qualified":null,"image":"1f9d4-1f3fc.png","sheet_x":44,"sheet_y":40,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F9D4-1F3FD","non_qualified":null,"image":"1f9d4-1f3fd.png","sheet_x":44,"sheet_y":41,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F9D4-1F3FE","non_qualified":null,"image":"1f9d4-1f3fe.png","sheet_x":44,"sheet_y":42,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F9D4-1F3FF","non_qualified":null,"image":"1f9d4-1f3ff.png","sheet_x":44,"sheet_y":43,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"PERSON WITH HEADSCARF","unified":"1F9D5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d5.png","sheet_x":44,"sheet_y":44,"short_name":"person_with_headscarf","short_names":["person_with_headscarf"],"text":null,"texts":null,"category":"Smileys & People","sort_order":174,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D5-1F3FB","non_qualified":null,"image":"1f9d5-1f3fb.png","sheet_x":44,"sheet_y":45,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F9D5-1F3FC","non_qualified":null,"image":"1f9d5-1f3fc.png","sheet_x":44,"sheet_y":46,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F9D5-1F3FD","non_qualified":null,"image":"1f9d5-1f3fd.png","sheet_x":44,"sheet_y":47,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F9D5-1F3FE","non_qualified":null,"image":"1f9d5-1f3fe.png","sheet_x":44,"sheet_y":48,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F9D5-1F3FF","non_qualified":null,"image":"1f9d5-1f3ff.png","sheet_x":44,"sheet_y":49,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":null,"unified":"1F9D6-200D-2640-FE0F","non_qualified":"1F9D6-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d6-200d-2640-fe0f.png","sheet_x":44,"sheet_y":50,"short_name":"woman_in_steamy_room","short_names":["woman_in_steamy_room"],"text":null,"texts":null,"category":"Smileys & People","sort_order":264,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D6-1F3FB-200D-2640-FE0F","non_qualified":"1F9D6-1F3FB-200D-2640","image":"1f9d6-1f3fb-200d-2640-fe0f.png","sheet_x":44,"sheet_y":51,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9D6-1F3FC-200D-2640-FE0F","non_qualified":"1F9D6-1F3FC-200D-2640","image":"1f9d6-1f3fc-200d-2640-fe0f.png","sheet_x":44,"sheet_y":52,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9D6-1F3FD-200D-2640-FE0F","non_qualified":"1F9D6-1F3FD-200D-2640","image":"1f9d6-1f3fd-200d-2640-fe0f.png","sheet_x":45,"sheet_y":0,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9D6-1F3FE-200D-2640-FE0F","non_qualified":"1F9D6-1F3FE-200D-2640","image":"1f9d6-1f3fe-200d-2640-fe0f.png","sheet_x":45,"sheet_y":1,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9D6-1F3FF-200D-2640-FE0F","non_qualified":"1F9D6-1F3FF-200D-2640","image":"1f9d6-1f3ff-200d-2640-fe0f.png","sheet_x":45,"sheet_y":2,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F9D6-200D-2642-FE0F","non_qualified":"1F9D6-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d6-200d-2642-fe0f.png","sheet_x":45,"sheet_y":3,"short_name":"man_in_steamy_room","short_names":["man_in_steamy_room"],"text":null,"texts":null,"category":"Smileys & People","sort_order":265,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D6-1F3FB-200D-2642-FE0F","non_qualified":"1F9D6-1F3FB-200D-2642","image":"1f9d6-1f3fb-200d-2642-fe0f.png","sheet_x":45,"sheet_y":4,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D6-1F3FB"},"1F3FC":{"unified":"1F9D6-1F3FC-200D-2642-FE0F","non_qualified":"1F9D6-1F3FC-200D-2642","image":"1f9d6-1f3fc-200d-2642-fe0f.png","sheet_x":45,"sheet_y":5,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D6-1F3FC"},"1F3FD":{"unified":"1F9D6-1F3FD-200D-2642-FE0F","non_qualified":"1F9D6-1F3FD-200D-2642","image":"1f9d6-1f3fd-200d-2642-fe0f.png","sheet_x":45,"sheet_y":6,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D6-1F3FD"},"1F3FE":{"unified":"1F9D6-1F3FE-200D-2642-FE0F","non_qualified":"1F9D6-1F3FE-200D-2642","image":"1f9d6-1f3fe-200d-2642-fe0f.png","sheet_x":45,"sheet_y":7,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D6-1F3FE"},"1F3FF":{"unified":"1F9D6-1F3FF-200D-2642-FE0F","non_qualified":"1F9D6-1F3FF-200D-2642","image":"1f9d6-1f3ff-200d-2642-fe0f.png","sheet_x":45,"sheet_y":8,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D6-1F3FF"}},"obsoletes":"1F9D6"},{"name":"PERSON IN STEAMY ROOM","unified":"1F9D6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d6.png","sheet_x":45,"sheet_y":9,"short_name":"person_in_steamy_room","short_names":["person_in_steamy_room"],"text":null,"texts":null,"category":"Smileys & People","sort_order":263,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D6-1F3FB","non_qualified":null,"image":"1f9d6-1f3fb.png","sheet_x":45,"sheet_y":10,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D6-1F3FB-200D-2642-FE0F"},"1F3FC":{"unified":"1F9D6-1F3FC","non_qualified":null,"image":"1f9d6-1f3fc.png","sheet_x":45,"sheet_y":11,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D6-1F3FC-200D-2642-FE0F"},"1F3FD":{"unified":"1F9D6-1F3FD","non_qualified":null,"image":"1f9d6-1f3fd.png","sheet_x":45,"sheet_y":12,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D6-1F3FD-200D-2642-FE0F"},"1F3FE":{"unified":"1F9D6-1F3FE","non_qualified":null,"image":"1f9d6-1f3fe.png","sheet_x":45,"sheet_y":13,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D6-1F3FE-200D-2642-FE0F"},"1F3FF":{"unified":"1F9D6-1F3FF","non_qualified":null,"image":"1f9d6-1f3ff.png","sheet_x":45,"sheet_y":14,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D6-1F3FF-200D-2642-FE0F"}},"obsoleted_by":"1F9D6-200D-2642-FE0F"},{"name":null,"unified":"1F9D7-200D-2640-FE0F","non_qualified":"1F9D7-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d7-200d-2640-fe0f.png","sheet_x":45,"sheet_y":15,"short_name":"woman_climbing","short_names":["woman_climbing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":267,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D7-1F3FB-200D-2640-FE0F","non_qualified":"1F9D7-1F3FB-200D-2640","image":"1f9d7-1f3fb-200d-2640-fe0f.png","sheet_x":45,"sheet_y":16,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D7-1F3FB"},"1F3FC":{"unified":"1F9D7-1F3FC-200D-2640-FE0F","non_qualified":"1F9D7-1F3FC-200D-2640","image":"1f9d7-1f3fc-200d-2640-fe0f.png","sheet_x":45,"sheet_y":17,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D7-1F3FC"},"1F3FD":{"unified":"1F9D7-1F3FD-200D-2640-FE0F","non_qualified":"1F9D7-1F3FD-200D-2640","image":"1f9d7-1f3fd-200d-2640-fe0f.png","sheet_x":45,"sheet_y":18,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D7-1F3FD"},"1F3FE":{"unified":"1F9D7-1F3FE-200D-2640-FE0F","non_qualified":"1F9D7-1F3FE-200D-2640","image":"1f9d7-1f3fe-200d-2640-fe0f.png","sheet_x":45,"sheet_y":19,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D7-1F3FE"},"1F3FF":{"unified":"1F9D7-1F3FF-200D-2640-FE0F","non_qualified":"1F9D7-1F3FF-200D-2640","image":"1f9d7-1f3ff-200d-2640-fe0f.png","sheet_x":45,"sheet_y":20,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D7-1F3FF"}},"obsoletes":"1F9D7"},{"name":null,"unified":"1F9D7-200D-2642-FE0F","non_qualified":"1F9D7-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d7-200d-2642-fe0f.png","sheet_x":45,"sheet_y":21,"short_name":"man_climbing","short_names":["man_climbing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":268,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D7-1F3FB-200D-2642-FE0F","non_qualified":"1F9D7-1F3FB-200D-2642","image":"1f9d7-1f3fb-200d-2642-fe0f.png","sheet_x":45,"sheet_y":22,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9D7-1F3FC-200D-2642-FE0F","non_qualified":"1F9D7-1F3FC-200D-2642","image":"1f9d7-1f3fc-200d-2642-fe0f.png","sheet_x":45,"sheet_y":23,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9D7-1F3FD-200D-2642-FE0F","non_qualified":"1F9D7-1F3FD-200D-2642","image":"1f9d7-1f3fd-200d-2642-fe0f.png","sheet_x":45,"sheet_y":24,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9D7-1F3FE-200D-2642-FE0F","non_qualified":"1F9D7-1F3FE-200D-2642","image":"1f9d7-1f3fe-200d-2642-fe0f.png","sheet_x":45,"sheet_y":25,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9D7-1F3FF-200D-2642-FE0F","non_qualified":"1F9D7-1F3FF-200D-2642","image":"1f9d7-1f3ff-200d-2642-fe0f.png","sheet_x":45,"sheet_y":26,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"PERSON CLIMBING","unified":"1F9D7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d7.png","sheet_x":45,"sheet_y":27,"short_name":"person_climbing","short_names":["person_climbing"],"text":null,"texts":null,"category":"Smileys & People","sort_order":266,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D7-1F3FB","non_qualified":null,"image":"1f9d7-1f3fb.png","sheet_x":45,"sheet_y":28,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D7-1F3FB-200D-2640-FE0F"},"1F3FC":{"unified":"1F9D7-1F3FC","non_qualified":null,"image":"1f9d7-1f3fc.png","sheet_x":45,"sheet_y":29,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D7-1F3FC-200D-2640-FE0F"},"1F3FD":{"unified":"1F9D7-1F3FD","non_qualified":null,"image":"1f9d7-1f3fd.png","sheet_x":45,"sheet_y":30,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D7-1F3FD-200D-2640-FE0F"},"1F3FE":{"unified":"1F9D7-1F3FE","non_qualified":null,"image":"1f9d7-1f3fe.png","sheet_x":45,"sheet_y":31,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D7-1F3FE-200D-2640-FE0F"},"1F3FF":{"unified":"1F9D7-1F3FF","non_qualified":null,"image":"1f9d7-1f3ff.png","sheet_x":45,"sheet_y":32,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D7-1F3FF-200D-2640-FE0F"}},"obsoleted_by":"1F9D7-200D-2640-FE0F"},{"name":null,"unified":"1F9D8-200D-2640-FE0F","non_qualified":"1F9D8-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d8-200d-2640-fe0f.png","sheet_x":45,"sheet_y":33,"short_name":"woman_in_lotus_position","short_names":["woman_in_lotus_position"],"text":null,"texts":null,"category":"Smileys & People","sort_order":270,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D8-1F3FB-200D-2640-FE0F","non_qualified":"1F9D8-1F3FB-200D-2640","image":"1f9d8-1f3fb-200d-2640-fe0f.png","sheet_x":45,"sheet_y":34,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D8-1F3FB"},"1F3FC":{"unified":"1F9D8-1F3FC-200D-2640-FE0F","non_qualified":"1F9D8-1F3FC-200D-2640","image":"1f9d8-1f3fc-200d-2640-fe0f.png","sheet_x":45,"sheet_y":35,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D8-1F3FC"},"1F3FD":{"unified":"1F9D8-1F3FD-200D-2640-FE0F","non_qualified":"1F9D8-1F3FD-200D-2640","image":"1f9d8-1f3fd-200d-2640-fe0f.png","sheet_x":45,"sheet_y":36,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D8-1F3FD"},"1F3FE":{"unified":"1F9D8-1F3FE-200D-2640-FE0F","non_qualified":"1F9D8-1F3FE-200D-2640","image":"1f9d8-1f3fe-200d-2640-fe0f.png","sheet_x":45,"sheet_y":37,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D8-1F3FE"},"1F3FF":{"unified":"1F9D8-1F3FF-200D-2640-FE0F","non_qualified":"1F9D8-1F3FF-200D-2640","image":"1f9d8-1f3ff-200d-2640-fe0f.png","sheet_x":45,"sheet_y":38,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D8-1F3FF"}},"obsoletes":"1F9D8"},{"name":null,"unified":"1F9D8-200D-2642-FE0F","non_qualified":"1F9D8-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d8-200d-2642-fe0f.png","sheet_x":45,"sheet_y":39,"short_name":"man_in_lotus_position","short_names":["man_in_lotus_position"],"text":null,"texts":null,"category":"Smileys & People","sort_order":271,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D8-1F3FB-200D-2642-FE0F","non_qualified":"1F9D8-1F3FB-200D-2642","image":"1f9d8-1f3fb-200d-2642-fe0f.png","sheet_x":45,"sheet_y":40,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9D8-1F3FC-200D-2642-FE0F","non_qualified":"1F9D8-1F3FC-200D-2642","image":"1f9d8-1f3fc-200d-2642-fe0f.png","sheet_x":45,"sheet_y":41,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9D8-1F3FD-200D-2642-FE0F","non_qualified":"1F9D8-1F3FD-200D-2642","image":"1f9d8-1f3fd-200d-2642-fe0f.png","sheet_x":45,"sheet_y":42,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9D8-1F3FE-200D-2642-FE0F","non_qualified":"1F9D8-1F3FE-200D-2642","image":"1f9d8-1f3fe-200d-2642-fe0f.png","sheet_x":45,"sheet_y":43,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9D8-1F3FF-200D-2642-FE0F","non_qualified":"1F9D8-1F3FF-200D-2642","image":"1f9d8-1f3ff-200d-2642-fe0f.png","sheet_x":45,"sheet_y":44,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"PERSON IN LOTUS POSITION","unified":"1F9D8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d8.png","sheet_x":45,"sheet_y":45,"short_name":"person_in_lotus_position","short_names":["person_in_lotus_position"],"text":null,"texts":null,"category":"Smileys & People","sort_order":269,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D8-1F3FB","non_qualified":null,"image":"1f9d8-1f3fb.png","sheet_x":45,"sheet_y":46,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D8-1F3FB-200D-2640-FE0F"},"1F3FC":{"unified":"1F9D8-1F3FC","non_qualified":null,"image":"1f9d8-1f3fc.png","sheet_x":45,"sheet_y":47,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D8-1F3FC-200D-2640-FE0F"},"1F3FD":{"unified":"1F9D8-1F3FD","non_qualified":null,"image":"1f9d8-1f3fd.png","sheet_x":45,"sheet_y":48,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D8-1F3FD-200D-2640-FE0F"},"1F3FE":{"unified":"1F9D8-1F3FE","non_qualified":null,"image":"1f9d8-1f3fe.png","sheet_x":45,"sheet_y":49,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D8-1F3FE-200D-2640-FE0F"},"1F3FF":{"unified":"1F9D8-1F3FF","non_qualified":null,"image":"1f9d8-1f3ff.png","sheet_x":45,"sheet_y":50,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D8-1F3FF-200D-2640-FE0F"}},"obsoleted_by":"1F9D8-200D-2640-FE0F"},{"name":null,"unified":"1F9D9-200D-2640-FE0F","non_qualified":"1F9D9-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d9-200d-2640-fe0f.png","sheet_x":45,"sheet_y":51,"short_name":"female_mage","short_names":["female_mage"],"text":null,"texts":null,"category":"Smileys & People","sort_order":199,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D9-1F3FB-200D-2640-FE0F","non_qualified":"1F9D9-1F3FB-200D-2640","image":"1f9d9-1f3fb-200d-2640-fe0f.png","sheet_x":45,"sheet_y":52,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D9-1F3FB"},"1F3FC":{"unified":"1F9D9-1F3FC-200D-2640-FE0F","non_qualified":"1F9D9-1F3FC-200D-2640","image":"1f9d9-1f3fc-200d-2640-fe0f.png","sheet_x":46,"sheet_y":0,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D9-1F3FC"},"1F3FD":{"unified":"1F9D9-1F3FD-200D-2640-FE0F","non_qualified":"1F9D9-1F3FD-200D-2640","image":"1f9d9-1f3fd-200d-2640-fe0f.png","sheet_x":46,"sheet_y":1,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D9-1F3FD"},"1F3FE":{"unified":"1F9D9-1F3FE-200D-2640-FE0F","non_qualified":"1F9D9-1F3FE-200D-2640","image":"1f9d9-1f3fe-200d-2640-fe0f.png","sheet_x":46,"sheet_y":2,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D9-1F3FE"},"1F3FF":{"unified":"1F9D9-1F3FF-200D-2640-FE0F","non_qualified":"1F9D9-1F3FF-200D-2640","image":"1f9d9-1f3ff-200d-2640-fe0f.png","sheet_x":46,"sheet_y":3,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9D9-1F3FF"}},"obsoletes":"1F9D9"},{"name":null,"unified":"1F9D9-200D-2642-FE0F","non_qualified":"1F9D9-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d9-200d-2642-fe0f.png","sheet_x":46,"sheet_y":4,"short_name":"male_mage","short_names":["male_mage"],"text":null,"texts":null,"category":"Smileys & People","sort_order":200,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D9-1F3FB-200D-2642-FE0F","non_qualified":"1F9D9-1F3FB-200D-2642","image":"1f9d9-1f3fb-200d-2642-fe0f.png","sheet_x":46,"sheet_y":5,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9D9-1F3FC-200D-2642-FE0F","non_qualified":"1F9D9-1F3FC-200D-2642","image":"1f9d9-1f3fc-200d-2642-fe0f.png","sheet_x":46,"sheet_y":6,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9D9-1F3FD-200D-2642-FE0F","non_qualified":"1F9D9-1F3FD-200D-2642","image":"1f9d9-1f3fd-200d-2642-fe0f.png","sheet_x":46,"sheet_y":7,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9D9-1F3FE-200D-2642-FE0F","non_qualified":"1F9D9-1F3FE-200D-2642","image":"1f9d9-1f3fe-200d-2642-fe0f.png","sheet_x":46,"sheet_y":8,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9D9-1F3FF-200D-2642-FE0F","non_qualified":"1F9D9-1F3FF-200D-2642","image":"1f9d9-1f3ff-200d-2642-fe0f.png","sheet_x":46,"sheet_y":9,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"MAGE","unified":"1F9D9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9d9.png","sheet_x":46,"sheet_y":10,"short_name":"mage","short_names":["mage"],"text":null,"texts":null,"category":"Smileys & People","sort_order":198,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9D9-1F3FB","non_qualified":null,"image":"1f9d9-1f3fb.png","sheet_x":46,"sheet_y":11,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D9-1F3FB-200D-2640-FE0F"},"1F3FC":{"unified":"1F9D9-1F3FC","non_qualified":null,"image":"1f9d9-1f3fc.png","sheet_x":46,"sheet_y":12,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D9-1F3FC-200D-2640-FE0F"},"1F3FD":{"unified":"1F9D9-1F3FD","non_qualified":null,"image":"1f9d9-1f3fd.png","sheet_x":46,"sheet_y":13,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D9-1F3FD-200D-2640-FE0F"},"1F3FE":{"unified":"1F9D9-1F3FE","non_qualified":null,"image":"1f9d9-1f3fe.png","sheet_x":46,"sheet_y":14,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D9-1F3FE-200D-2640-FE0F"},"1F3FF":{"unified":"1F9D9-1F3FF","non_qualified":null,"image":"1f9d9-1f3ff.png","sheet_x":46,"sheet_y":15,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9D9-1F3FF-200D-2640-FE0F"}},"obsoleted_by":"1F9D9-200D-2640-FE0F"},{"name":null,"unified":"1F9DA-200D-2640-FE0F","non_qualified":"1F9DA-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9da-200d-2640-fe0f.png","sheet_x":46,"sheet_y":16,"short_name":"female_fairy","short_names":["female_fairy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":202,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DA-1F3FB-200D-2640-FE0F","non_qualified":"1F9DA-1F3FB-200D-2640","image":"1f9da-1f3fb-200d-2640-fe0f.png","sheet_x":46,"sheet_y":17,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DA-1F3FB"},"1F3FC":{"unified":"1F9DA-1F3FC-200D-2640-FE0F","non_qualified":"1F9DA-1F3FC-200D-2640","image":"1f9da-1f3fc-200d-2640-fe0f.png","sheet_x":46,"sheet_y":18,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DA-1F3FC"},"1F3FD":{"unified":"1F9DA-1F3FD-200D-2640-FE0F","non_qualified":"1F9DA-1F3FD-200D-2640","image":"1f9da-1f3fd-200d-2640-fe0f.png","sheet_x":46,"sheet_y":19,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DA-1F3FD"},"1F3FE":{"unified":"1F9DA-1F3FE-200D-2640-FE0F","non_qualified":"1F9DA-1F3FE-200D-2640","image":"1f9da-1f3fe-200d-2640-fe0f.png","sheet_x":46,"sheet_y":20,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DA-1F3FE"},"1F3FF":{"unified":"1F9DA-1F3FF-200D-2640-FE0F","non_qualified":"1F9DA-1F3FF-200D-2640","image":"1f9da-1f3ff-200d-2640-fe0f.png","sheet_x":46,"sheet_y":21,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DA-1F3FF"}},"obsoletes":"1F9DA"},{"name":null,"unified":"1F9DA-200D-2642-FE0F","non_qualified":"1F9DA-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9da-200d-2642-fe0f.png","sheet_x":46,"sheet_y":22,"short_name":"male_fairy","short_names":["male_fairy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":203,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DA-1F3FB-200D-2642-FE0F","non_qualified":"1F9DA-1F3FB-200D-2642","image":"1f9da-1f3fb-200d-2642-fe0f.png","sheet_x":46,"sheet_y":23,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9DA-1F3FC-200D-2642-FE0F","non_qualified":"1F9DA-1F3FC-200D-2642","image":"1f9da-1f3fc-200d-2642-fe0f.png","sheet_x":46,"sheet_y":24,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9DA-1F3FD-200D-2642-FE0F","non_qualified":"1F9DA-1F3FD-200D-2642","image":"1f9da-1f3fd-200d-2642-fe0f.png","sheet_x":46,"sheet_y":25,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9DA-1F3FE-200D-2642-FE0F","non_qualified":"1F9DA-1F3FE-200D-2642","image":"1f9da-1f3fe-200d-2642-fe0f.png","sheet_x":46,"sheet_y":26,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9DA-1F3FF-200D-2642-FE0F","non_qualified":"1F9DA-1F3FF-200D-2642","image":"1f9da-1f3ff-200d-2642-fe0f.png","sheet_x":46,"sheet_y":27,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"FAIRY","unified":"1F9DA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9da.png","sheet_x":46,"sheet_y":28,"short_name":"fairy","short_names":["fairy"],"text":null,"texts":null,"category":"Smileys & People","sort_order":201,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DA-1F3FB","non_qualified":null,"image":"1f9da-1f3fb.png","sheet_x":46,"sheet_y":29,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DA-1F3FB-200D-2640-FE0F"},"1F3FC":{"unified":"1F9DA-1F3FC","non_qualified":null,"image":"1f9da-1f3fc.png","sheet_x":46,"sheet_y":30,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DA-1F3FC-200D-2640-FE0F"},"1F3FD":{"unified":"1F9DA-1F3FD","non_qualified":null,"image":"1f9da-1f3fd.png","sheet_x":46,"sheet_y":31,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DA-1F3FD-200D-2640-FE0F"},"1F3FE":{"unified":"1F9DA-1F3FE","non_qualified":null,"image":"1f9da-1f3fe.png","sheet_x":46,"sheet_y":32,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DA-1F3FE-200D-2640-FE0F"},"1F3FF":{"unified":"1F9DA-1F3FF","non_qualified":null,"image":"1f9da-1f3ff.png","sheet_x":46,"sheet_y":33,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DA-1F3FF-200D-2640-FE0F"}},"obsoleted_by":"1F9DA-200D-2640-FE0F"},{"name":null,"unified":"1F9DB-200D-2640-FE0F","non_qualified":"1F9DB-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9db-200d-2640-fe0f.png","sheet_x":46,"sheet_y":34,"short_name":"female_vampire","short_names":["female_vampire"],"text":null,"texts":null,"category":"Smileys & People","sort_order":205,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DB-1F3FB-200D-2640-FE0F","non_qualified":"1F9DB-1F3FB-200D-2640","image":"1f9db-1f3fb-200d-2640-fe0f.png","sheet_x":46,"sheet_y":35,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DB-1F3FB"},"1F3FC":{"unified":"1F9DB-1F3FC-200D-2640-FE0F","non_qualified":"1F9DB-1F3FC-200D-2640","image":"1f9db-1f3fc-200d-2640-fe0f.png","sheet_x":46,"sheet_y":36,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DB-1F3FC"},"1F3FD":{"unified":"1F9DB-1F3FD-200D-2640-FE0F","non_qualified":"1F9DB-1F3FD-200D-2640","image":"1f9db-1f3fd-200d-2640-fe0f.png","sheet_x":46,"sheet_y":37,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DB-1F3FD"},"1F3FE":{"unified":"1F9DB-1F3FE-200D-2640-FE0F","non_qualified":"1F9DB-1F3FE-200D-2640","image":"1f9db-1f3fe-200d-2640-fe0f.png","sheet_x":46,"sheet_y":38,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DB-1F3FE"},"1F3FF":{"unified":"1F9DB-1F3FF-200D-2640-FE0F","non_qualified":"1F9DB-1F3FF-200D-2640","image":"1f9db-1f3ff-200d-2640-fe0f.png","sheet_x":46,"sheet_y":39,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DB-1F3FF"}},"obsoletes":"1F9DB"},{"name":null,"unified":"1F9DB-200D-2642-FE0F","non_qualified":"1F9DB-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9db-200d-2642-fe0f.png","sheet_x":46,"sheet_y":40,"short_name":"male_vampire","short_names":["male_vampire"],"text":null,"texts":null,"category":"Smileys & People","sort_order":206,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DB-1F3FB-200D-2642-FE0F","non_qualified":"1F9DB-1F3FB-200D-2642","image":"1f9db-1f3fb-200d-2642-fe0f.png","sheet_x":46,"sheet_y":41,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9DB-1F3FC-200D-2642-FE0F","non_qualified":"1F9DB-1F3FC-200D-2642","image":"1f9db-1f3fc-200d-2642-fe0f.png","sheet_x":46,"sheet_y":42,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9DB-1F3FD-200D-2642-FE0F","non_qualified":"1F9DB-1F3FD-200D-2642","image":"1f9db-1f3fd-200d-2642-fe0f.png","sheet_x":46,"sheet_y":43,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9DB-1F3FE-200D-2642-FE0F","non_qualified":"1F9DB-1F3FE-200D-2642","image":"1f9db-1f3fe-200d-2642-fe0f.png","sheet_x":46,"sheet_y":44,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9DB-1F3FF-200D-2642-FE0F","non_qualified":"1F9DB-1F3FF-200D-2642","image":"1f9db-1f3ff-200d-2642-fe0f.png","sheet_x":46,"sheet_y":45,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":"VAMPIRE","unified":"1F9DB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9db.png","sheet_x":46,"sheet_y":46,"short_name":"vampire","short_names":["vampire"],"text":null,"texts":null,"category":"Smileys & People","sort_order":204,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DB-1F3FB","non_qualified":null,"image":"1f9db-1f3fb.png","sheet_x":46,"sheet_y":47,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DB-1F3FB-200D-2640-FE0F"},"1F3FC":{"unified":"1F9DB-1F3FC","non_qualified":null,"image":"1f9db-1f3fc.png","sheet_x":46,"sheet_y":48,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DB-1F3FC-200D-2640-FE0F"},"1F3FD":{"unified":"1F9DB-1F3FD","non_qualified":null,"image":"1f9db-1f3fd.png","sheet_x":46,"sheet_y":49,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DB-1F3FD-200D-2640-FE0F"},"1F3FE":{"unified":"1F9DB-1F3FE","non_qualified":null,"image":"1f9db-1f3fe.png","sheet_x":46,"sheet_y":50,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DB-1F3FE-200D-2640-FE0F"},"1F3FF":{"unified":"1F9DB-1F3FF","non_qualified":null,"image":"1f9db-1f3ff.png","sheet_x":46,"sheet_y":51,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoleted_by":"1F9DB-1F3FF-200D-2640-FE0F"}},"obsoleted_by":"1F9DB-200D-2640-FE0F"},{"name":null,"unified":"1F9DC-200D-2640-FE0F","non_qualified":"1F9DC-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9dc-200d-2640-fe0f.png","sheet_x":46,"sheet_y":52,"short_name":"mermaid","short_names":["mermaid"],"text":null,"texts":null,"category":"Smileys & People","sort_order":208,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DC-1F3FB-200D-2640-FE0F","non_qualified":"1F9DC-1F3FB-200D-2640","image":"1f9dc-1f3fb-200d-2640-fe0f.png","sheet_x":47,"sheet_y":0,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9DC-1F3FC-200D-2640-FE0F","non_qualified":"1F9DC-1F3FC-200D-2640","image":"1f9dc-1f3fc-200d-2640-fe0f.png","sheet_x":47,"sheet_y":1,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9DC-1F3FD-200D-2640-FE0F","non_qualified":"1F9DC-1F3FD-200D-2640","image":"1f9dc-1f3fd-200d-2640-fe0f.png","sheet_x":47,"sheet_y":2,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9DC-1F3FE-200D-2640-FE0F","non_qualified":"1F9DC-1F3FE-200D-2640","image":"1f9dc-1f3fe-200d-2640-fe0f.png","sheet_x":47,"sheet_y":3,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9DC-1F3FF-200D-2640-FE0F","non_qualified":"1F9DC-1F3FF-200D-2640","image":"1f9dc-1f3ff-200d-2640-fe0f.png","sheet_x":47,"sheet_y":4,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F9DC-200D-2642-FE0F","non_qualified":"1F9DC-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9dc-200d-2642-fe0f.png","sheet_x":47,"sheet_y":5,"short_name":"merman","short_names":["merman"],"text":null,"texts":null,"category":"Smileys & People","sort_order":209,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DC-1F3FB-200D-2642-FE0F","non_qualified":"1F9DC-1F3FB-200D-2642","image":"1f9dc-1f3fb-200d-2642-fe0f.png","sheet_x":47,"sheet_y":6,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DC-1F3FB"},"1F3FC":{"unified":"1F9DC-1F3FC-200D-2642-FE0F","non_qualified":"1F9DC-1F3FC-200D-2642","image":"1f9dc-1f3fc-200d-2642-fe0f.png","sheet_x":47,"sheet_y":7,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DC-1F3FC"},"1F3FD":{"unified":"1F9DC-1F3FD-200D-2642-FE0F","non_qualified":"1F9DC-1F3FD-200D-2642","image":"1f9dc-1f3fd-200d-2642-fe0f.png","sheet_x":47,"sheet_y":8,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DC-1F3FD"},"1F3FE":{"unified":"1F9DC-1F3FE-200D-2642-FE0F","non_qualified":"1F9DC-1F3FE-200D-2642","image":"1f9dc-1f3fe-200d-2642-fe0f.png","sheet_x":47,"sheet_y":9,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DC-1F3FE"},"1F3FF":{"unified":"1F9DC-1F3FF-200D-2642-FE0F","non_qualified":"1F9DC-1F3FF-200D-2642","image":"1f9dc-1f3ff-200d-2642-fe0f.png","sheet_x":47,"sheet_y":10,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DC-1F3FF"}},"obsoletes":"1F9DC"},{"name":"MERPERSON","unified":"1F9DC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9dc.png","sheet_x":47,"sheet_y":11,"short_name":"merperson","short_names":["merperson"],"text":null,"texts":null,"category":"Smileys & People","sort_order":207,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DC-1F3FB","non_qualified":null,"image":"1f9dc-1f3fb.png","sheet_x":47,"sheet_y":12,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DC-1F3FB-200D-2642-FE0F"},"1F3FC":{"unified":"1F9DC-1F3FC","non_qualified":null,"image":"1f9dc-1f3fc.png","sheet_x":47,"sheet_y":13,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DC-1F3FC-200D-2642-FE0F"},"1F3FD":{"unified":"1F9DC-1F3FD","non_qualified":null,"image":"1f9dc-1f3fd.png","sheet_x":47,"sheet_y":14,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DC-1F3FD-200D-2642-FE0F"},"1F3FE":{"unified":"1F9DC-1F3FE","non_qualified":null,"image":"1f9dc-1f3fe.png","sheet_x":47,"sheet_y":15,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DC-1F3FE-200D-2642-FE0F"},"1F3FF":{"unified":"1F9DC-1F3FF","non_qualified":null,"image":"1f9dc-1f3ff.png","sheet_x":47,"sheet_y":16,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DC-1F3FF-200D-2642-FE0F"}},"obsoleted_by":"1F9DC-200D-2642-FE0F"},{"name":null,"unified":"1F9DD-200D-2640-FE0F","non_qualified":"1F9DD-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9dd-200d-2640-fe0f.png","sheet_x":47,"sheet_y":17,"short_name":"female_elf","short_names":["female_elf"],"text":null,"texts":null,"category":"Smileys & People","sort_order":211,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DD-1F3FB-200D-2640-FE0F","non_qualified":"1F9DD-1F3FB-200D-2640","image":"1f9dd-1f3fb-200d-2640-fe0f.png","sheet_x":47,"sheet_y":18,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F9DD-1F3FC-200D-2640-FE0F","non_qualified":"1F9DD-1F3FC-200D-2640","image":"1f9dd-1f3fc-200d-2640-fe0f.png","sheet_x":47,"sheet_y":19,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F9DD-1F3FD-200D-2640-FE0F","non_qualified":"1F9DD-1F3FD-200D-2640","image":"1f9dd-1f3fd-200d-2640-fe0f.png","sheet_x":47,"sheet_y":20,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F9DD-1F3FE-200D-2640-FE0F","non_qualified":"1F9DD-1F3FE-200D-2640","image":"1f9dd-1f3fe-200d-2640-fe0f.png","sheet_x":47,"sheet_y":21,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F9DD-1F3FF-200D-2640-FE0F","non_qualified":"1F9DD-1F3FF-200D-2640","image":"1f9dd-1f3ff-200d-2640-fe0f.png","sheet_x":47,"sheet_y":22,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"1F9DD-200D-2642-FE0F","non_qualified":"1F9DD-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9dd-200d-2642-fe0f.png","sheet_x":47,"sheet_y":23,"short_name":"male_elf","short_names":["male_elf"],"text":null,"texts":null,"category":"Smileys & People","sort_order":212,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DD-1F3FB-200D-2642-FE0F","non_qualified":"1F9DD-1F3FB-200D-2642","image":"1f9dd-1f3fb-200d-2642-fe0f.png","sheet_x":47,"sheet_y":24,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DD-1F3FB"},"1F3FC":{"unified":"1F9DD-1F3FC-200D-2642-FE0F","non_qualified":"1F9DD-1F3FC-200D-2642","image":"1f9dd-1f3fc-200d-2642-fe0f.png","sheet_x":47,"sheet_y":25,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DD-1F3FC"},"1F3FD":{"unified":"1F9DD-1F3FD-200D-2642-FE0F","non_qualified":"1F9DD-1F3FD-200D-2642","image":"1f9dd-1f3fd-200d-2642-fe0f.png","sheet_x":47,"sheet_y":26,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DD-1F3FD"},"1F3FE":{"unified":"1F9DD-1F3FE-200D-2642-FE0F","non_qualified":"1F9DD-1F3FE-200D-2642","image":"1f9dd-1f3fe-200d-2642-fe0f.png","sheet_x":47,"sheet_y":27,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DD-1F3FE"},"1F3FF":{"unified":"1F9DD-1F3FF-200D-2642-FE0F","non_qualified":"1F9DD-1F3FF-200D-2642","image":"1f9dd-1f3ff-200d-2642-fe0f.png","sheet_x":47,"sheet_y":28,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"obsoletes":"1F9DD-1F3FF"}},"obsoletes":"1F9DD"},{"name":"ELF","unified":"1F9DD","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9dd.png","sheet_x":47,"sheet_y":29,"short_name":"elf","short_names":["elf"],"text":null,"texts":null,"category":"Smileys & People","sort_order":210,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"1F9DD-1F3FB","non_qualified":null,"image":"1f9dd-1f3fb.png","sheet_x":47,"sheet_y":30,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DD-1F3FB-200D-2642-FE0F"},"1F3FC":{"unified":"1F9DD-1F3FC","non_qualified":null,"image":"1f9dd-1f3fc.png","sheet_x":47,"sheet_y":31,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DD-1F3FC-200D-2642-FE0F"},"1F3FD":{"unified":"1F9DD-1F3FD","non_qualified":null,"image":"1f9dd-1f3fd.png","sheet_x":47,"sheet_y":32,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DD-1F3FD-200D-2642-FE0F"},"1F3FE":{"unified":"1F9DD-1F3FE","non_qualified":null,"image":"1f9dd-1f3fe.png","sheet_x":47,"sheet_y":33,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DD-1F3FE-200D-2642-FE0F"},"1F3FF":{"unified":"1F9DD-1F3FF","non_qualified":null,"image":"1f9dd-1f3ff.png","sheet_x":47,"sheet_y":34,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DD-1F3FF-200D-2642-FE0F"}},"obsoleted_by":"1F9DD-200D-2642-FE0F"},{"name":null,"unified":"1F9DE-200D-2640-FE0F","non_qualified":"1F9DE-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9de-200d-2640-fe0f.png","sheet_x":47,"sheet_y":35,"short_name":"female_genie","short_names":["female_genie"],"text":null,"texts":null,"category":"Smileys & People","sort_order":214,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F9DE-200D-2642-FE0F","non_qualified":"1F9DE-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9de-200d-2642-fe0f.png","sheet_x":47,"sheet_y":36,"short_name":"male_genie","short_names":["male_genie"],"text":null,"texts":null,"category":"Smileys & People","sort_order":215,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoletes":"1F9DE"},{"name":"GENIE","unified":"1F9DE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9de.png","sheet_x":47,"sheet_y":37,"short_name":"genie","short_names":["genie"],"text":null,"texts":null,"category":"Smileys & People","sort_order":213,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DE-200D-2642-FE0F"},{"name":null,"unified":"1F9DF-200D-2640-FE0F","non_qualified":"1F9DF-200D-2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9df-200d-2640-fe0f.png","sheet_x":47,"sheet_y":38,"short_name":"female_zombie","short_names":["female_zombie"],"text":null,"texts":null,"category":"Smileys & People","sort_order":217,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"1F9DF-200D-2642-FE0F","non_qualified":"1F9DF-200D-2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9df-200d-2642-fe0f.png","sheet_x":47,"sheet_y":39,"short_name":"male_zombie","short_names":["male_zombie"],"text":null,"texts":null,"category":"Smileys & People","sort_order":218,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoletes":"1F9DF"},{"name":"ZOMBIE","unified":"1F9DF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9df.png","sheet_x":47,"sheet_y":40,"short_name":"zombie","short_names":["zombie"],"text":null,"texts":null,"category":"Smileys & People","sort_order":216,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"obsoleted_by":"1F9DF-200D-2642-FE0F"},{"name":"BRAIN","unified":"1F9E0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e0.png","sheet_x":47,"sheet_y":41,"short_name":"brain","short_names":["brain"],"text":null,"texts":null,"category":"Smileys & People","sort_order":401,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"ORANGE HEART","unified":"1F9E1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e1.png","sheet_x":47,"sheet_y":42,"short_name":"orange_heart","short_names":["orange_heart"],"text":null,"texts":null,"category":"Smileys & People","sort_order":417,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BILLED CAP","unified":"1F9E2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e2.png","sheet_x":47,"sheet_y":43,"short_name":"billed_cap","short_names":["billed_cap"],"text":null,"texts":null,"category":"Smileys & People","sort_order":468,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SCARF","unified":"1F9E3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e3.png","sheet_x":47,"sheet_y":44,"short_name":"scarf","short_names":["scarf"],"text":null,"texts":null,"category":"Smileys & People","sort_order":444,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"GLOVES","unified":"1F9E4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e4.png","sheet_x":47,"sheet_y":45,"short_name":"gloves","short_names":["gloves"],"text":null,"texts":null,"category":"Smileys & People","sort_order":445,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"COAT","unified":"1F9E5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e5.png","sheet_x":47,"sheet_y":46,"short_name":"coat","short_names":["coat"],"text":null,"texts":null,"category":"Smileys & People","sort_order":446,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SOCKS","unified":"1F9E6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e6.png","sheet_x":47,"sheet_y":47,"short_name":"socks","short_names":["socks"],"text":null,"texts":null,"category":"Smileys & People","sort_order":447,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"RED GIFT ENVELOPE","unified":"1F9E7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e7.png","sheet_x":47,"sheet_y":48,"short_name":"red_envelope","short_names":["red_envelope"],"text":null,"texts":null,"category":"Activities","sort_order":16,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"FIRECRACKER","unified":"1F9E8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e8.png","sheet_x":47,"sheet_y":49,"short_name":"firecracker","short_names":["firecracker"],"text":null,"texts":null,"category":"Activities","sort_order":5,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"JIGSAW PUZZLE PIECE","unified":"1F9E9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9e9.png","sheet_x":47,"sheet_y":50,"short_name":"jigsaw","short_names":["jigsaw"],"text":null,"texts":null,"category":"Activities","sort_order":62,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"TEST TUBE","unified":"1F9EA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9ea.png","sheet_x":47,"sheet_y":51,"short_name":"test_tube","short_names":["test_tube"],"text":null,"texts":null,"category":"Objects","sort_order":155,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"PETRI DISH","unified":"1F9EB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9eb.png","sheet_x":47,"sheet_y":52,"short_name":"petri_dish","short_names":["petri_dish"],"text":null,"texts":null,"category":"Objects","sort_order":156,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"DNA DOUBLE HELIX","unified":"1F9EC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9ec.png","sheet_x":48,"sheet_y":0,"short_name":"dna","short_names":["dna"],"text":null,"texts":null,"category":"Objects","sort_order":157,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"COMPASS","unified":"1F9ED","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9ed.png","sheet_x":48,"sheet_y":1,"short_name":"compass","short_names":["compass"],"text":null,"texts":null,"category":"Travel & Places","sort_order":7,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"ABACUS","unified":"1F9EE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9ee.png","sheet_x":48,"sheet_y":2,"short_name":"abacus","short_names":["abacus"],"text":null,"texts":null,"category":"Objects","sort_order":43,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"FIRE EXTINGUISHER","unified":"1F9EF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9ef.png","sheet_x":48,"sheet_y":3,"short_name":"fire_extinguisher","short_names":["fire_extinguisher"],"text":null,"texts":null,"category":"Objects","sort_order":176,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"TOOLBOX","unified":"1F9F0","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f0.png","sheet_x":48,"sheet_y":4,"short_name":"toolbox","short_names":["toolbox"],"text":null,"texts":null,"category":"Objects","sort_order":152,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"BRICK","unified":"1F9F1","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f1.png","sheet_x":48,"sheet_y":5,"short_name":"bricks","short_names":["bricks"],"text":null,"texts":null,"category":"Travel & Places","sort_order":20,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"MAGNET","unified":"1F9F2","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f2.png","sheet_x":48,"sheet_y":6,"short_name":"magnet","short_names":["magnet"],"text":null,"texts":null,"category":"Objects","sort_order":153,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"LUGGAGE","unified":"1F9F3","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f3.png","sheet_x":48,"sheet_y":7,"short_name":"luggage","short_names":["luggage"],"text":null,"texts":null,"category":"Travel & Places","sort_order":126,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"LOTION BOTTLE","unified":"1F9F4","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f4.png","sheet_x":48,"sheet_y":8,"short_name":"lotion_bottle","short_names":["lotion_bottle"],"text":null,"texts":null,"category":"Objects","sort_order":169,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"SPOOL OF THREAD","unified":"1F9F5","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f5.png","sheet_x":48,"sheet_y":9,"short_name":"thread","short_names":["thread"],"text":null,"texts":null,"category":"Activities","sort_order":75,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"BALL OF YARN","unified":"1F9F6","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f6.png","sheet_x":48,"sheet_y":10,"short_name":"yarn","short_names":["yarn"],"text":null,"texts":null,"category":"Activities","sort_order":76,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"SAFETY PIN","unified":"1F9F7","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f7.png","sheet_x":48,"sheet_y":11,"short_name":"safety_pin","short_names":["safety_pin"],"text":null,"texts":null,"category":"Objects","sort_order":170,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"TEDDY BEAR","unified":"1F9F8","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f8.png","sheet_x":48,"sheet_y":12,"short_name":"teddy_bear","short_names":["teddy_bear"],"text":null,"texts":null,"category":"Activities","sort_order":63,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"BROOM","unified":"1F9F9","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9f9.png","sheet_x":48,"sheet_y":13,"short_name":"broom","short_names":["broom"],"text":null,"texts":null,"category":"Objects","sort_order":171,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"BASKET","unified":"1F9FA","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9fa.png","sheet_x":48,"sheet_y":14,"short_name":"basket","short_names":["basket"],"text":null,"texts":null,"category":"Objects","sort_order":172,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"ROLL OF PAPER","unified":"1F9FB","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9fb.png","sheet_x":48,"sheet_y":15,"short_name":"roll_of_paper","short_names":["roll_of_paper"],"text":null,"texts":null,"category":"Objects","sort_order":173,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"BAR OF SOAP","unified":"1F9FC","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9fc.png","sheet_x":48,"sheet_y":16,"short_name":"soap","short_names":["soap"],"text":null,"texts":null,"category":"Objects","sort_order":174,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"SPONGE","unified":"1F9FD","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9fd.png","sheet_x":48,"sheet_y":17,"short_name":"sponge","short_names":["sponge"],"text":null,"texts":null,"category":"Objects","sort_order":175,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"RECEIPT","unified":"1F9FE","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9fe.png","sheet_x":48,"sheet_y":18,"short_name":"receipt","short_names":["receipt"],"text":null,"texts":null,"category":"Objects","sort_order":83,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"NAZAR AMULET","unified":"1F9FF","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"1f9ff.png","sheet_x":48,"sheet_y":19,"short_name":"nazar_amulet","short_names":["nazar_amulet"],"text":null,"texts":null,"category":"Activities","sort_order":57,"added_in":"11.0","has_img_apple":true,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"DOUBLE EXCLAMATION MARK","unified":"203C-FE0F","non_qualified":"203C","docomo":"E704","au":"EB30","softbank":null,"google":"FEB06","image":"203c-fe0f.png","sheet_x":48,"sheet_y":20,"short_name":"bangbang","short_names":["bangbang"],"text":null,"texts":null,"category":"Symbols","sort_order":122,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EXCLAMATION QUESTION MARK","unified":"2049-FE0F","non_qualified":"2049","docomo":"E703","au":"EB2F","softbank":null,"google":"FEB05","image":"2049-fe0f.png","sheet_x":48,"sheet_y":21,"short_name":"interrobang","short_names":["interrobang"],"text":null,"texts":null,"category":"Symbols","sort_order":123,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TRADE MARK SIGN","unified":"2122-FE0F","non_qualified":"2122","docomo":"E732","au":"E54E","softbank":"E537","google":"FEB2A","image":"2122-fe0f.png","sheet_x":48,"sheet_y":22,"short_name":"tm","short_names":["tm"],"text":null,"texts":null,"category":"Symbols","sort_order":131,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"INFORMATION SOURCE","unified":"2139-FE0F","non_qualified":"2139","docomo":null,"au":"E533","softbank":null,"google":"FEB47","image":"2139-fe0f.png","sheet_x":48,"sheet_y":23,"short_name":"information_source","short_names":["information_source"],"text":null,"texts":null,"category":"Symbols","sort_order":157,"added_in":"3.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEFT RIGHT ARROW","unified":"2194-FE0F","non_qualified":"2194","docomo":"E73C","au":"EB7A","softbank":null,"google":"FEAF6","image":"2194-fe0f.png","sheet_x":48,"sheet_y":24,"short_name":"left_right_arrow","short_names":["left_right_arrow"],"text":null,"texts":null,"category":"Symbols","sort_order":36,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"UP DOWN ARROW","unified":"2195-FE0F","non_qualified":"2195","docomo":"E73D","au":"EB7B","softbank":null,"google":"FEAF7","image":"2195-fe0f.png","sheet_x":48,"sheet_y":25,"short_name":"arrow_up_down","short_names":["arrow_up_down"],"text":null,"texts":null,"category":"Symbols","sort_order":35,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NORTH WEST ARROW","unified":"2196-FE0F","non_qualified":"2196","docomo":"E697","au":"E54C","softbank":"E237","google":"FEAF2","image":"2196-fe0f.png","sheet_x":48,"sheet_y":26,"short_name":"arrow_upper_left","short_names":["arrow_upper_left"],"text":null,"texts":null,"category":"Symbols","sort_order":34,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NORTH EAST ARROW","unified":"2197-FE0F","non_qualified":"2197","docomo":"E678","au":"E555","softbank":"E236","google":"FEAF0","image":"2197-fe0f.png","sheet_x":48,"sheet_y":27,"short_name":"arrow_upper_right","short_names":["arrow_upper_right"],"text":null,"texts":null,"category":"Symbols","sort_order":28,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SOUTH EAST ARROW","unified":"2198-FE0F","non_qualified":"2198","docomo":"E696","au":"E54D","softbank":"E238","google":"FEAF1","image":"2198-fe0f.png","sheet_x":48,"sheet_y":28,"short_name":"arrow_lower_right","short_names":["arrow_lower_right"],"text":null,"texts":null,"category":"Symbols","sort_order":30,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SOUTH WEST ARROW","unified":"2199-FE0F","non_qualified":"2199","docomo":"E6A5","au":"E556","softbank":"E239","google":"FEAF3","image":"2199-fe0f.png","sheet_x":48,"sheet_y":29,"short_name":"arrow_lower_left","short_names":["arrow_lower_left"],"text":null,"texts":null,"category":"Symbols","sort_order":32,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEFTWARDS ARROW WITH HOOK","unified":"21A9-FE0F","non_qualified":"21A9","docomo":"E6DA","au":"E55D","softbank":null,"google":"FEB83","image":"21a9-fe0f.png","sheet_x":48,"sheet_y":30,"short_name":"leftwards_arrow_with_hook","short_names":["leftwards_arrow_with_hook"],"text":null,"texts":null,"category":"Symbols","sort_order":37,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RIGHTWARDS ARROW WITH HOOK","unified":"21AA-FE0F","non_qualified":"21AA","docomo":null,"au":"E55C","softbank":null,"google":"FEB88","image":"21aa-fe0f.png","sheet_x":48,"sheet_y":31,"short_name":"arrow_right_hook","short_names":["arrow_right_hook"],"text":null,"texts":null,"category":"Symbols","sort_order":38,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WATCH","unified":"231A","non_qualified":null,"docomo":"E71F","au":"E57A","softbank":null,"google":"FE01D","image":"231a.png","sheet_x":48,"sheet_y":32,"short_name":"watch","short_names":["watch"],"text":null,"texts":null,"category":"Travel & Places","sort_order":129,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HOURGLASS","unified":"231B","non_qualified":null,"docomo":"E71C","au":"E57B","softbank":null,"google":"FE01C","image":"231b.png","sheet_x":48,"sheet_y":33,"short_name":"hourglass","short_names":["hourglass"],"text":null,"texts":null,"category":"Travel & Places","sort_order":127,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"2328-FE0F","non_qualified":"2328","docomo":null,"au":null,"softbank":null,"google":null,"image":"2328-fe0f.png","sheet_x":48,"sheet_y":34,"short_name":"keyboard","short_names":["keyboard"],"text":null,"texts":null,"category":"Objects","sort_order":36,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"23CF-FE0F","non_qualified":"23CF","docomo":null,"au":null,"softbank":null,"google":null,"image":"23cf-fe0f.png","sheet_x":48,"sheet_y":35,"short_name":"eject","short_names":["eject"],"text":null,"texts":null,"category":"Symbols","sort_order":90,"added_in":"4.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BLACK RIGHT-POINTING DOUBLE TRIANGLE","unified":"23E9","non_qualified":null,"docomo":null,"au":"E530","softbank":"E23C","google":"FEAFE","image":"23e9.png","sheet_x":48,"sheet_y":36,"short_name":"fast_forward","short_names":["fast_forward"],"text":null,"texts":null,"category":"Symbols","sort_order":77,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK LEFT-POINTING DOUBLE TRIANGLE","unified":"23EA","non_qualified":null,"docomo":null,"au":"E52F","softbank":"E23D","google":"FEAFF","image":"23ea.png","sheet_x":48,"sheet_y":37,"short_name":"rewind","short_names":["rewind"],"text":null,"texts":null,"category":"Symbols","sort_order":81,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK UP-POINTING DOUBLE TRIANGLE","unified":"23EB","non_qualified":null,"docomo":null,"au":"E545","softbank":null,"google":"FEB03","image":"23eb.png","sheet_x":48,"sheet_y":38,"short_name":"arrow_double_up","short_names":["arrow_double_up"],"text":null,"texts":null,"category":"Symbols","sort_order":84,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK DOWN-POINTING DOUBLE TRIANGLE","unified":"23EC","non_qualified":null,"docomo":null,"au":"E544","softbank":null,"google":"FEB02","image":"23ec.png","sheet_x":48,"sheet_y":39,"short_name":"arrow_double_down","short_names":["arrow_double_down"],"text":null,"texts":null,"category":"Symbols","sort_order":86,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"23ED-FE0F","non_qualified":"23ED","docomo":null,"au":null,"softbank":null,"google":null,"image":"23ed-fe0f.png","sheet_x":48,"sheet_y":40,"short_name":"black_right_pointing_double_triangle_with_vertical_bar","short_names":["black_right_pointing_double_triangle_with_vertical_bar"],"text":null,"texts":null,"category":"Symbols","sort_order":78,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"23EE-FE0F","non_qualified":"23EE","docomo":null,"au":null,"softbank":null,"google":null,"image":"23ee-fe0f.png","sheet_x":48,"sheet_y":41,"short_name":"black_left_pointing_double_triangle_with_vertical_bar","short_names":["black_left_pointing_double_triangle_with_vertical_bar"],"text":null,"texts":null,"category":"Symbols","sort_order":82,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"23EF-FE0F","non_qualified":"23EF","docomo":null,"au":null,"softbank":null,"google":null,"image":"23ef-fe0f.png","sheet_x":48,"sheet_y":42,"short_name":"black_right_pointing_triangle_with_double_vertical_bar","short_names":["black_right_pointing_triangle_with_double_vertical_bar"],"text":null,"texts":null,"category":"Symbols","sort_order":79,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"ALARM CLOCK","unified":"23F0","non_qualified":null,"docomo":"E6BA","au":"E594","softbank":null,"google":"FE02A","image":"23f0.png","sheet_x":48,"sheet_y":43,"short_name":"alarm_clock","short_names":["alarm_clock"],"text":null,"texts":null,"category":"Travel & Places","sort_order":130,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"23F1-FE0F","non_qualified":"23F1","docomo":null,"au":null,"softbank":null,"google":null,"image":"23f1-fe0f.png","sheet_x":48,"sheet_y":44,"short_name":"stopwatch","short_names":["stopwatch"],"text":null,"texts":null,"category":"Travel & Places","sort_order":131,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"23F2-FE0F","non_qualified":"23F2","docomo":null,"au":null,"softbank":null,"google":null,"image":"23f2-fe0f.png","sheet_x":48,"sheet_y":45,"short_name":"timer_clock","short_names":["timer_clock"],"text":null,"texts":null,"category":"Travel & Places","sort_order":132,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"HOURGLASS WITH FLOWING SAND","unified":"23F3","non_qualified":null,"docomo":"E71C","au":"E47C","softbank":null,"google":"FE01B","image":"23f3.png","sheet_x":48,"sheet_y":46,"short_name":"hourglass_flowing_sand","short_names":["hourglass_flowing_sand"],"text":null,"texts":null,"category":"Travel & Places","sort_order":128,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"23F8-FE0F","non_qualified":"23F8","docomo":null,"au":null,"softbank":null,"google":null,"image":"23f8-fe0f.png","sheet_x":48,"sheet_y":47,"short_name":"double_vertical_bar","short_names":["double_vertical_bar"],"text":null,"texts":null,"category":"Symbols","sort_order":87,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"23F9-FE0F","non_qualified":"23F9","docomo":null,"au":null,"softbank":null,"google":null,"image":"23f9-fe0f.png","sheet_x":48,"sheet_y":48,"short_name":"black_square_for_stop","short_names":["black_square_for_stop"],"text":null,"texts":null,"category":"Symbols","sort_order":88,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"23FA-FE0F","non_qualified":"23FA","docomo":null,"au":null,"softbank":null,"google":null,"image":"23fa-fe0f.png","sheet_x":48,"sheet_y":49,"short_name":"black_circle_for_record","short_names":["black_circle_for_record"],"text":null,"texts":null,"category":"Symbols","sort_order":89,"added_in":"7.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CIRCLED LATIN CAPITAL LETTER M","unified":"24C2-FE0F","non_qualified":"24C2","docomo":"E65C","au":"E5BC","softbank":null,"google":"FE7E1","image":"24c2-fe0f.png","sheet_x":48,"sheet_y":50,"short_name":"m","short_names":["m"],"text":null,"texts":null,"category":"Symbols","sort_order":159,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK SMALL SQUARE","unified":"25AA-FE0F","non_qualified":"25AA","docomo":null,"au":"E532","softbank":null,"google":"FEB6E","image":"25aa-fe0f.png","sheet_x":48,"sheet_y":51,"short_name":"black_small_square","short_names":["black_small_square"],"text":null,"texts":null,"category":"Symbols","sort_order":185,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE SMALL SQUARE","unified":"25AB-FE0F","non_qualified":"25AB","docomo":null,"au":"E531","softbank":null,"google":"FEB6D","image":"25ab-fe0f.png","sheet_x":48,"sheet_y":52,"short_name":"white_small_square","short_names":["white_small_square"],"text":null,"texts":null,"category":"Symbols","sort_order":186,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK RIGHT-POINTING TRIANGLE","unified":"25B6-FE0F","non_qualified":"25B6","docomo":null,"au":"E52E","softbank":"E23A","google":"FEAFC","image":"25b6-fe0f.png","sheet_x":49,"sheet_y":0,"short_name":"arrow_forward","short_names":["arrow_forward"],"text":null,"texts":null,"category":"Symbols","sort_order":76,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK LEFT-POINTING TRIANGLE","unified":"25C0-FE0F","non_qualified":"25C0","docomo":null,"au":"E52D","softbank":"E23B","google":"FEAFD","image":"25c0-fe0f.png","sheet_x":49,"sheet_y":1,"short_name":"arrow_backward","short_names":["arrow_backward"],"text":null,"texts":null,"category":"Symbols","sort_order":80,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE MEDIUM SQUARE","unified":"25FB-FE0F","non_qualified":"25FB","docomo":null,"au":"E538","softbank":null,"google":"FEB71","image":"25fb-fe0f.png","sheet_x":49,"sheet_y":2,"short_name":"white_medium_square","short_names":["white_medium_square"],"text":null,"texts":null,"category":"Symbols","sort_order":187,"added_in":"3.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK MEDIUM SQUARE","unified":"25FC-FE0F","non_qualified":"25FC","docomo":null,"au":"E539","softbank":null,"google":"FEB72","image":"25fc-fe0f.png","sheet_x":49,"sheet_y":3,"short_name":"black_medium_square","short_names":["black_medium_square"],"text":null,"texts":null,"category":"Symbols","sort_order":188,"added_in":"3.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE MEDIUM SMALL SQUARE","unified":"25FD","non_qualified":null,"docomo":null,"au":"E534","softbank":null,"google":"FEB6F","image":"25fd.png","sheet_x":49,"sheet_y":4,"short_name":"white_medium_small_square","short_names":["white_medium_small_square"],"text":null,"texts":null,"category":"Symbols","sort_order":189,"added_in":"3.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK MEDIUM SMALL SQUARE","unified":"25FE","non_qualified":null,"docomo":null,"au":"E535","softbank":null,"google":"FEB70","image":"25fe.png","sheet_x":49,"sheet_y":5,"short_name":"black_medium_small_square","short_names":["black_medium_small_square"],"text":null,"texts":null,"category":"Symbols","sort_order":190,"added_in":"3.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK SUN WITH RAYS","unified":"2600-FE0F","non_qualified":"2600","docomo":"E63E","au":"E488","softbank":"E04A","google":"FE000","image":"2600-fe0f.png","sheet_x":49,"sheet_y":6,"short_name":"sunny","short_names":["sunny"],"text":null,"texts":null,"category":"Travel & Places","sort_order":171,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CLOUD","unified":"2601-FE0F","non_qualified":"2601","docomo":"E63F","au":"E48D","softbank":"E049","google":"FE001","image":"2601-fe0f.png","sheet_x":49,"sheet_y":7,"short_name":"cloud","short_names":["cloud"],"text":null,"texts":null,"category":"Travel & Places","sort_order":177,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"2602-FE0F","non_qualified":"2602","docomo":null,"au":null,"softbank":null,"google":null,"image":"2602-fe0f.png","sheet_x":49,"sheet_y":8,"short_name":"umbrella","short_names":["umbrella"],"text":null,"texts":null,"category":"Travel & Places","sort_order":192,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2603-FE0F","non_qualified":"2603","docomo":null,"au":null,"softbank":null,"google":null,"image":"2603-fe0f.png","sheet_x":49,"sheet_y":9,"short_name":"snowman","short_names":["snowman"],"text":null,"texts":null,"category":"Travel & Places","sort_order":197,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2604-FE0F","non_qualified":"2604","docomo":null,"au":null,"softbank":null,"google":null,"image":"2604-fe0f.png","sheet_x":49,"sheet_y":10,"short_name":"comet","short_names":["comet"],"text":null,"texts":null,"category":"Travel & Places","sort_order":199,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"BLACK TELEPHONE","unified":"260E-FE0F","non_qualified":"260E","docomo":"E687","au":"E596","softbank":"E009","google":"FE523","image":"260e-fe0f.png","sheet_x":49,"sheet_y":11,"short_name":"phone","short_names":["phone","telephone"],"text":null,"texts":null,"category":"Objects","sort_order":27,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BALLOT BOX WITH CHECK","unified":"2611-FE0F","non_qualified":"2611","docomo":null,"au":"EB02","softbank":null,"google":"FEB8B","image":"2611-fe0f.png","sheet_x":49,"sheet_y":12,"short_name":"ballot_box_with_check","short_names":["ballot_box_with_check"],"text":null,"texts":null,"category":"Symbols","sort_order":108,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"UMBRELLA WITH RAIN DROPS","unified":"2614","non_qualified":null,"docomo":"E640","au":"E48C","softbank":"E04B","google":"FE002","image":"2614.png","sheet_x":49,"sheet_y":13,"short_name":"umbrella_with_rain_drops","short_names":["umbrella_with_rain_drops"],"text":null,"texts":null,"category":"Travel & Places","sort_order":193,"added_in":"4.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HOT BEVERAGE","unified":"2615","non_qualified":null,"docomo":"E670","au":"E597","softbank":"E045","google":"FE981","image":"2615.png","sheet_x":49,"sheet_y":14,"short_name":"coffee","short_names":["coffee"],"text":null,"texts":null,"category":"Food & Drink","sort_order":91,"added_in":"4.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"2618-FE0F","non_qualified":"2618","docomo":null,"au":null,"softbank":null,"google":null,"image":"2618-fe0f.png","sheet_x":49,"sheet_y":15,"short_name":"shamrock","short_names":["shamrock"],"text":null,"texts":null,"category":"Animals & Nature","sort_order":120,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"WHITE UP POINTING INDEX","unified":"261D-FE0F","non_qualified":"261D","docomo":null,"au":"E4F6","softbank":"E00F","google":"FEB98","image":"261d-fe0f.png","sheet_x":49,"sheet_y":16,"short_name":"point_up","short_names":["point_up"],"text":null,"texts":null,"category":"Smileys & People","sort_order":366,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"261D-1F3FB","non_qualified":null,"image":"261d-1f3fb.png","sheet_x":49,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"261D-1F3FC","non_qualified":null,"image":"261d-1f3fc.png","sheet_x":49,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"261D-1F3FD","non_qualified":null,"image":"261d-1f3fd.png","sheet_x":49,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"261D-1F3FE","non_qualified":null,"image":"261d-1f3fe.png","sheet_x":49,"sheet_y":20,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"261D-1F3FF","non_qualified":null,"image":"261d-1f3ff.png","sheet_x":49,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"2620-FE0F","non_qualified":"2620","docomo":null,"au":null,"softbank":null,"google":null,"image":"2620-fe0f.png","sheet_x":49,"sheet_y":22,"short_name":"skull_and_crossbones","short_names":["skull_and_crossbones"],"text":null,"texts":null,"category":"Smileys & People","sort_order":96,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2622-FE0F","non_qualified":"2622","docomo":null,"au":null,"softbank":null,"google":null,"image":"2622-fe0f.png","sheet_x":49,"sheet_y":23,"short_name":"radioactive_sign","short_names":["radioactive_sign"],"text":null,"texts":null,"category":"Symbols","sort_order":25,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2623-FE0F","non_qualified":"2623","docomo":null,"au":null,"softbank":null,"google":null,"image":"2623-fe0f.png","sheet_x":49,"sheet_y":24,"short_name":"biohazard_sign","short_names":["biohazard_sign"],"text":null,"texts":null,"category":"Symbols","sort_order":26,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2626-FE0F","non_qualified":"2626","docomo":null,"au":null,"softbank":null,"google":null,"image":"2626-fe0f.png","sheet_x":49,"sheet_y":25,"short_name":"orthodox_cross","short_names":["orthodox_cross"],"text":null,"texts":null,"category":"Symbols","sort_order":55,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"262A-FE0F","non_qualified":"262A","docomo":null,"au":null,"softbank":null,"google":null,"image":"262a-fe0f.png","sheet_x":49,"sheet_y":26,"short_name":"star_and_crescent","short_names":["star_and_crescent"],"text":null,"texts":null,"category":"Symbols","sort_order":56,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"262E-FE0F","non_qualified":"262E","docomo":null,"au":null,"softbank":null,"google":null,"image":"262e-fe0f.png","sheet_x":49,"sheet_y":27,"short_name":"peace_symbol","short_names":["peace_symbol"],"text":null,"texts":null,"category":"Symbols","sort_order":57,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"262F-FE0F","non_qualified":"262F","docomo":null,"au":null,"softbank":null,"google":null,"image":"262f-fe0f.png","sheet_x":49,"sheet_y":28,"short_name":"yin_yang","short_names":["yin_yang"],"text":null,"texts":null,"category":"Symbols","sort_order":53,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2638-FE0F","non_qualified":"2638","docomo":null,"au":null,"softbank":null,"google":null,"image":"2638-fe0f.png","sheet_x":49,"sheet_y":29,"short_name":"wheel_of_dharma","short_names":["wheel_of_dharma"],"text":null,"texts":null,"category":"Symbols","sort_order":52,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2639-FE0F","non_qualified":"2639","docomo":null,"au":null,"softbank":null,"google":null,"image":"2639-fe0f.png","sheet_x":49,"sheet_y":30,"short_name":"white_frowning_face","short_names":["white_frowning_face"],"text":null,"texts":null,"category":"Smileys & People","sort_order":50,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"WHITE SMILING FACE","unified":"263A-FE0F","non_qualified":"263A","docomo":"E6F0","au":"E4FB","softbank":"E414","google":"FE336","image":"263a-fe0f.png","sheet_x":49,"sheet_y":31,"short_name":"relaxed","short_names":["relaxed"],"text":null,"texts":null,"category":"Smileys & People","sort_order":19,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"2640-FE0F","non_qualified":"2640","docomo":null,"au":null,"softbank":null,"google":null,"image":"2640-fe0f.png","sheet_x":49,"sheet_y":32,"short_name":"female_sign","short_names":["female_sign"],"text":null,"texts":null,"category":"Symbols","sort_order":97,"added_in":"1.1","has_img_apple":false,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2642-FE0F","non_qualified":"2642","docomo":null,"au":null,"softbank":null,"google":null,"image":"2642-fe0f.png","sheet_x":49,"sheet_y":33,"short_name":"male_sign","short_names":["male_sign"],"text":null,"texts":null,"category":"Symbols","sort_order":98,"added_in":"1.1","has_img_apple":false,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"ARIES","unified":"2648","non_qualified":null,"docomo":"E646","au":"E48F","softbank":"E23F","google":"FE02B","image":"2648.png","sheet_x":49,"sheet_y":34,"short_name":"aries","short_names":["aries"],"text":null,"texts":null,"category":"Symbols","sort_order":60,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"TAURUS","unified":"2649","non_qualified":null,"docomo":"E647","au":"E490","softbank":"E240","google":"FE02C","image":"2649.png","sheet_x":49,"sheet_y":35,"short_name":"taurus","short_names":["taurus"],"text":null,"texts":null,"category":"Symbols","sort_order":61,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"GEMINI","unified":"264A","non_qualified":null,"docomo":"E648","au":"E491","softbank":"E241","google":"FE02D","image":"264a.png","sheet_x":49,"sheet_y":36,"short_name":"gemini","short_names":["gemini"],"text":null,"texts":null,"category":"Symbols","sort_order":62,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CANCER","unified":"264B","non_qualified":null,"docomo":"E649","au":"E492","softbank":"E242","google":"FE02E","image":"264b.png","sheet_x":49,"sheet_y":37,"short_name":"cancer","short_names":["cancer"],"text":null,"texts":null,"category":"Symbols","sort_order":63,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEO","unified":"264C","non_qualified":null,"docomo":"E64A","au":"E493","softbank":"E243","google":"FE02F","image":"264c.png","sheet_x":49,"sheet_y":38,"short_name":"leo","short_names":["leo"],"text":null,"texts":null,"category":"Symbols","sort_order":64,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"VIRGO","unified":"264D","non_qualified":null,"docomo":"E64B","au":"E494","softbank":"E244","google":"FE030","image":"264d.png","sheet_x":49,"sheet_y":39,"short_name":"virgo","short_names":["virgo"],"text":null,"texts":null,"category":"Symbols","sort_order":65,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LIBRA","unified":"264E","non_qualified":null,"docomo":"E64C","au":"E495","softbank":"E245","google":"FE031","image":"264e.png","sheet_x":49,"sheet_y":40,"short_name":"libra","short_names":["libra"],"text":null,"texts":null,"category":"Symbols","sort_order":66,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SCORPIUS","unified":"264F","non_qualified":null,"docomo":"E64D","au":"E496","softbank":"E246","google":"FE032","image":"264f.png","sheet_x":49,"sheet_y":41,"short_name":"scorpius","short_names":["scorpius"],"text":null,"texts":null,"category":"Symbols","sort_order":67,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SAGITTARIUS","unified":"2650","non_qualified":null,"docomo":"E64E","au":"E497","softbank":"E247","google":"FE033","image":"2650.png","sheet_x":49,"sheet_y":42,"short_name":"sagittarius","short_names":["sagittarius"],"text":null,"texts":null,"category":"Symbols","sort_order":68,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CAPRICORN","unified":"2651","non_qualified":null,"docomo":"E64F","au":"E498","softbank":"E248","google":"FE034","image":"2651.png","sheet_x":49,"sheet_y":43,"short_name":"capricorn","short_names":["capricorn"],"text":null,"texts":null,"category":"Symbols","sort_order":69,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"AQUARIUS","unified":"2652","non_qualified":null,"docomo":"E650","au":"E499","softbank":"E249","google":"FE035","image":"2652.png","sheet_x":49,"sheet_y":44,"short_name":"aquarius","short_names":["aquarius"],"text":null,"texts":null,"category":"Symbols","sort_order":70,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PISCES","unified":"2653","non_qualified":null,"docomo":"E651","au":"E49A","softbank":"E24A","google":"FE036","image":"2653.png","sheet_x":49,"sheet_y":45,"short_name":"pisces","short_names":["pisces"],"text":null,"texts":null,"category":"Symbols","sort_order":71,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"265F-FE0F","non_qualified":"265F","docomo":null,"au":null,"softbank":null,"google":null,"image":"265f-fe0f.png","sheet_x":49,"sheet_y":46,"short_name":"chess_pawn","short_names":["chess_pawn"],"text":null,"texts":null,"category":"Activities","sort_order":68,"added_in":"1.1","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"BLACK SPADE SUIT","unified":"2660-FE0F","non_qualified":"2660","docomo":"E68E","au":"E5A1","softbank":"E20E","google":"FEB1B","image":"2660-fe0f.png","sheet_x":49,"sheet_y":47,"short_name":"spades","short_names":["spades"],"text":null,"texts":null,"category":"Activities","sort_order":64,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK CLUB SUIT","unified":"2663-FE0F","non_qualified":"2663","docomo":"E690","au":"E5A3","softbank":"E20F","google":"FEB1D","image":"2663-fe0f.png","sheet_x":49,"sheet_y":48,"short_name":"clubs","short_names":["clubs"],"text":null,"texts":null,"category":"Activities","sort_order":67,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK HEART SUIT","unified":"2665-FE0F","non_qualified":"2665","docomo":"E68D","au":"EAA5","softbank":"E20C","google":"FEB1A","image":"2665-fe0f.png","sheet_x":49,"sheet_y":49,"short_name":"hearts","short_names":["hearts"],"text":null,"texts":null,"category":"Activities","sort_order":65,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK DIAMOND SUIT","unified":"2666-FE0F","non_qualified":"2666","docomo":"E68F","au":"E5A2","softbank":"E20D","google":"FEB1C","image":"2666-fe0f.png","sheet_x":49,"sheet_y":50,"short_name":"diamonds","short_names":["diamonds"],"text":null,"texts":null,"category":"Activities","sort_order":66,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HOT SPRINGS","unified":"2668-FE0F","non_qualified":"2668","docomo":"E6F7","au":"E4BC","softbank":"E123","google":"FE7FA","image":"2668-fe0f.png","sheet_x":49,"sheet_y":51,"short_name":"hotsprings","short_names":["hotsprings"],"text":null,"texts":null,"category":"Travel & Places","sort_order":56,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK UNIVERSAL RECYCLING SYMBOL","unified":"267B-FE0F","non_qualified":"267B","docomo":"E735","au":"EB79","softbank":null,"google":"FEB2C","image":"267b-fe0f.png","sheet_x":49,"sheet_y":52,"short_name":"recycle","short_names":["recycle"],"text":null,"texts":null,"category":"Symbols","sort_order":101,"added_in":"3.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"267E-FE0F","non_qualified":"267E","docomo":null,"au":null,"softbank":null,"google":null,"image":"267e-fe0f.png","sheet_x":50,"sheet_y":0,"short_name":"infinity","short_names":["infinity"],"text":null,"texts":null,"category":"Symbols","sort_order":100,"added_in":"4.1","has_img_apple":false,"has_img_google":false,"has_img_twitter":false,"has_img_facebook":false,"has_img_messenger":false},{"name":"WHEELCHAIR SYMBOL","unified":"267F","non_qualified":null,"docomo":"E69B","au":"E47F","softbank":"E20A","google":"FEB20","image":"267f.png","sheet_x":50,"sheet_y":1,"short_name":"wheelchair","short_names":["wheelchair"],"text":null,"texts":null,"category":"Symbols","sort_order":4,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"2692-FE0F","non_qualified":"2692","docomo":null,"au":null,"softbank":null,"google":null,"image":"2692-fe0f.png","sheet_x":50,"sheet_y":2,"short_name":"hammer_and_pick","short_names":["hammer_and_pick"],"text":null,"texts":null,"category":"Objects","sort_order":138,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"ANCHOR","unified":"2693","non_qualified":null,"docomo":"E661","au":"E4A9","softbank":null,"google":"FE4C1","image":"2693.png","sheet_x":50,"sheet_y":3,"short_name":"anchor","short_names":["anchor"],"text":null,"texts":null,"category":"Travel & Places","sort_order":105,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"2694-FE0F","non_qualified":"2694","docomo":null,"au":null,"softbank":null,"google":null,"image":"2694-fe0f.png","sheet_x":50,"sheet_y":4,"short_name":"crossed_swords","short_names":["crossed_swords"],"text":null,"texts":null,"category":"Objects","sort_order":141,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2695-FE0F","non_qualified":"2695","docomo":null,"au":null,"softbank":null,"google":null,"image":"2695-fe0f.png","sheet_x":50,"sheet_y":5,"short_name":"medical_symbol","short_names":["medical_symbol","staff_of_aesculapius"],"text":null,"texts":null,"category":"Symbols","sort_order":99,"added_in":"4.1","has_img_apple":false,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2696-FE0F","non_qualified":"2696","docomo":null,"au":null,"softbank":null,"google":null,"image":"2696-fe0f.png","sheet_x":50,"sheet_y":6,"short_name":"scales","short_names":["scales"],"text":null,"texts":null,"category":"Objects","sort_order":149,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2697-FE0F","non_qualified":"2697","docomo":null,"au":null,"softbank":null,"google":null,"image":"2697-fe0f.png","sheet_x":50,"sheet_y":7,"short_name":"alembic","short_names":["alembic"],"text":null,"texts":null,"category":"Objects","sort_order":154,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2699-FE0F","non_qualified":"2699","docomo":null,"au":null,"softbank":null,"google":null,"image":"2699-fe0f.png","sheet_x":50,"sheet_y":8,"short_name":"gear","short_names":["gear"],"text":null,"texts":null,"category":"Objects","sort_order":147,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"269B-FE0F","non_qualified":"269B","docomo":null,"au":null,"softbank":null,"google":null,"image":"269b-fe0f.png","sheet_x":50,"sheet_y":9,"short_name":"atom_symbol","short_names":["atom_symbol"],"text":null,"texts":null,"category":"Symbols","sort_order":49,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"269C-FE0F","non_qualified":"269C","docomo":null,"au":null,"softbank":null,"google":null,"image":"269c-fe0f.png","sheet_x":50,"sheet_y":10,"short_name":"fleur_de_lis","short_names":["fleur_de_lis"],"text":null,"texts":null,"category":"Symbols","sort_order":102,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"WARNING SIGN","unified":"26A0-FE0F","non_qualified":"26A0","docomo":"E737","au":"E481","softbank":"E252","google":"FEB23","image":"26a0-fe0f.png","sheet_x":50,"sheet_y":11,"short_name":"warning","short_names":["warning"],"text":null,"texts":null,"category":"Symbols","sort_order":14,"added_in":"4.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HIGH VOLTAGE SIGN","unified":"26A1","non_qualified":null,"docomo":"E642","au":"E487","softbank":"E13D","google":"FE004","image":"26a1.png","sheet_x":50,"sheet_y":12,"short_name":"zap","short_names":["zap"],"text":null,"texts":null,"category":"Travel & Places","sort_order":195,"added_in":"4.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MEDIUM WHITE CIRCLE","unified":"26AA","non_qualified":null,"docomo":"E69C","au":"E53A","softbank":null,"google":"FEB65","image":"26aa.png","sheet_x":50,"sheet_y":13,"short_name":"white_circle","short_names":["white_circle"],"text":null,"texts":null,"category":"Symbols","sort_order":203,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"MEDIUM BLACK CIRCLE","unified":"26AB","non_qualified":null,"docomo":"E69C","au":"E53B","softbank":null,"google":"FEB66","image":"26ab.png","sheet_x":50,"sheet_y":14,"short_name":"black_circle","short_names":["black_circle"],"text":null,"texts":null,"category":"Symbols","sort_order":204,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"26B0-FE0F","non_qualified":"26B0","docomo":null,"au":null,"softbank":null,"google":null,"image":"26b0-fe0f.png","sheet_x":50,"sheet_y":15,"short_name":"coffin","short_names":["coffin"],"text":null,"texts":null,"category":"Objects","sort_order":179,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"26B1-FE0F","non_qualified":"26B1","docomo":null,"au":null,"softbank":null,"google":null,"image":"26b1-fe0f.png","sheet_x":50,"sheet_y":16,"short_name":"funeral_urn","short_names":["funeral_urn"],"text":null,"texts":null,"category":"Objects","sort_order":180,"added_in":"4.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SOCCER BALL","unified":"26BD","non_qualified":null,"docomo":"E656","au":"E4B6","softbank":"E018","google":"FE7D4","image":"26bd.png","sheet_x":50,"sheet_y":17,"short_name":"soccer","short_names":["soccer"],"text":null,"texts":null,"category":"Activities","sort_order":28,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BASEBALL","unified":"26BE","non_qualified":null,"docomo":"E653","au":"E4BA","softbank":"E016","google":"FE7D1","image":"26be.png","sheet_x":50,"sheet_y":18,"short_name":"baseball","short_names":["baseball"],"text":null,"texts":null,"category":"Activities","sort_order":29,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SNOWMAN WITHOUT SNOW","unified":"26C4","non_qualified":null,"docomo":"E641","au":"E485","softbank":"E048","google":"FE003","image":"26c4.png","sheet_x":50,"sheet_y":19,"short_name":"snowman_without_snow","short_names":["snowman_without_snow"],"text":null,"texts":null,"category":"Travel & Places","sort_order":198,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SUN BEHIND CLOUD","unified":"26C5","non_qualified":null,"docomo":"E63E-E63F","au":"E48E","softbank":null,"google":"FE00F","image":"26c5.png","sheet_x":50,"sheet_y":20,"short_name":"partly_sunny","short_names":["partly_sunny"],"text":null,"texts":null,"category":"Travel & Places","sort_order":178,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"26C8-FE0F","non_qualified":"26C8","docomo":null,"au":null,"softbank":null,"google":null,"image":"26c8-fe0f.png","sheet_x":50,"sheet_y":21,"short_name":"thunder_cloud_and_rain","short_names":["thunder_cloud_and_rain"],"text":null,"texts":null,"category":"Travel & Places","sort_order":179,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"OPHIUCHUS","unified":"26CE","non_qualified":null,"docomo":null,"au":"E49B","softbank":"E24B","google":"FE037","image":"26ce.png","sheet_x":50,"sheet_y":22,"short_name":"ophiuchus","short_names":["ophiuchus"],"text":null,"texts":null,"category":"Symbols","sort_order":72,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"26CF-FE0F","non_qualified":"26CF","docomo":null,"au":null,"softbank":null,"google":null,"image":"26cf-fe0f.png","sheet_x":50,"sheet_y":23,"short_name":"pick","short_names":["pick"],"text":null,"texts":null,"category":"Objects","sort_order":137,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"26D1-FE0F","non_qualified":"26D1","docomo":null,"au":null,"softbank":null,"google":null,"image":"26d1-fe0f.png","sheet_x":50,"sheet_y":24,"short_name":"helmet_with_white_cross","short_names":["helmet_with_white_cross"],"text":null,"texts":null,"category":"Smileys & People","sort_order":469,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"26D3-FE0F","non_qualified":"26D3","docomo":null,"au":null,"softbank":null,"google":null,"image":"26d3-fe0f.png","sheet_x":50,"sheet_y":25,"short_name":"chains","short_names":["chains"],"text":null,"texts":null,"category":"Objects","sort_order":151,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"NO ENTRY","unified":"26D4","non_qualified":null,"docomo":"E72F","au":"E484","softbank":null,"google":"FEB26","image":"26d4.png","sheet_x":50,"sheet_y":26,"short_name":"no_entry","short_names":["no_entry"],"text":null,"texts":null,"category":"Symbols","sort_order":16,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"26E9-FE0F","non_qualified":"26E9","docomo":null,"au":null,"softbank":null,"google":null,"image":"26e9-fe0f.png","sheet_x":50,"sheet_y":27,"short_name":"shinto_shrine","short_names":["shinto_shrine"],"text":null,"texts":null,"category":"Travel & Places","sort_order":44,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"CHURCH","unified":"26EA","non_qualified":null,"docomo":null,"au":"E5BB","softbank":"E037","google":"FE4BB","image":"26ea.png","sheet_x":50,"sheet_y":28,"short_name":"church","short_names":["church"],"text":null,"texts":null,"category":"Travel & Places","sort_order":41,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"26F0-FE0F","non_qualified":"26F0","docomo":null,"au":null,"softbank":null,"google":null,"image":"26f0-fe0f.png","sheet_x":50,"sheet_y":29,"short_name":"mountain","short_names":["mountain"],"text":null,"texts":null,"category":"Travel & Places","sort_order":9,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"26F1-FE0F","non_qualified":"26F1","docomo":null,"au":null,"softbank":null,"google":null,"image":"26f1-fe0f.png","sheet_x":50,"sheet_y":30,"short_name":"umbrella_on_ground","short_names":["umbrella_on_ground"],"text":null,"texts":null,"category":"Travel & Places","sort_order":194,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"FOUNTAIN","unified":"26F2","non_qualified":null,"docomo":null,"au":"E5CF","softbank":"E121","google":"FE4BC","image":"26f2.png","sheet_x":50,"sheet_y":31,"short_name":"fountain","short_names":["fountain"],"text":null,"texts":null,"category":"Travel & Places","sort_order":46,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FLAG IN HOLE","unified":"26F3","non_qualified":null,"docomo":"E654","au":"E599","softbank":"E014","google":"FE7D2","image":"26f3.png","sheet_x":50,"sheet_y":32,"short_name":"golf","short_names":["golf"],"text":null,"texts":null,"category":"Activities","sort_order":47,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"26F4-FE0F","non_qualified":"26F4","docomo":null,"au":null,"softbank":null,"google":null,"image":"26f4-fe0f.png","sheet_x":50,"sheet_y":33,"short_name":"ferry","short_names":["ferry"],"text":null,"texts":null,"category":"Travel & Places","sort_order":110,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SAILBOAT","unified":"26F5","non_qualified":null,"docomo":"E6A3","au":"E4B4","softbank":"E01C","google":"FE7EA","image":"26f5.png","sheet_x":50,"sheet_y":34,"short_name":"boat","short_names":["boat","sailboat"],"text":null,"texts":null,"category":"Travel & Places","sort_order":106,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"26F7-FE0F","non_qualified":"26F7","docomo":null,"au":null,"softbank":null,"google":null,"image":"26f7-fe0f.png","sheet_x":50,"sheet_y":35,"short_name":"skier","short_names":["skier"],"text":null,"texts":null,"category":"Smileys & People","sort_order":280,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"26F8-FE0F","non_qualified":"26F8","docomo":null,"au":null,"softbank":null,"google":null,"image":"26f8-fe0f.png","sheet_x":50,"sheet_y":36,"short_name":"ice_skate","short_names":["ice_skate"],"text":null,"texts":null,"category":"Activities","sort_order":48,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"26F9-FE0F-200D-2640-FE0F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"26f9-fe0f-200d-2640-fe0f.png","sheet_x":50,"sheet_y":37,"short_name":"woman-bouncing-ball","short_names":["woman-bouncing-ball"],"text":null,"texts":null,"category":"Smileys & People","sort_order":296,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"26F9-1F3FB-200D-2640-FE0F","non_qualified":"26F9-1F3FB-200D-2640","image":"26f9-1f3fb-200d-2640-fe0f.png","sheet_x":50,"sheet_y":38,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"26F9-1F3FC-200D-2640-FE0F","non_qualified":"26F9-1F3FC-200D-2640","image":"26f9-1f3fc-200d-2640-fe0f.png","sheet_x":50,"sheet_y":39,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"26F9-1F3FD-200D-2640-FE0F","non_qualified":"26F9-1F3FD-200D-2640","image":"26f9-1f3fd-200d-2640-fe0f.png","sheet_x":50,"sheet_y":40,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"26F9-1F3FE-200D-2640-FE0F","non_qualified":"26F9-1F3FE-200D-2640","image":"26f9-1f3fe-200d-2640-fe0f.png","sheet_x":50,"sheet_y":41,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"26F9-1F3FF-200D-2640-FE0F","non_qualified":"26F9-1F3FF-200D-2640","image":"26f9-1f3ff-200d-2640-fe0f.png","sheet_x":50,"sheet_y":42,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}}},{"name":null,"unified":"26F9-FE0F-200D-2642-FE0F","non_qualified":null,"docomo":null,"au":null,"softbank":null,"google":null,"image":"26f9-fe0f-200d-2642-fe0f.png","sheet_x":50,"sheet_y":43,"short_name":"man-bouncing-ball","short_names":["man-bouncing-ball"],"text":null,"texts":null,"category":"Smileys & People","sort_order":295,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"26F9-1F3FB-200D-2642-FE0F","non_qualified":"26F9-1F3FB-200D-2642","image":"26f9-1f3fb-200d-2642-fe0f.png","sheet_x":50,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"26F9-1F3FC-200D-2642-FE0F","non_qualified":"26F9-1F3FC-200D-2642","image":"26f9-1f3fc-200d-2642-fe0f.png","sheet_x":50,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"26F9-1F3FD-200D-2642-FE0F","non_qualified":"26F9-1F3FD-200D-2642","image":"26f9-1f3fd-200d-2642-fe0f.png","sheet_x":50,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"26F9-1F3FE-200D-2642-FE0F","non_qualified":"26F9-1F3FE-200D-2642","image":"26f9-1f3fe-200d-2642-fe0f.png","sheet_x":50,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"26F9-1F3FF-200D-2642-FE0F","non_qualified":"26F9-1F3FF-200D-2642","image":"26f9-1f3ff-200d-2642-fe0f.png","sheet_x":50,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoletes":"26F9-FE0F"},{"name":null,"unified":"26F9-FE0F","non_qualified":"26F9","docomo":null,"au":null,"softbank":null,"google":null,"image":"26f9-fe0f.png","sheet_x":50,"sheet_y":49,"short_name":"person_with_ball","short_names":["person_with_ball"],"text":null,"texts":null,"category":"Smileys & People","sort_order":294,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"26F9-1F3FB","non_qualified":null,"image":"26f9-1f3fb.png","sheet_x":50,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"26F9-1F3FC","non_qualified":null,"image":"26f9-1f3fc.png","sheet_x":50,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"26F9-1F3FD","non_qualified":null,"image":"26f9-1f3fd.png","sheet_x":50,"sheet_y":52,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"26F9-1F3FE","non_qualified":null,"image":"26f9-1f3fe.png","sheet_x":51,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"26F9-1F3FF","non_qualified":null,"image":"26f9-1f3ff.png","sheet_x":51,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":false,"has_img_messenger":false}},"obsoleted_by":"26F9-FE0F-200D-2642-FE0F"},{"name":"TENT","unified":"26FA","non_qualified":null,"docomo":null,"au":"E5D0","softbank":"E122","google":"FE7FB","image":"26fa.png","sheet_x":51,"sheet_y":2,"short_name":"tent","short_names":["tent"],"text":null,"texts":null,"category":"Travel & Places","sort_order":47,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"FUEL PUMP","unified":"26FD","non_qualified":null,"docomo":"E66B","au":"E571","softbank":"E03A","google":"FE7F5","image":"26fd.png","sheet_x":51,"sheet_y":3,"short_name":"fuelpump","short_names":["fuelpump"],"text":null,"texts":null,"category":"Travel & Places","sort_order":99,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK SCISSORS","unified":"2702-FE0F","non_qualified":"2702","docomo":"E675","au":"E516","softbank":"E313","google":"FE53E","image":"2702-fe0f.png","sheet_x":51,"sheet_y":4,"short_name":"scissors","short_names":["scissors"],"text":null,"texts":null,"category":"Objects","sort_order":126,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE HEAVY CHECK MARK","unified":"2705","non_qualified":null,"docomo":null,"au":"E55E","softbank":null,"google":"FEB4A","image":"2705.png","sheet_x":51,"sheet_y":5,"short_name":"white_check_mark","short_names":["white_check_mark"],"text":null,"texts":null,"category":"Symbols","sort_order":107,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"AIRPLANE","unified":"2708-FE0F","non_qualified":"2708","docomo":"E662","au":"E4B3","softbank":"E01D","google":"FE7E9","image":"2708-fe0f.png","sheet_x":51,"sheet_y":6,"short_name":"airplane","short_names":["airplane"],"text":null,"texts":null,"category":"Travel & Places","sort_order":113,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ENVELOPE","unified":"2709-FE0F","non_qualified":"2709","docomo":"E6D3","au":"E521","softbank":null,"google":"FE529","image":"2709-fe0f.png","sheet_x":51,"sheet_y":7,"short_name":"email","short_names":["email","envelope"],"text":null,"texts":null,"category":"Objects","sort_order":87,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"RAISED FIST","unified":"270A","non_qualified":null,"docomo":"E693","au":"EB83","softbank":"E010","google":"FEB93","image":"270a.png","sheet_x":51,"sheet_y":8,"short_name":"fist","short_names":["fist"],"text":null,"texts":null,"category":"Smileys & People","sort_order":380,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"270A-1F3FB","non_qualified":null,"image":"270a-1f3fb.png","sheet_x":51,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"270A-1F3FC","non_qualified":null,"image":"270a-1f3fc.png","sheet_x":51,"sheet_y":10,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"270A-1F3FD","non_qualified":null,"image":"270a-1f3fd.png","sheet_x":51,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"270A-1F3FE","non_qualified":null,"image":"270a-1f3fe.png","sheet_x":51,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"270A-1F3FF","non_qualified":null,"image":"270a-1f3ff.png","sheet_x":51,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"RAISED HAND","unified":"270B","non_qualified":null,"docomo":"E695","au":"E5A7","softbank":"E012","google":"FEB95","image":"270b.png","sheet_x":51,"sheet_y":14,"short_name":"hand","short_names":["hand","raised_hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":376,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"270B-1F3FB","non_qualified":null,"image":"270b-1f3fb.png","sheet_x":51,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"270B-1F3FC","non_qualified":null,"image":"270b-1f3fc.png","sheet_x":51,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"270B-1F3FD","non_qualified":null,"image":"270b-1f3fd.png","sheet_x":51,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"270B-1F3FE","non_qualified":null,"image":"270b-1f3fe.png","sheet_x":51,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"270B-1F3FF","non_qualified":null,"image":"270b-1f3ff.png","sheet_x":51,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":"VICTORY HAND","unified":"270C-FE0F","non_qualified":"270C","docomo":"E694","au":"E5A6","softbank":"E011","google":"FEB94","image":"270c-fe0f.png","sheet_x":51,"sheet_y":20,"short_name":"v","short_names":["v"],"text":null,"texts":null,"category":"Smileys & People","sort_order":370,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true,"skin_variations":{"1F3FB":{"unified":"270C-1F3FB","non_qualified":null,"image":"270c-1f3fb.png","sheet_x":51,"sheet_y":21,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"270C-1F3FC","non_qualified":null,"image":"270c-1f3fc.png","sheet_x":51,"sheet_y":22,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"270C-1F3FD","non_qualified":null,"image":"270c-1f3fd.png","sheet_x":51,"sheet_y":23,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"270C-1F3FE","non_qualified":null,"image":"270c-1f3fe.png","sheet_x":51,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"270C-1F3FF","non_qualified":null,"image":"270c-1f3ff.png","sheet_x":51,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}}},{"name":null,"unified":"270D-FE0F","non_qualified":"270D","docomo":null,"au":null,"softbank":null,"google":null,"image":"270d-fe0f.png","sheet_x":51,"sheet_y":26,"short_name":"writing_hand","short_names":["writing_hand"],"text":null,"texts":null,"category":"Smileys & People","sort_order":387,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false,"skin_variations":{"1F3FB":{"unified":"270D-1F3FB","non_qualified":null,"image":"270d-1f3fb.png","sheet_x":51,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"270D-1F3FC","non_qualified":null,"image":"270d-1f3fc.png","sheet_x":51,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"270D-1F3FD","non_qualified":null,"image":"270d-1f3fd.png","sheet_x":51,"sheet_y":29,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"270D-1F3FE","non_qualified":null,"image":"270d-1f3fe.png","sheet_x":51,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"270D-1F3FF","non_qualified":null,"image":"270d-1f3ff.png","sheet_x":51,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false}}},{"name":"PENCIL","unified":"270F-FE0F","non_qualified":"270F","docomo":"E719","au":"E4A1","softbank":null,"google":"FE539","image":"270f-fe0f.png","sheet_x":51,"sheet_y":32,"short_name":"pencil2","short_names":["pencil2"],"text":null,"texts":null,"category":"Objects","sort_order":100,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK NIB","unified":"2712-FE0F","non_qualified":"2712","docomo":"E6AE","au":"EB03","softbank":null,"google":"FE536","image":"2712-fe0f.png","sheet_x":51,"sheet_y":33,"short_name":"black_nib","short_names":["black_nib"],"text":null,"texts":null,"category":"Objects","sort_order":101,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEAVY CHECK MARK","unified":"2714-FE0F","non_qualified":"2714","docomo":null,"au":"E557","softbank":null,"google":"FEB49","image":"2714-fe0f.png","sheet_x":51,"sheet_y":34,"short_name":"heavy_check_mark","short_names":["heavy_check_mark"],"text":null,"texts":null,"category":"Symbols","sort_order":109,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEAVY MULTIPLICATION X","unified":"2716-FE0F","non_qualified":"2716","docomo":null,"au":"E54F","softbank":null,"google":"FEB53","image":"2716-fe0f.png","sheet_x":51,"sheet_y":35,"short_name":"heavy_multiplication_x","short_names":["heavy_multiplication_x"],"text":null,"texts":null,"category":"Symbols","sort_order":110,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"271D-FE0F","non_qualified":"271D","docomo":null,"au":null,"softbank":null,"google":null,"image":"271d-fe0f.png","sheet_x":51,"sheet_y":36,"short_name":"latin_cross","short_names":["latin_cross"],"text":null,"texts":null,"category":"Symbols","sort_order":54,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":null,"unified":"2721-FE0F","non_qualified":"2721","docomo":null,"au":null,"softbank":null,"google":null,"image":"2721-fe0f.png","sheet_x":51,"sheet_y":37,"short_name":"star_of_david","short_names":["star_of_david"],"text":null,"texts":null,"category":"Symbols","sort_order":51,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"SPARKLES","unified":"2728","non_qualified":null,"docomo":"E6FA","au":"EAAB","softbank":"E32E","google":"FEB60","image":"2728.png","sheet_x":51,"sheet_y":38,"short_name":"sparkles","short_names":["sparkles"],"text":null,"texts":null,"category":"Activities","sort_order":6,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EIGHT SPOKED ASTERISK","unified":"2733-FE0F","non_qualified":"2733","docomo":"E6F8","au":"E53E","softbank":"E206","google":"FEB62","image":"2733-fe0f.png","sheet_x":51,"sheet_y":39,"short_name":"eight_spoked_asterisk","short_names":["eight_spoked_asterisk"],"text":null,"texts":null,"category":"Symbols","sort_order":119,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"EIGHT POINTED BLACK STAR","unified":"2734-FE0F","non_qualified":"2734","docomo":"E6F8","au":"E479","softbank":"E205","google":"FEB61","image":"2734-fe0f.png","sheet_x":51,"sheet_y":40,"short_name":"eight_pointed_black_star","short_names":["eight_pointed_black_star"],"text":null,"texts":null,"category":"Symbols","sort_order":120,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SNOWFLAKE","unified":"2744-FE0F","non_qualified":"2744","docomo":null,"au":"E48A","softbank":null,"google":"FE00E","image":"2744-fe0f.png","sheet_x":51,"sheet_y":41,"short_name":"snowflake","short_names":["snowflake"],"text":null,"texts":null,"category":"Travel & Places","sort_order":196,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"SPARKLE","unified":"2747-FE0F","non_qualified":"2747","docomo":"E6FA","au":"E46C","softbank":null,"google":"FEB77","image":"2747-fe0f.png","sheet_x":51,"sheet_y":42,"short_name":"sparkle","short_names":["sparkle"],"text":null,"texts":null,"category":"Symbols","sort_order":121,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CROSS MARK","unified":"274C","non_qualified":null,"docomo":null,"au":"E550","softbank":"E333","google":"FEB45","image":"274c.png","sheet_x":51,"sheet_y":43,"short_name":"x","short_names":["x"],"text":null,"texts":null,"category":"Symbols","sort_order":111,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"NEGATIVE SQUARED CROSS MARK","unified":"274E","non_qualified":null,"docomo":null,"au":"E551","softbank":null,"google":"FEB46","image":"274e.png","sheet_x":51,"sheet_y":44,"short_name":"negative_squared_cross_mark","short_names":["negative_squared_cross_mark"],"text":null,"texts":null,"category":"Symbols","sort_order":112,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK QUESTION MARK ORNAMENT","unified":"2753","non_qualified":null,"docomo":null,"au":"E483","softbank":"E020","google":"FEB09","image":"2753.png","sheet_x":51,"sheet_y":45,"short_name":"question","short_names":["question"],"text":null,"texts":null,"category":"Symbols","sort_order":124,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE QUESTION MARK ORNAMENT","unified":"2754","non_qualified":null,"docomo":null,"au":"E483","softbank":"E336","google":"FEB0A","image":"2754.png","sheet_x":51,"sheet_y":46,"short_name":"grey_question","short_names":["grey_question"],"text":null,"texts":null,"category":"Symbols","sort_order":125,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE EXCLAMATION MARK ORNAMENT","unified":"2755","non_qualified":null,"docomo":"E702","au":"E482","softbank":"E337","google":"FEB0B","image":"2755.png","sheet_x":51,"sheet_y":47,"short_name":"grey_exclamation","short_names":["grey_exclamation"],"text":null,"texts":null,"category":"Symbols","sort_order":126,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEAVY EXCLAMATION MARK SYMBOL","unified":"2757","non_qualified":null,"docomo":"E702","au":"E482","softbank":"E021","google":"FEB04","image":"2757.png","sheet_x":51,"sheet_y":48,"short_name":"exclamation","short_names":["exclamation","heavy_exclamation_mark"],"text":null,"texts":null,"category":"Symbols","sort_order":127,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":null,"unified":"2763-FE0F","non_qualified":"2763","docomo":null,"au":null,"softbank":null,"google":null,"image":"2763-fe0f.png","sheet_x":51,"sheet_y":49,"short_name":"heavy_heart_exclamation_mark_ornament","short_names":["heavy_heart_exclamation_mark_ornament"],"text":null,"texts":null,"category":"Smileys & People","sort_order":423,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":false},{"name":"HEAVY BLACK HEART","unified":"2764-FE0F","non_qualified":"2764","docomo":"E6EC","au":"E595","softbank":"E022","google":"FEB0C","image":"2764-fe0f.png","sheet_x":51,"sheet_y":50,"short_name":"heart","short_names":["heart"],"text":"<3","texts":["<3"],"category":"Smileys & People","sort_order":408,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEAVY PLUS SIGN","unified":"2795","non_qualified":null,"docomo":null,"au":"E53C","softbank":null,"google":"FEB51","image":"2795.png","sheet_x":51,"sheet_y":51,"short_name":"heavy_plus_sign","short_names":["heavy_plus_sign"],"text":null,"texts":null,"category":"Symbols","sort_order":113,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEAVY MINUS SIGN","unified":"2796","non_qualified":null,"docomo":null,"au":"E53D","softbank":null,"google":"FEB52","image":"2796.png","sheet_x":51,"sheet_y":52,"short_name":"heavy_minus_sign","short_names":["heavy_minus_sign"],"text":null,"texts":null,"category":"Symbols","sort_order":114,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEAVY DIVISION SIGN","unified":"2797","non_qualified":null,"docomo":null,"au":"E554","softbank":null,"google":"FEB54","image":"2797.png","sheet_x":52,"sheet_y":0,"short_name":"heavy_division_sign","short_names":["heavy_division_sign"],"text":null,"texts":null,"category":"Symbols","sort_order":115,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK RIGHTWARDS ARROW","unified":"27A1-FE0F","non_qualified":"27A1","docomo":null,"au":"E552","softbank":"E234","google":"FEAFA","image":"27a1-fe0f.png","sheet_x":52,"sheet_y":1,"short_name":"arrow_right","short_names":["arrow_right"],"text":null,"texts":null,"category":"Symbols","sort_order":29,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CURLY LOOP","unified":"27B0","non_qualified":null,"docomo":"E70A","au":"EB31","softbank":null,"google":"FEB08","image":"27b0.png","sheet_x":52,"sheet_y":2,"short_name":"curly_loop","short_names":["curly_loop"],"text":null,"texts":null,"category":"Symbols","sort_order":116,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DOUBLE CURLY LOOP","unified":"27BF","non_qualified":null,"docomo":"E6DF","au":null,"softbank":"E211","google":"FE82B","image":"27bf.png","sheet_x":52,"sheet_y":3,"short_name":"loop","short_names":["loop"],"text":null,"texts":null,"category":"Symbols","sort_order":117,"added_in":"6.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS","unified":"2934-FE0F","non_qualified":"2934","docomo":"E6F5","au":"EB2D","softbank":null,"google":"FEAF4","image":"2934-fe0f.png","sheet_x":52,"sheet_y":4,"short_name":"arrow_heading_up","short_names":["arrow_heading_up"],"text":null,"texts":null,"category":"Symbols","sort_order":39,"added_in":"3.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS","unified":"2935-FE0F","non_qualified":"2935","docomo":"E700","au":"EB2E","softbank":null,"google":"FEAF5","image":"2935-fe0f.png","sheet_x":52,"sheet_y":5,"short_name":"arrow_heading_down","short_names":["arrow_heading_down"],"text":null,"texts":null,"category":"Symbols","sort_order":40,"added_in":"3.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"LEFTWARDS BLACK ARROW","unified":"2B05-FE0F","non_qualified":"2B05","docomo":null,"au":"E553","softbank":"E235","google":"FEAFB","image":"2b05-fe0f.png","sheet_x":52,"sheet_y":6,"short_name":"arrow_left","short_names":["arrow_left"],"text":null,"texts":null,"category":"Symbols","sort_order":33,"added_in":"4.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"UPWARDS BLACK ARROW","unified":"2B06-FE0F","non_qualified":"2B06","docomo":null,"au":"E53F","softbank":"E232","google":"FEAF8","image":"2b06-fe0f.png","sheet_x":52,"sheet_y":7,"short_name":"arrow_up","short_names":["arrow_up"],"text":null,"texts":null,"category":"Symbols","sort_order":27,"added_in":"4.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"DOWNWARDS BLACK ARROW","unified":"2B07-FE0F","non_qualified":"2B07","docomo":null,"au":"E540","softbank":"E233","google":"FEAF9","image":"2b07-fe0f.png","sheet_x":52,"sheet_y":8,"short_name":"arrow_down","short_names":["arrow_down"],"text":null,"texts":null,"category":"Symbols","sort_order":31,"added_in":"4.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"BLACK LARGE SQUARE","unified":"2B1B","non_qualified":null,"docomo":null,"au":"E549","softbank":null,"google":"FEB6C","image":"2b1b.png","sheet_x":52,"sheet_y":9,"short_name":"black_large_square","short_names":["black_large_square"],"text":null,"texts":null,"category":"Symbols","sort_order":191,"added_in":"5.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE LARGE SQUARE","unified":"2B1C","non_qualified":null,"docomo":null,"au":"E548","softbank":null,"google":"FEB6B","image":"2b1c.png","sheet_x":52,"sheet_y":10,"short_name":"white_large_square","short_names":["white_large_square"],"text":null,"texts":null,"category":"Symbols","sort_order":192,"added_in":"5.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WHITE MEDIUM STAR","unified":"2B50","non_qualified":null,"docomo":null,"au":"E48B","softbank":"E32F","google":"FEB68","image":"2b50.png","sheet_x":52,"sheet_y":11,"short_name":"star","short_names":["star"],"text":null,"texts":null,"category":"Travel & Places","sort_order":174,"added_in":"5.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"HEAVY LARGE CIRCLE","unified":"2B55","non_qualified":null,"docomo":"E6A0","au":"EAAD","softbank":"E332","google":"FEB44","image":"2b55.png","sheet_x":52,"sheet_y":12,"short_name":"o","short_names":["o"],"text":null,"texts":null,"category":"Symbols","sort_order":106,"added_in":"5.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"WAVY DASH","unified":"3030-FE0F","non_qualified":"3030","docomo":"E709","au":null,"softbank":null,"google":"FEB07","image":"3030-fe0f.png","sheet_x":52,"sheet_y":13,"short_name":"wavy_dash","short_names":["wavy_dash"],"text":null,"texts":null,"category":"Symbols","sort_order":128,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"PART ALTERNATION MARK","unified":"303D-FE0F","non_qualified":"303D","docomo":null,"au":null,"softbank":"E12C","google":"FE81B","image":"303d-fe0f.png","sheet_x":52,"sheet_y":14,"short_name":"part_alternation_mark","short_names":["part_alternation_mark"],"text":null,"texts":null,"category":"Symbols","sort_order":118,"added_in":"3.2","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CIRCLED IDEOGRAPH CONGRATULATION","unified":"3297-FE0F","non_qualified":"3297","docomo":null,"au":"EA99","softbank":"E30D","google":"FEB43","image":"3297-fe0f.png","sheet_x":52,"sheet_y":15,"short_name":"congratulations","short_names":["congratulations"],"text":null,"texts":null,"category":"Symbols","sort_order":181,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true},{"name":"CIRCLED IDEOGRAPH SECRET","unified":"3299-FE0F","non_qualified":"3299","docomo":"E734","au":"E4F1","softbank":"E315","google":"FEB2B","image":"3299-fe0f.png","sheet_x":52,"sheet_y":16,"short_name":"secret","short_names":["secret"],"text":null,"texts":null,"category":"Symbols","sort_order":182,"added_in":"1.1","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_facebook":true,"has_img_messenger":true}]
\ No newline at end of file diff --git a/recipes-graphics/ttf-fonts/ttf-dejavu_%.bbappend b/recipes-graphics/ttf-fonts/ttf-dejavu_%.bbappend index bf79e949..86a5d90c 100644 --- a/recipes-graphics/ttf-fonts/ttf-dejavu_%.bbappend +++ b/recipes-graphics/ttf-fonts/ttf-dejavu_%.bbappend @@ -1,15 +1 @@ -FILESEXTRAPATHS_prepend := "${THISDIR}/files:" -DEPENDS += "fontforge-native" - -# From the orginal work located at https://aur.archlinux.org/packages/ttf-dejavu-emojiless/ - -SRC_URI_append = "\ - file://cleaner.py \ - file://emoji.json \ - " - -do_install_prepend() { - for TTF in ${S}/*.ttf; do - fontforge -script ${WORKDIR}/cleaner.py ${TTF} - done -} +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'ttf-dejavu_agldemo.inc', '', d)} diff --git a/recipes-graphics/ttf-fonts/ttf-dejavu_agldemo.inc b/recipes-graphics/ttf-fonts/ttf-dejavu_agldemo.inc new file mode 100644 index 00000000..08b6aa49 --- /dev/null +++ b/recipes-graphics/ttf-fonts/ttf-dejavu_agldemo.inc @@ -0,0 +1,12 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" +DEPENDS:append = " fontforge-native" + +# From the orginal work located at https://aur.archlinux.org/packages/ttf-dejavu-emojiless/ + +SRC_URI:append = " file://cleaner.py" + +do_install:prepend() { + for TTF in ${S}/*.ttf; do + fontforge -script ${WORKDIR}/cleaner.py ${TTF} + done +} diff --git a/recipes-graphics/ttf-fonts/ttf-noto-emoji_20190815.bb b/recipes-graphics/ttf-fonts/ttf-noto-emoji_20190815.bb deleted file mode 100644 index 38aaa4eb..00000000 --- a/recipes-graphics/ttf-fonts/ttf-noto-emoji_20190815.bb +++ /dev/null @@ -1,19 +0,0 @@ -require ../../../external/meta-openembedded/meta-oe/recipes-graphics/ttf-fonts/ttf.inc - -SUMMARY = "Google noto emoji font pack" -HOMEPAGE = "https://github.com/googlefonts/noto-emoji" -LICENSE = "OFL-1.1" -LIC_FILES_CHKSUM = "file://fonts/LICENSE;md5=55719faa0112708e946b820b24b14097" - -SRC_URI = "git://github.com/googlefonts/noto-emoji;protocol=https" -SRCREV = "833a43d03246a9325e748a2d783006454d76ff66" - -PACKAGES = "${PN}-color ${PN}-regular" -FONT_PACKAGES = "${PN}-color ${PN}-regular" - -S = "${WORKDIR}/git" - -FILES_${PN}-color = "${datadir}/fonts/truetype/NotoColorEmoji.ttf" -FILES_${PN}-regular = "${datadir}/fonts/truetype/NotoEmoji-Regular.ttf" - -do_compile[noexec] = "1" diff --git a/recipes-graphics/wayland/agl-compositor-init-agl-container-guest/agl-compositor-guest.conf b/recipes-graphics/wayland/agl-compositor-init-agl-container-guest/agl-compositor-guest.conf new file mode 100644 index 00000000..b98108ed --- /dev/null +++ b/recipes-graphics/wayland/agl-compositor-init-agl-container-guest/agl-compositor-guest.conf @@ -0,0 +1,14 @@ +# This is a system unit for launching AGL compositor in container guest. +# Need to drop tty dependency. +[Unit] +ConditionPathExists= + +[Service] +TTYPath= +TTYReset= +TTYVHangup= +TTYVTDisallocate= + +StandardInput=null + +UtmpIdentifier= diff --git a/recipes-graphics/wayland/agl-compositor-init-agl-container-guest/agl-compositor.env b/recipes-graphics/wayland/agl-compositor-init-agl-container-guest/agl-compositor.env new file mode 100644 index 00000000..d817effa --- /dev/null +++ b/recipes-graphics/wayland/agl-compositor-init-agl-container-guest/agl-compositor.env @@ -0,0 +1,2 @@ +DLM_RUNTIME_PATH=/var/display/drm-lease-manager +DRM_LEASE_DEVICE=lease diff --git a/recipes-graphics/wayland/agl-compositor-init.bbappend b/recipes-graphics/wayland/agl-compositor-init.bbappend new file mode 100644 index 00000000..e7829562 --- /dev/null +++ b/recipes-graphics/wayland/agl-compositor-init.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agl-container-guest-demo', 'agl-compositor-init_agl-container-guest-demo.inc', '', d)} diff --git a/recipes-graphics/wayland/agl-compositor-init_agl-container-guest-demo.inc b/recipes-graphics/wayland/agl-compositor-init_agl-container-guest-demo.inc new file mode 100644 index 00000000..fe9bd098 --- /dev/null +++ b/recipes-graphics/wayland/agl-compositor-init_agl-container-guest-demo.inc @@ -0,0 +1,17 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/agl-compositor-init-agl-container-guest:" + +SRC_URI:append = " \ + file://agl-compositor.env \ + file://agl-compositor-guest.conf \ + " + +DRM_LEASE_DEVICE = "lease" + +do_install:append() { + install -Dm644 ${WORKDIR}/agl-compositor.env ${D}${sysconfdir}/default/agl-compositor + install -m644 ${WORKDIR}/agl-compositor-guest.conf ${D}/${systemd_system_unitdir}/agl-compositor.service.d/agl-compositor-guest.conf +} + +FILES:${PN} += "\ + ${sysconfdir}/default/agl-compositor \ + " diff --git a/recipes-graphics/wayland/agl-compositor_%.bbappend b/recipes-graphics/wayland/agl-compositor_%.bbappend new file mode 100644 index 00000000..504e1884 --- /dev/null +++ b/recipes-graphics/wayland/agl-compositor_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'agl-compositor_agldemo.inc', '', d)} diff --git a/recipes-graphics/wayland/agl-compositor_agldemo.inc b/recipes-graphics/wayland/agl-compositor_agldemo.inc new file mode 100644 index 00000000..5ea1a2dc --- /dev/null +++ b/recipes-graphics/wayland/agl-compositor_agldemo.inc @@ -0,0 +1,2 @@ +# enable grpc-proxy +PACKAGECONFIG += "grpc-proxy" diff --git a/recipes-graphics/wayland/weston-agl-driver-conf.bb b/recipes-graphics/wayland/weston-agl-driver-conf.bb new file mode 100644 index 00000000..763103d4 --- /dev/null +++ b/recipes-graphics/wayland/weston-agl-driver-conf.bb @@ -0,0 +1,22 @@ +SUMMARY = "Weston systemd configuration to run as agl-driver user" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd allarch features_check + +REQUIRED_DISTRO_FEATURES = "wayland systemd" + +SRC_URI = "file://weston-agl-driver.conf" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + # Install override drop-in + install -d ${D}${systemd_system_unitdir}/weston.service.d + install -m 0644 ${WORKDIR}/weston-agl-driver.conf ${D}${systemd_system_unitdir}/weston.service.d/ +} + +FILES:${PN} += "${systemd_system_unitdir}" + +RDEPENDS:${PN} += "weston agl-users" diff --git a/recipes-graphics/wayland/weston-agl-driver-conf/weston-agl-driver.conf b/recipes-graphics/wayland/weston-agl-driver-conf/weston-agl-driver.conf new file mode 100644 index 00000000..75ab576a --- /dev/null +++ b/recipes-graphics/wayland/weston-agl-driver-conf/weston-agl-driver.conf @@ -0,0 +1,5 @@ +[Service] +User= +User=agl-driver +Group= +Group=agl-driver diff --git a/recipes-graphics/wayland/weston-ini-conf.bbappend b/recipes-graphics/wayland/weston-ini-conf.bbappend new file mode 100644 index 00000000..423a4694 --- /dev/null +++ b/recipes-graphics/wayland/weston-ini-conf.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'weston-ini-conf_agldemo.inc', '', d)} diff --git a/recipes-graphics/wayland/weston-ini-conf/weston.ini.kvm.in b/recipes-graphics/wayland/weston-ini-conf/weston.ini.kvm.in new file mode 100644 index 00000000..79ca30cd --- /dev/null +++ b/recipes-graphics/wayland/weston-ini-conf/weston.ini.kvm.in @@ -0,0 +1,18 @@ +[core] +backend=drm-backend.so +require-input=false +modules=systemd-notify.so + +[shell] +locking=true +panel-position=none + +# A display is connected to HDMI-A-1 +[output] +name=HDMI-A-1 +agl-shell-app-id=@GUEST_VM1_IMAGE@ + +# A display is connected to HDMI-A-2 +[output] +name=HDMI-A-2 +agl-shell-app-id=@GUEST_VM2_IMAGE@ diff --git a/recipes-graphics/wayland/weston-ini-conf_agldemo.inc b/recipes-graphics/wayland/weston-ini-conf_agldemo.inc new file mode 100644 index 00000000..6d6a0a8d --- /dev/null +++ b/recipes-graphics/wayland/weston-ini-conf_agldemo.inc @@ -0,0 +1,28 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/weston-ini-conf:" + +SRC_URI += "file://weston.ini.kvm.in" + +GUEST_VM1_IMAGE ?= "agl-ivi-demo-platform-flutter" +GUEST_VM2_IMAGE ?= "agl-cluster-demo-platform-flutter" + +do_compile:append() { + # Start with a canned configuration for a KVM host, filling in + # the guest VM application ids to pin them to specific outputs. + rm -f ${WORKDIR}/weston.ini.kvm + sed -e "s/@GUEST_VM1_IMAGE@/${GUEST_VM1_IMAGE}/g" \ + -e "s/@GUEST_VM2_IMAGE@/${GUEST_VM2_IMAGE}/g" \ + ${WORKDIR}/weston.ini.kvm.in > ${WORKDIR}/weston.ini.kvm +} + +do_install:append() { + install -m 0644 ${WORKDIR}/weston.ini.kvm ${D}${weston_ini_dir}/ +} + +PACKAGE_BEFORE_PN += "${PN}-kvm" + +FILES:${PN}-kvm = "${weston_ini_dir}/weston.ini.kvm" + +RPROVIDES:${PN}-kvm = "weston-ini" +RCONFLICTS:${PN}-kvm = "${PN}" +ALTERNATIVE:${PN}-kvm = "weston.ini" +ALTERNATIVE_TARGET_${PN}-kvm = "${weston_ini_dir}/weston.ini.kvm" diff --git a/recipes-graphics/wayland/weston-terminal-conf.bb b/recipes-graphics/wayland/weston-terminal-conf.bb new file mode 100644 index 00000000..390edc8a --- /dev/null +++ b/recipes-graphics/wayland/weston-terminal-conf.bb @@ -0,0 +1,21 @@ +SUMMARY = "AGL user session" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit allarch agl-app + +AGL_APP_ID = "org.freedesktop.weston.wayland-terminal" +AGL_APP_EXEC = "weston-terminal" +AGL_APP_NAME = "Weston Terminal" + +do_install() { + # Enable systemd sandboxing override as a demonstration + install -d ${D}${systemd_system_unitdir}/agl-app@${AGL_APP_ID}.service.d/ + ln -sf ${systemd_system_unitdir}/sandboxing/no-network.conf ${D}${systemd_system_unitdir}/agl-app@${AGL_APP_ID}.service.d/ +} + +FILES:${PN} = " \ + ${sysconfdir}/systemd/system/agl-app@${AGL_APP_ID}.service.d \ +" + +RDEPENDS:${PN} = "weston-terminal" diff --git a/recipes-graphics/web-runtime/web-runtime/web-runtime b/recipes-graphics/web-runtime/web-runtime/web-runtime deleted file mode 100755 index 39f3781b..00000000 --- a/recipes-graphics/web-runtime/web-runtime/web-runtime +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -export -n QT_WAYLAND_SHELL_INTEGRATION -port=$(echo -n "$1" | sed 's,.*local.*:\([^/]*\)/.*,\1,') -token=$(echo -n "$1" | sed 's,.*token=,,') -export AFM_APP_INSTALL_DIR=$(mktemp -d) -cat << EOC > $AFM_APP_INSTALL_DIR/runxdg.toml -[application] -role = "WebBrowser" -method = "POSIX" -path = "/usr/bin/qt5/qmlscene" -params = [ - "$1", - "/usr/bin/web-runtime.qml" -] -EOC -export LD_PRELOAD=/usr/lib/libEGL.so -/usr/bin/runxdg "$port" "$token" -rm -rf $AFM_APP_INSTALL_DIR diff --git a/recipes-graphics/web-runtime/web-runtime/web-runtime-webkit.qml b/recipes-graphics/web-runtime/web-runtime/web-runtime-webkit.qml deleted file mode 100644 index 8025ab12..00000000 --- a/recipes-graphics/web-runtime/web-runtime/web-runtime-webkit.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtWebKit 3.0 - -ApplicationWindow { - width: 1080 - height: 1488 - visible: true - WebView { - url: Qt.application.arguments[1] - anchors.fill: parent - } -} diff --git a/recipes-graphics/web-runtime/web-runtime/web-runtime.qml b/recipes-graphics/web-runtime/web-runtime/web-runtime.qml deleted file mode 100644 index 3efe5159..00000000 --- a/recipes-graphics/web-runtime/web-runtime/web-runtime.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtWebEngine 1.1 - -ApplicationWindow { - width: 1080 - height: 1488 - visible: true - flags: Qt.WindowFullScreen | Qt.FramelessWindowHint - WebEngineView { - url: Qt.application.arguments[1] - anchors.fill: parent - } -} diff --git a/recipes-graphics/web-runtime/web-runtime_0.1.bb b/recipes-graphics/web-runtime/web-runtime_0.1.bb deleted file mode 100644 index ea5acbbf..00000000 --- a/recipes-graphics/web-runtime/web-runtime_0.1.bb +++ /dev/null @@ -1,37 +0,0 @@ -inherit allarch - -SUMMARY = "Provides the 'web-runtime' command" -DESCRIPTION = "The command 'web-runtime' is an abstraction that allows to " - -LICENSE = "MIT" -LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" - -SRC_URI = "\ - file://web-runtime;md5sum=2245be1e6029b30966f0842e3fee75ea \ - file://web-runtime.qml;md5sum=922aeae6d596d7c83af01abca266f0df \ - file://web-runtime-webkit.qml;md5sum=4daf9df39078634c27a7923d37e82e3d \ -" - -RDEPENDS_${PN} = "\ - qtdeclarative-tools \ - qtwayland-qmlplugins \ - qtquickcontrols-qmlplugins \ - qtwebengine \ - runxdg \ - bash \ -" - -PROVIDES += "virtual/webruntime" -# add also RPROVIDES to satisfy the packagegroup -RPROVIDES_${PN} += "virtual/webruntime" - -do_configure() { - : -} - -do_install() { - install -d ${D}${bindir} - install -m 0755 ${WORKDIR}/web-runtime ${D}${bindir}/web-runtime - install -m 0644 ${WORKDIR}/web-runtime.qml ${D}${bindir}/web-runtime.qml - install -m 0644 ${WORKDIR}/web-runtime-webkit.qml ${D}${bindir}/web-runtime-webkit.qml -} diff --git a/recipes-kernel/linux/linux-%.bbappend b/recipes-kernel/linux/linux-%.bbappend new file mode 100644 index 00000000..e6b19c21 --- /dev/null +++ b/recipes-kernel/linux/linux-%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'linux_agldemo.inc', '', d) if bb.data.inherits_class('kernel', d) else ''} diff --git a/recipes-kernel/linux/linux/btusb.cfg b/recipes-kernel/linux/linux/btusb.cfg new file mode 100644 index 00000000..0986578e --- /dev/null +++ b/recipes-kernel/linux/linux/btusb.cfg @@ -0,0 +1,35 @@ +CONFIG_BT=m +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_HS=y +CONFIG_BT_LE=y +CONFIG_BT_LEDS=y +# CONFIG_BT_SELFTEST is not set +CONFIG_BT_DEBUGFS=y + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m +CONFIG_BT_RTL=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CMAC=m + +# +# Bluetooth AVRCP support +# +CONFIG_INPUT_UINPUT=y diff --git a/recipes-kernel/linux/linux/can-devices.cfg b/recipes-kernel/linux/linux/can-devices.cfg new file mode 100644 index 00000000..77a8bffa --- /dev/null +++ b/recipes-kernel/linux/linux/can-devices.cfg @@ -0,0 +1,29 @@ +# +# CAN Device Drivers +# +CONFIG_CAN_SLCAN=m +CONFIG_CAN_DEV=m +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m +# CONFIG_CAN_SJA1000 is not set +# CONFIG_CAN_M_CAN is not set +# CONFIG_CAN_CC770 is not set + +# +# CAN SPI interfaces +# +CONFIG_CAN_MCP251X=m + +# +# CAN USB interfaces +# +# CONFIG_CAN_EMS_USB is not set +CONFIG_CAN_ESD_USB=m +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_MCBA_USB=m +# CONFIG_CAN_SOFTING is not set +# CONFIG_CAN_DEBUG_DEVICES is not set diff --git a/recipes-kernel/linux/linux/disable_most.cfg b/recipes-kernel/linux/linux/disable_most.cfg new file mode 100644 index 00000000..db207dfc --- /dev/null +++ b/recipes-kernel/linux/linux/disable_most.cfg @@ -0,0 +1 @@ +# CONFIG_MOST is not set diff --git a/recipes-kernel/linux/linux/hid.cfg b/recipes-kernel/linux/linux/hid.cfg new file mode 100644 index 00000000..327c753a --- /dev/null +++ b/recipes-kernel/linux/linux/hid.cfg @@ -0,0 +1 @@ +CONFIG_HID_MULTITOUCH=y diff --git a/recipes-kernel/linux/linux/i2c-led.cfg b/recipes-kernel/linux/linux/i2c-led.cfg new file mode 100644 index 00000000..248b5118 --- /dev/null +++ b/recipes-kernel/linux/linux/i2c-led.cfg @@ -0,0 +1,3 @@ +# enabling I2C and LED for demonstrator +CONFIG_I2C_TINY_USB=y +CONFIG_LEDS_BLINKM=y diff --git a/recipes-kernel/linux/linux/iiodevice.cfg b/recipes-kernel/linux/linux/iiodevice.cfg new file mode 100644 index 00000000..c5b8ff35 --- /dev/null +++ b/recipes-kernel/linux/linux/iiodevice.cfg @@ -0,0 +1,26 @@ +# +# Extcon Device Drivers +# +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_BUFFER_CB=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_CONFIGFS=m +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 +CONFIG_IIO_SW_DEVICE=m +CONFIG_IIO_SW_TRIGGER=m + +# +# IIO dummy driver +# +CONFIG_IIO_DUMMY_EVGEN=m +CONFIG_IIO_SIMPLE_DUMMY=m +CONFIG_IIO_SIMPLE_DUMMY_EVENTS=y +CONFIG_IIO_SIMPLE_DUMMY_BUFFER=y + +# +# Triggers - standalone +# +CONFIG_IIO_HRTIMER_TRIGGER=m +CONFIG_IIO_TRIGGERED_BUFFER=m diff --git a/recipes-kernel/linux/linux/joystick.cfg b/recipes-kernel/linux/linux/joystick.cfg new file mode 100644 index 00000000..2201bcb0 --- /dev/null +++ b/recipes-kernel/linux/linux/joystick.cfg @@ -0,0 +1,9 @@ +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ADI=y +CONFIG_GAMEPORT=y +CONFIG_HID_LOGITECH=y +CONFIG_LOGIWHEELS_FF=y +CONFIG_HID_LOGITECH_HIDPP=y +CONFIG_LOGITECH_FF=y +CONFIG_LOGIG940_FF=y diff --git a/recipes-kernel/linux/linux/kvm-demo-can-devices.cfg b/recipes-kernel/linux/linux/kvm-demo-can-devices.cfg new file mode 100644 index 00000000..17cb166a --- /dev/null +++ b/recipes-kernel/linux/linux/kvm-demo-can-devices.cfg @@ -0,0 +1,5 @@ +CONFIG_CAN_DEV=m +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_SJA1000=y +CONFIG_PCI=y +CONFIG_CAN_KVASER_PCI=m diff --git a/recipes-kernel/linux/linux/kvm-demo-usb.cfg b/recipes-kernel/linux/linux/kvm-demo-usb.cfg new file mode 100644 index 00000000..2fa56a1b --- /dev/null +++ b/recipes-kernel/linux/linux/kvm-demo-usb.cfg @@ -0,0 +1,4 @@ +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_PCI=y diff --git a/recipes-kernel/linux/linux/most_deps.cfg b/recipes-kernel/linux/linux/most_deps.cfg new file mode 100644 index 00000000..53964a59 --- /dev/null +++ b/recipes-kernel/linux/linux/most_deps.cfg @@ -0,0 +1,8 @@ +CONFIG_I2C=y +CONFIG_USB=y +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_SUBDEV_API=y diff --git a/recipes-kernel/linux/linux/nfc.cfg b/recipes-kernel/linux/linux/nfc.cfg new file mode 100644 index 00000000..6d863a07 --- /dev/null +++ b/recipes-kernel/linux/linux/nfc.cfg @@ -0,0 +1,34 @@ +CONFIG_NFC=m +CONFIG_NFC_DIGITAL=m +CONFIG_NFC_NCI=m +CONFIG_NFC_NCI_SPI=m +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y +CONFIG_NFC_TRF7970A=m +CONFIG_NFC_MEI_PHY=m +CONFIG_NFC_PORT100=m +CONFIG_NFC_FDP=m +CONFIG_NFC_FDP_I2C=m +CONFIG_NFC_PN544=m +CONFIG_NFC_PN544_I2C=m +CONFIG_NFC_PN544_MEI=m +CONFIG_NFC_PN533=m +CONFIG_NFC_PN533_USB=m +CONFIG_NFC_PN533_I2C=m +CONFIG_NFC_MICROREAD=m +CONFIG_NFC_MICROREAD_I2C=m +CONFIG_NFC_MICROREAD_MEI=m +CONFIG_NFC_MRVL=m +CONFIG_NFC_MRVL_USB=m +CONFIG_NFC_MRVL_I2C=m +CONFIG_NFC_MRVL_SPI=m +CONFIG_NFC_ST21NFCA=m +CONFIG_NFC_ST21NFCA_I2C=m +CONFIG_NFC_ST_NCI=m +CONFIG_NFC_ST_NCI_I2C=m +CONFIG_NFC_ST_NCI_SPI=m +CONFIG_NFC_NXP_NCI=m +CONFIG_NFC_NXP_NCI_I2C=m +CONFIG_NFC_S3FWRN5=m +CONFIG_NFC_S3FWRN5_I2C=m +CONFIG_NFC_ST95HF=m diff --git a/recipes-kernel/linux/linux/rtc.cfg b/recipes-kernel/linux/linux/rtc.cfg new file mode 100644 index 00000000..2641958a --- /dev/null +++ b/recipes-kernel/linux/linux/rtc.cfg @@ -0,0 +1,7 @@ +CONFIG_RTC_CLASS=y +CONFIG_RTC_LIB=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS3232=m diff --git a/recipes-kernel/linux/linux/rtl_sdr.cfg b/recipes-kernel/linux/linux/rtl_sdr.cfg new file mode 100644 index 00000000..d4574700 --- /dev/null +++ b/recipes-kernel/linux/linux/rtl_sdr.cfg @@ -0,0 +1,4 @@ +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_RTL28XXU=m diff --git a/recipes-kernel/linux/linux/usb.cfg b/recipes-kernel/linux/linux/usb.cfg new file mode 100644 index 00000000..68955086 --- /dev/null +++ b/recipes-kernel/linux/linux/usb.cfg @@ -0,0 +1,9 @@ +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_ACM=m +CONFIG_CRC_CCITT=y +CONFIG_USB_SERIAL_CP210X=y +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_PCI=y diff --git a/recipes-kernel/linux/linux/usbaudio.cfg b/recipes-kernel/linux/linux/usbaudio.cfg new file mode 100644 index 00000000..5961f43d --- /dev/null +++ b/recipes-kernel/linux/linux/usbaudio.cfg @@ -0,0 +1,2 @@ +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=y diff --git a/recipes-kernel/linux/linux/usbmodem.cfg b/recipes-kernel/linux/linux/usbmodem.cfg new file mode 100644 index 00000000..3ded931e --- /dev/null +++ b/recipes-kernel/linux/linux/usbmodem.cfg @@ -0,0 +1,7 @@ +CONFIG_USB_USBNET=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_QUALCOMM=m diff --git a/recipes-kernel/linux/linux/uvc.cfg b/recipes-kernel/linux/linux/uvc.cfg new file mode 100644 index 00000000..7c6556c1 --- /dev/null +++ b/recipes-kernel/linux/linux/uvc.cfg @@ -0,0 +1,4 @@ +CONFIG_VIDEOBUF2_VMALLOC=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y diff --git a/recipes-kernel/linux/linux/wifi.cfg b/recipes-kernel/linux/linux/wifi.cfg new file mode 100644 index 00000000..e289062c --- /dev/null +++ b/recipes-kernel/linux/linux/wifi.cfg @@ -0,0 +1,5 @@ +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_WLAN_VENDOR_ATH=y +CONFIG_ATH9K_HTC=m +CONFIG_RTL8XXXU=m diff --git a/recipes-kernel/linux/linux_agldemo.inc b/recipes-kernel/linux/linux_agldemo.inc new file mode 100644 index 00000000..1126c767 --- /dev/null +++ b/recipes-kernel/linux/linux_agldemo.inc @@ -0,0 +1,49 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/linux:" + +# Enable assorted USB device support for demo systems +AGL_KCONFIG_FRAGMENTS_DEMO += " \ + usb.cfg \ + uvc.cfg \ + hid.cfg \ + joystick.cfg \ + usbaudio.cfg \ + usbmodem.cfg \ + btusb.cfg \ + i2c-led.cfg \ +" + +# Enable CAN device support +AGL_KCONFIG_FRAGMENTS_DEMO += "can-devices.cfg" + +# Enable NFC support +AGL_KCONFIG_FRAGMENTS_DEMO += "nfc.cfg" + +# Enable support for TP-Link TL-W722N USB Wifi adapter (rev 1 and 2) +AGL_KCONFIG_FRAGMENTS_DEMO += "wifi.cfg" + +# Enable support for RTLSDR +AGL_KCONFIG_FRAGMENTS_DEMO += "rtl_sdr.cfg" + +# iio-dummy-device support for test IIO device +AGL_KCONFIG_FRAGMENTS_DEMO += "iiodevice.cfg" + +# External rtc support via e.g. http://wiki.seeedstudio.com/Grove-RTC/ +AGL_KCONFIG_FRAGMENTS_DEMO += "rtc.cfg" + +# Make sure in-kernel MOST drivers are disabled to avoid conflicting +# with our externally built ones +AGL_KCONFIG_FRAGMENTS_DEMO += "disable_most.cfg" + +# Enable some things on qemuarm64 so MOST drivers will build and load. +AGL_KCONFIG_FRAGMENTS_DEMO:append:qemuarm64 = " most_deps.cfg" + +# We don't want most of the above for the virtio guest kernels, +# use an explicit list +AGL_KCONFIG_FRAGMENTS_DEMO:virtio-all = " \ + kvm-demo-can-devices.cfg \ + kvm-demo-usb.cfg \ + usbaudio.cfg \ + hid.cfg \ +" + +AGL_KCONFIG_FRAGMENTS += "${AGL_KCONFIG_FRAGMENTS_DEMO}"
\ No newline at end of file diff --git a/recipes-kernel/sllin/files/0001-Disable-sllin-driver-debug-log.patch b/recipes-kernel/sllin/files/0001-Disable-sllin-driver-debug-log.patch deleted file mode 100644 index 99d6183a..00000000 --- a/recipes-kernel/sllin/files/0001-Disable-sllin-driver-debug-log.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 04ffb4b8f828c19e914987e271aaf3aa7eab28bf Mon Sep 17 00:00:00 2001 -From: Yuichi Kusakabe <yuichi.kusakabe@denso-ten.com> -Date: Thu, 29 Nov 2018 22:12:00 +0900 -Subject: [PATCH] Disable sllin driver debug log - -Signed-off-by: Yuichi Kusakabe <yuichi.kusakabe@denso-ten.com> ---- - sllin/sllin.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/sllin/sllin.c b/sllin/sllin.c -index 77b2cb8..133d6e9 100644 ---- a/sllin/sllin.c -+++ b/sllin/sllin.c -@@ -41,7 +41,9 @@ - * Funded by: Volkswagen Group Research - */ - -+#if 0 - #define DEBUG 1 /* Enables pr_debug() printouts */ -+#endif - - #include <linux/module.h> - #include <linux/moduleparam.h> --- -2.7.4 - diff --git a/recipes-kernel/sllin/files/0002_fix_null_operation_check.patch b/recipes-kernel/sllin/files/0002_fix_null_operation_check.patch deleted file mode 100644 index 896e2680..00000000 --- a/recipes-kernel/sllin/files/0002_fix_null_operation_check.patch +++ /dev/null @@ -1,176 +0,0 @@ -diff --git a/sllin/sllin.c b/sllin/sllin.c -index 2db896f..2969448 100644 ---- a/sllin/sllin.c -+++ b/sllin/sllin.c -@@ -869,7 +869,6 @@ static int sllin_send_tx_buff(struct sllin *sl) - #else - remains = sl->tx_lim - sl->tx_cnt; - #endif -- - res = tty->ops->write(tty, sl->tx_buff + sl->tx_cnt, remains); - if (res < 0) - goto error_in_write; -@@ -916,10 +915,25 @@ static int sllin_send_break(struct sllin *sl) - unsigned long break_baud; - int res; - -+ netdev_dbg(sl->dev, "%s()#<BREAK_BY_BAUD> invoke.\n", __func__); -+ if (tty == NULL) { -+ netdev_dbg(sl->dev, "%s() tty == NULL.\n", __func__); -+ sl->lin_state = SLSTATE_IDLE; -+ return -1; -+ } -+ if (tty->ops == NULL) { -+ netdev_dbg(sl->dev, "%s() tty->ops == NULL.\n", __func__); -+ sl->lin_state = SLSTATE_IDLE; -+ return -1; -+ } - break_baud = ((sl->lin_baud * 2) / 3); - sltty_change_speed(tty, break_baud); - -- tty->ops->flush_buffer(tty); -+ if (tty->ops->flush_buffer) { -+ tty->ops->flush_buffer(tty); -+ } else { -+ netdev_dbg(sl->dev, "%s() tty->ops->flush_buffer is NULL.\n", __func__); -+ } - sl->rx_cnt = SLLIN_BUFF_BREAK; - - sl->rx_expect = SLLIN_BUFF_BREAK + 1; -@@ -943,6 +957,17 @@ static int sllin_send_break(struct sllin *sl) - unsigned long usleep_range_min; - unsigned long usleep_range_max; - -+ netdev_dbg(sl->dev, "%s() invoke.\n", __func__); -+ if (tty == NULL) { -+ netdev_dbg(sl->dev, "%s() tty == NULL.\n", __func__); -+ sl->lin_state = SLSTATE_IDLE; -+ return -1; -+ } -+ if (tty->ops == NULL) { -+ netdev_dbg(sl->dev, "%s() tty->ops == NULL.\n", __func__); -+ sl->lin_state = SLSTATE_IDLE; -+ return -1; -+ } - break_baud = ((sl->lin_baud * 2) / 3); - sl->rx_cnt = SLLIN_BUFF_BREAK; - sl->rx_expect = SLLIN_BUFF_BREAK + 1; -@@ -950,21 +975,31 @@ static int sllin_send_break(struct sllin *sl) - - /* Do the break ourselves; Inspired by - http://lxr.linux.no/#linux+v3.1.2/drivers/tty/tty_io.c#L2452 */ -- retval = tty->ops->break_ctl(tty, -1); -- if (retval) -- return retval; -+ if (tty->ops->break_ctl) { -+ retval = tty->ops->break_ctl(tty, -1); -+ if (retval) -+ return retval; -+ } else { -+ netdev_dbg(sl->dev, "%s() tty->ops->break_ctl is NULL.\n", __func__); -+ } - - /* udelay(712); */ - usleep_range_min = (1000000l * SLLIN_SAMPLES_PER_CHAR) / break_baud; - usleep_range_max = usleep_range_min + 50; - usleep_range(usleep_range_min, usleep_range_max); - -- retval = tty->ops->break_ctl(tty, 0); -+ if(tty->ops->break_ctl) { -+ retval = tty->ops->break_ctl(tty, 0); -+ } - usleep_range_min = (1000000l * 1 /* 1 bit */) / break_baud; - usleep_range_max = usleep_range_min + 30; - usleep_range(usleep_range_min, usleep_range_max); - -- tty->ops->flush_buffer(tty); -+ if ( tty->ops->flush_buffer) { -+ tty->ops->flush_buffer(tty); -+ } else { -+ netdev_dbg(sl->dev, "%s() tty->ops->flush_buffer is NULL.\n", __func__); -+ } - - sl->tx_cnt = SLLIN_BUFF_SYNC; - -@@ -1028,6 +1063,12 @@ static int sllin_kwthread(void *ptr) - int lin_dlc; - u8 lin_data_buff[SLLIN_DATA_MAX]; - -+ if (sl == NULL) { -+ pr_err("sllin: sl is NULL\n"); -+ } -+ if (sl->dev == NULL) { -+ pr_err("sllin: sl->dev is NULL\n"); -+ } - - if ((sl->lin_state == SLSTATE_IDLE) && sl->lin_master && - sl->id_to_send) { -@@ -1036,6 +1077,7 @@ static int sllin_kwthread(void *ptr) - } - } - -+ netdev_dbg(sl->dev, "sllin_kthread <WAIT_EVENT>\n"); - wait_event_killable(sl->kwt_wq, kthread_should_stop() || - test_bit(SLF_RXEVENT, &sl->flags) || - test_bit(SLF_TXEVENT, &sl->flags) || -@@ -1046,6 +1088,7 @@ static int sllin_kwthread(void *ptr) - (sl->lin_state == SLSTATE_RESPONSE_WAIT)) - && test_bit(SLF_MSGEVENT, &sl->flags))); - -+ netdev_dbg(sl->dev, "sllin_kthread <WAKEUPED>\n"); - if (test_and_clear_bit(SLF_RXEVENT, &sl->flags)) { - netdev_dbg(sl->dev, "sllin_kthread RXEVENT\n"); - } -@@ -1078,21 +1121,25 @@ static int sllin_kwthread(void *ptr) - sl->lin_state = SLSTATE_IDLE; - } - -+ netdev_dbg(sl->dev, "sllin_kthread: lin_state <%08x>\n",sl->lin_state); - switch (sl->lin_state) { - case SLSTATE_IDLE: - if (!test_bit(SLF_MSGEVENT, &sl->flags)) - break; -- -+ if (sl->tx_req_skb == NULL) -+ netdev_dbg(sl->dev, "sl->tx_req_skb == NULL\n"); -+ if (sl->tx_req_skb->data == NULL) -+ netdev_dbg(sl->dev, "sl->tx_req_skb->data == NULL\n"); - cf = (struct can_frame *)sl->tx_req_skb->data; - - /* SFF RTR CAN frame -> LIN header */ - if (cf->can_id & CAN_RTR_FLAG) { - struct sllin_conf_entry *sce; - -- netdev_dbg(sl->dev, "%s: RTR SFF CAN frame, ID = %x\n", -- __func__, cf->can_id & LIN_ID_MASK); - - sce = &sl->linfr_cache[cf->can_id & LIN_ID_MASK]; -+ netdev_dbg(sl->dev, "%s: RTR SFF CAN frame, ID = %x dlc=%d\n", -+ __func__, cf->can_id & LIN_ID_MASK, sce->dlc); - spin_lock_irqsave(&sl->linfr_lock, flags); - - /* Is there Slave response in linfr_cache to be sent? */ -@@ -1114,8 +1161,8 @@ static int sllin_kwthread(void *ptr) - spin_unlock_irqrestore(&sl->linfr_lock, flags); - - } else { /* SFF NON-RTR CAN frame -> LIN header + LIN response */ -- netdev_dbg(sl->dev, "%s: NON-RTR SFF CAN frame, ID = %x\n", -- __func__, (int)cf->can_id & LIN_ID_MASK); -+ netdev_dbg(sl->dev, "%s: NON-RTR SFF CAN frame, ID = %x\n dlc=%d", -+ __func__, (int)cf->can_id & LIN_ID_MASK, cf->can_dlc); - - lin_data = cf->data; - lin_dlc = cf->can_dlc; -@@ -1140,6 +1187,7 @@ static int sllin_kwthread(void *ptr) - hrtimer_start(&sl->rx_timer, - ktime_add(ktime_get(), sl->rx_timer_timeout), - HRTIMER_MODE_ABS); -+ netdev_dbg(sl->dev, "sllin_kthread: SLSTATE finish\n"); - break; - - case SLSTATE_BREAK_SENT: -@@ -1654,3 +1702,4 @@ static void __exit sllin_exit(void) - - module_init(sllin_init); - module_exit(sllin_exit); -+ diff --git a/recipes-kernel/sllin/files/0003-Allow-recent-kernels-newer-4.11.x-to-build.patch b/recipes-kernel/sllin/files/0003-Allow-recent-kernels-newer-4.11.x-to-build.patch deleted file mode 100644 index c8f2f926..00000000 --- a/recipes-kernel/sllin/files/0003-Allow-recent-kernels-newer-4.11.x-to-build.patch +++ /dev/null @@ -1,69 +0,0 @@ -From fcebb8f510bbb5c681f1f9af4506b4de241837dd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jan-Simon=20M=C3=B6ller?= <jsmoeller@linuxfoundation.org> -Date: Wed, 31 Oct 2018 20:48:20 +0000 -Subject: [PATCH] Allow recent kernels newer 4.11.x to build -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -API changes enforce porting. - -Signed-off-by: Jan-Simon Möller <jsmoeller@linuxfoundation.org> ---- - sllin/sllin.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/sllin/sllin.c b/sllin/sllin.c -index 2969448..7e17127 100644 ---- a/sllin/sllin.c -+++ b/sllin/sllin.c -@@ -56,7 +56,12 @@ - #include <linux/rtnetlink.h> - #include <linux/if_arp.h> - #include <linux/if_ether.h> -+#include <linux/version.h> -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0) - #include <linux/sched.h> -+#else -+#include <uapi/linux/sched/types.h> -+#endif - #include <linux/delay.h> - #include <linux/init.h> - #include <linux/can.h> -@@ -447,7 +451,9 @@ static int sll_open(struct net_device *dev) - static void sll_free_netdev(struct net_device *dev) - { - int i = dev->base_addr; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,9) - free_netdev(dev); -+#endif - sllin_devs[i] = NULL; - } - -@@ -460,7 +466,12 @@ static const struct net_device_ops sll_netdev_ops = { - static void sll_setup(struct net_device *dev) - { - dev->netdev_ops = &sll_netdev_ops; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,9) - dev->destructor = sll_free_netdev; -+#else -+ dev->needs_free_netdev = true; -+ dev->priv_destructor = sll_free_netdev; -+#endif - - dev->hard_header_len = 0; - dev->addr_len = 0; -@@ -1685,8 +1696,10 @@ static void __exit sllin_exit(void) - sl = netdev_priv(dev); - if (sl->tty) { - netdev_dbg(sl->dev, "tty discipline still running\n"); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,9) - /* Intentionally leak the control block. */ - dev->destructor = NULL; -+#endif - } - - unregister_netdev(dev); --- -2.13.7 - diff --git a/recipes-kernel/sllin/files/0005-Fix-build-with-5.13-kernel.patch b/recipes-kernel/sllin/files/0005-Fix-build-with-5.13-kernel.patch new file mode 100644 index 00000000..51147081 --- /dev/null +++ b/recipes-kernel/sllin/files/0005-Fix-build-with-5.13-kernel.patch @@ -0,0 +1,24 @@ +Remove TTY_LDISC_MAGIC usage + +The 5.13 kernel removed the .magic field from tty_ldisc_ops and +the associated TTY_LDISC_MAGIC #define, so remove their use when +building for 5.13 or newer. + +Upstream-Status: Inappropriate [no upstream] +Signed-off-by: Scott Murray <scott.murray@konsulko.com> + +--- +diff --git a/sllin/sllin.c b/sllin/sllin.c +index 92c52ad..904cff9 100644 +--- a/sllin/sllin.c ++++ b/sllin/sllin.c +@@ -1619,7 +1619,9 @@ static int sllin_ioctl(struct tty_struct *tty, struct file *file, + + static struct tty_ldisc_ops sll_ldisc = { + .owner = THIS_MODULE, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,13,0) + .magic = TTY_LDISC_MAGIC, ++#endif + .name = "sllin", + .open = sllin_open, + .close = sllin_close, diff --git a/recipes-kernel/sllin/files/0006-Fix-build-with-5.14-kernel.patch b/recipes-kernel/sllin/files/0006-Fix-build-with-5.14-kernel.patch new file mode 100644 index 00000000..bb0049f0 --- /dev/null +++ b/recipes-kernel/sllin/files/0006-Fix-build-with-5.14-kernel.patch @@ -0,0 +1,108 @@ +Updates for 5.14 + +The 5.14 kernel reworked the tty register and unregister call +arguments, and made one of the arguments to the receive_buf +callback const, add some kernel version conditionals to handle +those. + +Upstream-Status: Inappropriate [no upstream] +Signed-off-by: Scott Murray <scott.murray@konsulko.com> + +--- + sllin/sllin.c | 29 ++++++++++++++++++++++++----- + 1 file changed, 24 insertions(+), 5 deletions(-) + +diff --git a/sllin/sllin.c b/sllin/sllin.c +index 904cff9..b89d06d 100644 +--- a/sllin/sllin.c ++++ b/sllin/sllin.c +@@ -72,6 +72,12 @@ + #include <linux/version.h> + #include "linux/lin_bus.h" + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,14,0) ++#define FP_CONST const ++#else ++#define FP_CONST ++#endif ++ + /* Should be in include/linux/tty.h */ + #define N_SLLIN 25 + /* -------------------------------- */ +@@ -185,9 +191,9 @@ struct sllin { + static struct net_device **sllin_devs; + static int sllin_configure_frame_cache(struct sllin *sl, struct can_frame *cf); + static void sllin_slave_receive_buf(struct tty_struct *tty, +- const unsigned char *cp, char *fp, int count); ++ const unsigned char *cp, FP_CONST char *fp, int count); + static void sllin_master_receive_buf(struct tty_struct *tty, +- const unsigned char *cp, char *fp, int count); ++ const unsigned char *cp, FP_CONST char *fp, int count); + + + /* Values of two parity bits in LIN Protected +@@ -492,7 +498,7 @@ static void sll_setup(struct net_device *dev) + Routines looking at TTY side. + ******************************************/ + static void sllin_master_receive_buf(struct tty_struct *tty, +- const unsigned char *cp, char *fp, int count) ++ const unsigned char *cp, FP_CONST char *fp, int count) + { + struct sllin *sl = (struct sllin *) tty->disc_data; + +@@ -735,7 +741,7 @@ static void sllin_slave_finish_rx_msg(struct sllin *sl) + } + + static void sllin_slave_receive_buf(struct tty_struct *tty, +- const unsigned char *cp, char *fp, int count) ++ const unsigned char *cp, FP_CONST char *fp, int count) + { + struct sllin *sl = (struct sllin *) tty->disc_data; + int lin_id; +@@ -842,7 +848,7 @@ static void sllin_slave_receive_buf(struct tty_struct *tty, + } + + static void sllin_receive_buf(struct tty_struct *tty, +- const unsigned char *cp, char *fp, int count) ++ const unsigned char *cp, FP_CONST char *fp, int count) + { + struct sllin *sl = (struct sllin *) tty->disc_data; + netdev_dbg(sl->dev, "sllin_receive_buf invoked, count = %u\n", count); +@@ -1619,6 +1625,9 @@ static int sllin_ioctl(struct tty_struct *tty, struct file *file, + + static struct tty_ldisc_ops sll_ldisc = { + .owner = THIS_MODULE, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,14,0) ++ .num = N_SLLIN, ++#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,13,0) + .magic = TTY_LDISC_MAGIC, + #endif +@@ -1648,7 +1657,11 @@ static int __init sllin_init(void) + } + + /* Fill in our line protocol discipline, and register it */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,14,0) ++ status = tty_register_ldisc(&sll_ldisc); ++#else + status = tty_register_ldisc(N_SLLIN, &sll_ldisc); ++#endif + if (status) { + pr_err("sllin: can't register line discipline\n"); + kfree(sllin_devs); +@@ -1719,9 +1732,15 @@ static void __exit sllin_exit(void) + kfree(sllin_devs); + sllin_devs = NULL; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,14,0) ++ tty_unregister_ldisc(&sll_ldisc); ++ ++#else + i = tty_unregister_ldisc(N_SLLIN); ++ + if (i) + pr_err("sllin: can't unregister ldisc (err %d)\n", i); ++#endif + } + + module_init(sllin_init); diff --git a/recipes-kernel/sllin/files/lin_config.conf b/recipes-kernel/sllin/files/lin_config.conf deleted file mode 100644 index 9775b8b3..00000000 --- a/recipes-kernel/sllin/files/lin_config.conf +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!--PCAN-LIN CT profile.--> -<PCLIN_PROFILE Version="1"> - <LIN Group="2"> - <Scheduler_Entries Count="1"> - <!-- Poll steering wheel adapter at address 0x21 every 100 ms --> - <Entry Time="100">33</Entry> - </Scheduler_Entries> - </LIN> -</PCLIN_PROFILE> diff --git a/recipes-kernel/sllin/files/sllin-demo-virtual.service b/recipes-kernel/sllin/files/sllin-demo-virtual.service deleted file mode 100644 index 78824219..00000000 --- a/recipes-kernel/sllin/files/sllin-demo-virtual.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=LIN demo configuration (virtual) -ConditionPathExists=!/dev/ttyUSB0 -After=afm-system-daemon.service - -[Service] -Type=oneshot -ExecStart=/usr/bin/start_lin_demo.sh -RemainAfterExit=yes - -[Install] -WantedBy=multi-user.target diff --git a/recipes-kernel/sllin/files/sllin-demo.service b/recipes-kernel/sllin/files/sllin-demo.service deleted file mode 100644 index 2f2f5ac2..00000000 --- a/recipes-kernel/sllin/files/sllin-demo.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=LIN demo configuration -ConditionPathExists=/dev/ttyUSB0 -After=afm-system-daemon.service - -[Service] -Type=forking -PIDFile=/var/run/lin_config.pid -ExecStart=/usr/bin/start_lin_demo.sh -RemainAfterExit=yes - -[Install] -WantedBy=multi-user.target diff --git a/recipes-kernel/sllin/files/start_lin_demo.sh b/recipes-kernel/sllin/files/start_lin_demo.sh deleted file mode 100755 index 26f64c0a..00000000 --- a/recipes-kernel/sllin/files/start_lin_demo.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/sh - -# Attach serial LIN->CAN bridge and set up LIN polling -if [ -c /dev/ttyUSB0 ]; then - sleep 1 - /usr/bin/lin_config -c /etc/lin_config.conf -a sllin:/dev/ttyUSB0 - pidof lin_config > /var/run/lin_config.pid - sleep 1 -else - ip link add dev sllin0 type vcan -fi -ip link set sllin0 up - -# Initialize HVAC controller -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 02A# -usleep 100000 -cansend sllin0 02B# -usleep 100000 -cansend sllin0 032#F0F8FFFFFFFFFFFF -usleep 100000 -cansend sllin0 032#F0F8FFFFFFFFFFFF -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 030# -usleep 100000 -cansend sllin0 02D# -usleep 100000 -cansend sllin0 02C# -usleep 100000 -cansend sllin0 02D# -usleep 100000 -cansend sllin0 02C# -usleep 100000 - diff --git a/recipes-kernel/sllin/sllin.bb b/recipes-kernel/sllin/sllin.bb deleted file mode 100644 index 7c4313f1..00000000 --- a/recipes-kernel/sllin/sllin.bb +++ /dev/null @@ -1,51 +0,0 @@ -DESCRIPTION = "slLIN driver module" -LICENSE = "GPLv2" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" - -inherit module systemd - -DEPENDS = "virtual/kernel" - -SRC_URI = "git://github.com/trainman419/linux-lin.git;protocol=https" -SRCREV = "155d885e8ccc907a56f6c86c4b159fac27ef6fec" -S = "${WORKDIR}/git/sllin" - -PV = "0.1+git${SRCPV}" - -SRC_URI_append = " \ - file://0001_update_makefile.patch;pnum=2 \ - file://0002_fix_null_operation_check.patch;pnum=2 \ - file://0003-Allow-recent-kernels-newer-4.11.x-to-build.patch;pnum=2 \ - file://0001-Disable-sllin-driver-debug-log.patch;pnum=2 \ - file://sllin-demo.service \ - file://sllin-demo-virtual.service \ - file://start_lin_demo.sh \ - file://lin_config.conf \ -" - -KERNEL_MODULE_AUTOLOAD_append = " sllin" -KERNEL_MODULE_PROBECONF_append = " sllin" - -SLLINBAUDRATE ??= "9600" -module_conf_sllin = "options sllin baudrate=${SLLINBAUDRATE}" - -SYSTEMD_SERVICE_${PN} = "sllin-demo.service" -SYSTEMD_SERVICE_${PN}-virtual = "sllin-demo-virtual.service" - -do_install_append () { - install -d 644 ${D}/${bindir} - install -m 755 ${WORKDIR}/start_lin_demo.sh ${D}/${bindir}/start_lin_demo.sh - install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/sllin-demo.service ${D}${systemd_system_unitdir}/ - install -m 0644 ${WORKDIR}/sllin-demo-virtual.service ${D}${systemd_system_unitdir}/ - install -d ${D}${sysconfdir} - install -m 0644 ${WORKDIR}/lin_config.conf ${D}${sysconfdir}/ -} - -PACKAGES =+ "${PN}-virtual" - -FILES_${PN} += "${bindir}/start_lin_demo.sh ${sysconfdir}/lin_config.conf" - -FILES_${PN}-virtual = "${systemd_system_unitdir}/sllin-demo-virtual.service" - -RDEPENDS_${PN} += "lin-config" diff --git a/recipes-kernel/sllin/files/0001_update_makefile.patch b/recipes-kernel/sllin/sllin/0001-update-makefile.patch index 7db57802..7db57802 100644 --- a/recipes-kernel/sllin/files/0001_update_makefile.patch +++ b/recipes-kernel/sllin/sllin/0001-update-makefile.patch diff --git a/recipes-kernel/sllin/sllin/0002-5.4-less-than-110-fix.patch b/recipes-kernel/sllin/sllin/0002-5.4-less-than-110-fix.patch new file mode 100644 index 00000000..8c13bfb5 --- /dev/null +++ b/recipes-kernel/sllin/sllin/0002-5.4-less-than-110-fix.patch @@ -0,0 +1,25 @@ +Fix compilation against kernels < 5.4.110 + +The fix to handle the backport of 4e096a18 to linux-5.4.y is a bit +too broad, as it breaks building against kernels older than 5.4.110, +add a version check to fix. + +Upstream-Status: pending +Signed-off-by: Scott Murray <scott.murray@konsulko.com> + +diff --git a/sllin/sllin.c b/sllin/sllin.c +index b3f2636..a6fb120 100644 +--- a/sllin/sllin.c ++++ b/sllin/sllin.c +@@ -1604,7 +1604,11 @@ static struct sllin *sll_alloc(dev_t line) + sl = netdev_priv(dev); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) + can_ml = (void *)sl + ALIGN(sizeof(*sl), NETDEV_ALIGN); ++ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 110) + can_set_ml_priv(dev, can_ml); ++ #else ++ dev->ml_priv = can_ml; ++ #endif + #endif + /* Initialize channel control data */ + sl->magic = SLLIN_MAGIC; diff --git a/recipes-kernel/sllin/sllin_git.bb b/recipes-kernel/sllin/sllin_git.bb new file mode 100644 index 00000000..f13bcd55 --- /dev/null +++ b/recipes-kernel/sllin/sllin_git.bb @@ -0,0 +1,22 @@ +DESCRIPTION = "slLIN driver module" +LICENSE = "GPL-2.0-only" +LIC_FILES_CHKSUM = "file://sllin.c;beginline=7;endline=37;md5=6408e14dba951f8cbe3c2a003a0d89d2" + +inherit module + +DEPENDS = "virtual/kernel" + +SRC_URI = "git://github.com/lin-bus/linux-lin.git;protocol=https;branch=master \ + file://0001-update-makefile.patch;pnum=2 \ + file://0002-5.4-less-than-110-fix.patch;pnum=2 \ +" +SRCREV = "beb057d7505e0c4d7c61f3f4927b76916ec00e88" +S = "${WORKDIR}/git/sllin" + +PV = "0.1+git${SRCPV}" + +KERNEL_MODULE_AUTOLOAD:append = " sllin" +KERNEL_MODULE_PROBECONF:append = " sllin" + +SLLINBAUDRATE ??= "9600" +module_conf_sllin = "options sllin baudrate=${SLLINBAUDRATE}" diff --git a/recipes-multimedia/flite/flite-voicedata_1.05.bb b/recipes-multimedia/flite/flite-voicedata_1.05.bb index c339c7bf..e38b8120 100755 --- a/recipes-multimedia/flite/flite-voicedata_1.05.bb +++ b/recipes-multimedia/flite/flite-voicedata_1.05.bb @@ -19,4 +19,4 @@ do_install() { install -m 0644 -p ${S}/*.htsvoice ${D}/${datadir}/Voice/us/ } -FILES_${PN} += " ${datadir}/Voice/us/*.htsvoice " +FILES:${PN} += " ${datadir}/Voice/us/*.htsvoice " diff --git a/recipes-multimedia/flite/flite_1.06.bb b/recipes-multimedia/flite/flite_1.06.bb index aff54964..f3b77c38 100755 --- a/recipes-multimedia/flite/flite_1.06.bb +++ b/recipes-multimedia/flite/flite_1.06.bb @@ -1,7 +1,7 @@ SUMMARY = "The Flite+hts_engine is an English TTS System." HOMEPAGE = "http://hts-engine.sourceforge.net/" SECTION = "libs" -LICENSE = "BSD" +LICENSE = "BSD-3-Clause" LIC_FILES_CHKSUM = "file://COPYING;md5=a1ab16abd1c593cab35c2987fd871678" @@ -14,7 +14,7 @@ SRC_URI[sha256sum] = "8a8c3ecc186ef92eda150a4aa687d8638f4f42be52aa2971e72aa960d4 DEPENDS = " hts-engine " -RDEPENDS_${PN} += " flite-voicedata " +RDEPENDS:${PN} += " flite-voicedata " inherit autotools-brokensep diff --git a/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_%.bbappend b/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_%.bbappend new file mode 100644 index 00000000..2d314acd --- /dev/null +++ b/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'gstreamer1.0-plugins-good_agldemo.inc', '', d)} diff --git a/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_agldemo.inc b/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_agldemo.inc new file mode 100644 index 00000000..10fd995b --- /dev/null +++ b/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_agldemo.inc @@ -0,0 +1,2 @@ +# libv4l2 is useful for making more efficient use of cameras via v4l2src. +PACKAGECONFIG:append = " libv4l2" diff --git a/recipes-multimedia/hts_engine/hts-engine_1.10.bb b/recipes-multimedia/hts_engine/hts-engine_1.10.bb index ed5cae63..5a72c5af 100644 --- a/recipes-multimedia/hts_engine/hts-engine_1.10.bb +++ b/recipes-multimedia/hts_engine/hts-engine_1.10.bb @@ -1,7 +1,7 @@ SUMMARY = "hts_engine is software to synthesize speech waveform from HMMs trained by the HMM-based speech synthesis system (HTS)." HOMEPAGE = "http://hts-engine.sourceforge.net/" SECTION = "libs" -LICENSE = "BSD" +LICENSE = "BSD-3-Clause" LIC_FILES_CHKSUM = "file://COPYING;md5=b3be85b37c90bfd4d34d79a0e3f28700" diff --git a/recipes-multimedia/libmp4v2/files/0001-add-a-configure-option-to-disable-build-of-man-pages.patch b/recipes-multimedia/libmp4v2/files/0001-add-a-configure-option-to-disable-build-of-man-pages.patch new file mode 100644 index 00000000..51896e8d --- /dev/null +++ b/recipes-multimedia/libmp4v2/files/0001-add-a-configure-option-to-disable-build-of-man-pages.patch @@ -0,0 +1,40 @@ +From 530a31e3eb24b2f1ed7b30859ed62a2d1b24bd91 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andreas=20M=C3=BCller?= <schnitzeltony@googlemail.com> +Date: Tue, 7 Feb 2017 11:51:58 +0100 +Subject: [PATCH] add a configure option to disable build of man-pages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream-Status: Pending + +Signed-off-by: Andreas Müller <schnitzeltony@googlemail.com> +--- + configure.ac | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 8316c67..099fc0c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -67,6 +67,8 @@ AC_ARG_ENABLE([largefile], + [AS_HELP_STRING([--disable-largefile],[disable LFS (large file support)])]) + AC_ARG_ENABLE([util], + [AS_HELP_STRING([--disable-util],[disable build of command-line utilities])]) ++AC_ARG_ENABLE([man], ++ [AS_HELP_STRING([--disable-man],[disable build of man-pages])]) + AC_ARG_ENABLE([bi], + [AS_HELP_STRING([--enable-bi=ARCH],[enable -mARCH for bi-arch compilation])]) + AC_ARG_ENABLE([ub], +@@ -395,7 +397,7 @@ AM_CONDITIONAL([ADD_PLATFORM_POSIX],[test "$X_PLATFORM" = "posix"]) + AM_CONDITIONAL([ADD_PLATFORM_WIN32],[test "$X_PLATFORM" = "win32"]) + + AM_CONDITIONAL([ADD_UTIL],[test "$enable_util" != "no"]) +-AM_CONDITIONAL([ADD_MANS],[test "$X_PLATFORM" != "win32"]) ++AM_CONDITIONAL([ADD_MANS],[test "$enable_man" != "no"]) + + ############################################################################### + # declare common substitutions +-- +2.9.3 + diff --git a/recipes-multimedia/libmp4v2/files/gcc10.patch b/recipes-multimedia/libmp4v2/files/gcc10.patch new file mode 100644 index 00000000..fca17099 --- /dev/null +++ b/recipes-multimedia/libmp4v2/files/gcc10.patch @@ -0,0 +1,420 @@ +Fix compilation with gcc 10 + +Patch pulled from Fedora source RPM: +https://dl.fedoraproject.org/pub/fedora/linux/development/34/Everything/source/tree/Packages/l/libmp4v2-2.1.0-0.23.trunkREV507.fc34.src.rpm + +Upstream-Status: Inappropriate[no upstream] +Signed-off-by: Scott Murray <scott.murray@konsulko.com> + +--- +diff -Nrup a/libutil/Utility.cpp b/libutil/Utility.cpp +--- a/libutil/Utility.cpp 2015-04-24 09:37:49.000000000 -0600 ++++ b/libutil/Utility.cpp 2019-09-24 12:39:23.669103515 -0600 +@@ -531,26 +531,26 @@ Utility::process_impl() + printHelp( false, false ); + return SUCCESS; + +- case LC_DEBUG: ++ case int(LC_DEBUG): + debugUpdate( std::strtoul( prog::optarg, NULL, 0 ) ); + break; + +- case LC_VERBOSE: ++ case int(LC_VERBOSE): + { + const uint32_t level = std::strtoul( prog::optarg, NULL, 0 ); + _verbosity = ( level < 4 ) ? level : 3; + break; + } + +- case LC_HELP: ++ case int(LC_HELP): + printHelp( true, false ); + return SUCCESS; + +- case LC_VERSION: ++ case int(LC_VERSION): + printVersion( false ); + return SUCCESS; + +- case LC_VERSIONX: ++ case int(LC_VERSIONX): + printVersion( true ); + return SUCCESS; + +diff -Nrup a/util/mp4art.cpp b/util/mp4art.cpp +--- a/util/mp4art.cpp 2015-04-24 09:37:49.000000000 -0600 ++++ b/util/mp4art.cpp 2019-09-24 12:32:35.078171912 -0600 +@@ -377,11 +377,11 @@ ArtUtility::utility_option( int code, bo + handled = true; + + switch( code ) { +- case LC_ART_ANY: ++ case int(LC_ART_ANY): + _artFilter = numeric_limits<uint32_t>::max(); + break; + +- case LC_ART_INDEX: ++ case int(LC_ART_INDEX): + { + istringstream iss( prog::optarg ); + iss >> _artFilter; +@@ -390,29 +390,29 @@ ArtUtility::utility_option( int code, bo + break; + } + +- case LC_LIST: ++ case int(LC_LIST): + _action = &ArtUtility::actionList; + break; + +- case LC_ADD: ++ case int(LC_ADD): + _action = &ArtUtility::actionAdd; + _artImageFile = prog::optarg; + if( _artImageFile.empty() ) + return herrf( "invalid image file: empty-string\n" ); + break; + +- case LC_REMOVE: ++ case int(LC_REMOVE): + _action = &ArtUtility::actionRemove; + break; + +- case LC_REPLACE: ++ case int(LC_REPLACE): + _action = &ArtUtility::actionReplace; + _artImageFile = prog::optarg; + if( _artImageFile.empty() ) + return herrf( "invalid image file: empty-string\n" ); + break; + +- case LC_EXTRACT: ++ case int(LC_EXTRACT): + _action = &ArtUtility::actionExtract; + break; + +diff -Nrup a/util/mp4chaps.cpp b/util/mp4chaps.cpp +--- a/util/mp4chaps.cpp 2015-04-24 09:37:49.000000000 -0600 ++++ b/util/mp4chaps.cpp 2019-09-24 12:35:24.121316167 -0600 +@@ -634,32 +634,32 @@ ChapterUtility::utility_option( int code + + switch( code ) { + case 'A': +- case LC_CHPT_ANY: ++ case int(LC_CHPT_ANY): + _ChapterType = MP4ChapterTypeAny; + break; + + case 'Q': +- case LC_CHPT_QT: ++ case int(LC_CHPT_QT): + _ChapterType = MP4ChapterTypeQt; + break; + + case 'N': +- case LC_CHPT_NERO: ++ case int(LC_CHPT_NERO): + _ChapterType = MP4ChapterTypeNero; + break; + + case 'C': +- case LC_CHPT_COMMON: ++ case int(LC_CHPT_COMMON): + _ChapterFormat = CHPT_FMT_COMMON; + break; + + case 'l': +- case LC_CHP_LIST: ++ case int(LC_CHP_LIST): + _action = &ChapterUtility::actionList; + break; + + case 'e': +- case LC_CHP_EVERY: ++ case int(LC_CHP_EVERY): + { + istringstream iss( prog::optarg ); + iss >> _ChaptersEvery; +@@ -675,7 +675,7 @@ ChapterUtility::utility_option( int code + _action = &ChapterUtility::actionExport; + break; + +- case LC_CHP_EXPORT: ++ case int(LC_CHP_EXPORT): + _action = &ChapterUtility::actionExport; + /* currently not supported since the chapters of n input files would be written to one chapter file + _ChapterFile = prog::optarg; +@@ -690,7 +690,7 @@ ChapterUtility::utility_option( int code + _action = &ChapterUtility::actionImport; + break; + +- case LC_CHP_IMPORT: ++ case int(LC_CHP_IMPORT): + _action = &ChapterUtility::actionImport; + /* currently not supported since the chapters of n input files would be read from one chapter file + _ChapterFile = prog::optarg; +@@ -702,12 +702,12 @@ ChapterUtility::utility_option( int code + break; + + case 'c': +- case LC_CHP_CONVERT: ++ case int(LC_CHP_CONVERT): + _action = &ChapterUtility::actionConvert; + break; + + case 'r': +- case LC_CHP_REMOVE: ++ case int(LC_CHP_REMOVE): + _action = &ChapterUtility::actionRemove; + break; + +diff -Nrup a/util/mp4file.cpp b/util/mp4file.cpp +--- a/util/mp4file.cpp 2015-04-24 09:37:49.000000000 -0600 ++++ b/util/mp4file.cpp 2019-09-24 12:33:09.735996459 -0600 +@@ -190,15 +190,15 @@ FileUtility::utility_option( int code, b + handled = true; + + switch( code ) { +- case LC_LIST: ++ case int(LC_LIST): + _action = &FileUtility::actionList; + break; + +- case LC_OPTIMIZE: ++ case int(LC_OPTIMIZE): + _action = &FileUtility::actionOptimize; + break; + +- case LC_DUMP: ++ case int(LC_DUMP): + _action = &FileUtility::actionDump; + break; + +diff -Nrup a/util/mp4subtitle.cpp b/util/mp4subtitle.cpp +--- a/util/mp4subtitle.cpp 2015-04-24 09:37:49.000000000 -0600 ++++ b/util/mp4subtitle.cpp 2019-09-24 12:33:53.739773682 -0600 +@@ -165,25 +165,25 @@ SubtitleUtility::utility_option( int cod + handled = true; + + switch( code ) { +- case LC_LIST: ++ case int(LC_LIST): + _action = &SubtitleUtility::actionList; + break; + +- case LC_EXPORT: ++ case int(LC_EXPORT): + _action = &SubtitleUtility::actionExport; + _stTextFile = prog::optarg; + if( _stTextFile.empty() ) + return herrf( "invalid TXT file: empty-string\n" ); + break; + +- case LC_IMPORT: ++ case int(LC_IMPORT): + _action = &SubtitleUtility::actionImport; + _stTextFile = prog::optarg; + if( _stTextFile.empty() ) + return herrf( "invalid TXT file: empty-string\n" ); + break; + +- case LC_REMOVE: ++ case int(LC_REMOVE): + _action = &SubtitleUtility::actionRemove; + break; + +diff -Nrup a/util/mp4track.cpp b/util/mp4track.cpp +--- a/util/mp4track.cpp 2015-04-24 09:37:49.000000000 -0600 ++++ b/util/mp4track.cpp 2019-09-24 12:37:02.934815918 -0600 +@@ -789,11 +789,11 @@ TrackUtility::utility_option( int code, + handled = true; + + switch( code ) { +- case LC_TRACK_WILDCARD: ++ case int(LC_TRACK_WILDCARD): + _trackMode = TM_WILDCARD; + break; + +- case LC_TRACK_INDEX: ++ case int(LC_TRACK_INDEX): + { + _trackMode = TM_INDEX; + istringstream iss( prog::optarg ); +@@ -803,7 +803,7 @@ TrackUtility::utility_option( int code, + break; + } + +- case LC_TRACK_ID: ++ case int(LC_TRACK_ID): + { + _trackMode = TM_ID; + istringstream iss( prog::optarg ); +@@ -813,142 +813,142 @@ TrackUtility::utility_option( int code, + break; + } + +- case LC_LIST: ++ case int(LC_LIST): + _action = &TrackUtility::actionList; + break; + +- case LC_COLR_PARMS: ++ case int(LC_COLR_PARMS): + _colorParameterItem.convertFromCSV( prog::optarg ); + break; + +- case LC_COLR_PARM_HD: ++ case int(LC_COLR_PARM_HD): + _colorParameterItem.primariesIndex = 1; + _colorParameterItem.transferFunctionIndex = 1; + _colorParameterItem.matrixIndex = 1; + break; + +- case LC_COLR_PARM_SD: ++ case int(LC_COLR_PARM_SD): + _colorParameterItem.primariesIndex = 6; + _colorParameterItem.transferFunctionIndex = 1; + _colorParameterItem.matrixIndex = 6; + break; + +- case LC_COLR_LIST: ++ case int(LC_COLR_LIST): + _action = &TrackUtility::actionColorParameterList; + break; + +- case LC_ENABLED: ++ case int(LC_ENABLED): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setEnabled; + _actionTrackModifierSet_name = "enabled"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_INMOVIE: ++ case int(LC_INMOVIE): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setInMovie; + _actionTrackModifierSet_name = "inMovie"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_INPREVIEW: ++ case int(LC_INPREVIEW): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setInPreview; + _actionTrackModifierSet_name = "inPreview"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_LAYER: ++ case int(LC_LAYER): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setLayer; + _actionTrackModifierSet_name = "layer"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_ALTGROUP: ++ case int(LC_ALTGROUP): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setAlternateGroup; + _actionTrackModifierSet_name = "alternateGroup"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_VOLUME: ++ case int(LC_VOLUME): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setVolume; + _actionTrackModifierSet_name = "volume"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_WIDTH: ++ case int(LC_WIDTH): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setWidth; + _actionTrackModifierSet_name = "width"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_HEIGHT: ++ case int(LC_HEIGHT): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setHeight; + _actionTrackModifierSet_name = "height"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_LANGUAGE: ++ case int(LC_LANGUAGE): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setLanguage; + _actionTrackModifierSet_name = "language"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_HDLRNAME: ++ case int(LC_HDLRNAME): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setHandlerName; + _actionTrackModifierSet_name = "handlerName"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_UDTANAME: ++ case int(LC_UDTANAME): + _action = &TrackUtility::actionTrackModifierSet; + _actionTrackModifierSet_function = &TrackModifier::setUserDataName; + _actionTrackModifierSet_name = "userDataName"; + _actionTrackModifierSet_value = prog::optarg; + break; + +- case LC_UDTANAME_R: ++ case int(LC_UDTANAME_R): + _action = &TrackUtility::actionTrackModifierRemove; + _actionTrackModifierRemove_function = &TrackModifier::removeUserDataName; + _actionTrackModifierRemove_name = "userDataName"; + break; + +- case LC_COLR_ADD: ++ case int(LC_COLR_ADD): + _action = &TrackUtility::actionColorParameterAdd; + break; + +- case LC_COLR_SET: ++ case int(LC_COLR_SET): + _action = &TrackUtility::actionColorParameterSet; + break; + +- case LC_COLR_REMOVE: ++ case int(LC_COLR_REMOVE): + _action = &TrackUtility::actionColorParameterRemove; + break; + +- case LC_PASP_PARMS: ++ case int(LC_PASP_PARMS): + _pictureAspectRatioItem.convertFromCSV( prog::optarg ); + break; + +- case LC_PASP_LIST: ++ case int(LC_PASP_LIST): + _action = &TrackUtility::actionPictureAspectRatioList; + break; + +- case LC_PASP_ADD: ++ case int(LC_PASP_ADD): + _action = &TrackUtility::actionPictureAspectRatioAdd; + break; + +- case LC_PASP_SET: ++ case int(LC_PASP_SET): + _action = &TrackUtility::actionPictureAspectRatioSet; + break; + +- case LC_PASP_REMOVE: ++ case int(LC_PASP_REMOVE): + _action = &TrackUtility::actionPictureAspectRatioRemove; + break; + diff --git a/recipes-multimedia/libmp4v2/libmp4v2_git.bb b/recipes-multimedia/libmp4v2/libmp4v2_git.bb new file mode 100644 index 00000000..5fb6cbc8 --- /dev/null +++ b/recipes-multimedia/libmp4v2/libmp4v2_git.bb @@ -0,0 +1,19 @@ +SUMMARY = "The MP4v2 library provides an API to create and modify mp4 files" +HOMEPAGE = "https://github.com/sergiomb2/libmp4v2/wiki" +LICENSE = "MPL-1.1" +LIC_FILES_CHKSUM = "file://COPYING;md5=eb3014b036b6d2151d944aef6a84c36f" + +inherit autotools-brokensep pkgconfig + +SRC_URI = " \ + git://github.com/sergiomb2/${BPN}.git;branch=master;protocol=https \ + file://0001-add-a-configure-option-to-disable-build-of-man-pages.patch \ + file://gcc10.patch \ +" +SRCREV = "855e9674232808ff3be7191b697dfb56917db21f" +S = "${WORKDIR}/git" +PV = "2.1.0+git${SRCPV}" + + +SECURITY_CFLAGS = "${SECURITY_NO_PIE_CFLAGS}" +EXTRA_OECONF = "--disable-man" diff --git a/recipes-multimedia/musicpd/files/mpd-volatiles.conf b/recipes-multimedia/musicpd/files/mpd-volatiles.conf new file mode 100644 index 00000000..dd7bff09 --- /dev/null +++ b/recipes-multimedia/musicpd/files/mpd-volatiles.conf @@ -0,0 +1,2 @@ +d /var/volatile/lib/mpd 0755 mpd mpd +L+ /var/lib/mpd - - - - /var/volatile/lib/mpd diff --git a/recipes-multimedia/musicpd/files/mpd.conf.in b/recipes-multimedia/musicpd/files/mpd.conf.in new file mode 100644 index 00000000..6dae60ae --- /dev/null +++ b/recipes-multimedia/musicpd/files/mpd.conf.in @@ -0,0 +1,425 @@ +# An example configuration file for MPD +# See the mpd.conf man page for a more detailed description of each parameter. + + +# Files and directories ####################################################### +# +# This setting controls the top directory which MPD will search to discover the +# available audio files and add them to the daemon's online database. This +# setting defaults to the XDG directory, otherwise the music directory will be +# be disabled and audio files will only be accepted over ipc socket (using +# file:// protocol) or streaming files over an accepted protocol. +# +music_directory "/media" +# +# This setting sets the MPD internal playlist directory. The purpose of this +# directory is storage for playlists created by MPD. The server will use +# playlist files not created by the server but only if they are in the MPD +# format. This setting defaults to playlist saving being disabled. +# +playlist_directory "%playlist_directory%" +# +# This setting sets the location of the MPD database. This file is used to +# load the database at server start up and store the database while the +# server is not up. This setting defaults to disabled which will allow +# MPD to accept files over ipc socket (using file:// protocol) or streaming +# files over an accepted protocol. +# +db_file "%db_file%" +# +# These settings are the locations for the daemon log files for the daemon. +# These logs are great for troubleshooting, depending on your log_level +# settings. +# +# The special value "syslog" makes MPD use the local syslog daemon. This +# setting defaults to logging to syslog, otherwise logging is disabled. +# +log_file "syslog" +# +# This setting sets the location of the file which stores the process ID +# for use of mpd --kill and some init scripts. This setting is disabled by +# default and the pid file will not be stored. +# +#pid_file "/var/run/mpd/mpd.pid" +# +# This setting sets the location of the file which contains information about +# most variables to get MPD back into the same general shape it was in before +# it was brought down. This setting is disabled by default and the server +# state will be reset on server start up. +# +state_file "%state_file%" +# +# The location of the sticker database. This is a database which +# manages dynamic information attached to songs. +# +#sticker_file "~/.mpd/sticker.sql" +# +############################################################################### + + +# General music daemon options ################################################ +# +# This setting specifies the user that MPD will run as. MPD should never run as +# root and you may use this setting to make MPD change its user ID after +# initialization. This setting is disabled by default and MPD is run as the +# current user. +# +user "mpd" +# +# This setting specifies the group that MPD will run as. If not specified +# primary group of user specified with "user" setting will be used (if set). +# This is useful if MPD needs to be a member of group such as "audio" to +# have permission to use sound card. +# +#group "audio" +# +# This setting sets the address for the daemon to listen on. Careful attention +# should be paid if this is assigned to anything other then the default, any. +# This setting can deny access to control of the daemon. +# +# For network +bind_to_address "any" +# +# And for Unix Socket +#bind_to_address "~/.mpd/socket" +# +# This setting is the TCP port that is desired for the daemon to get assigned +# to. +# +#port "6600" +# +# This setting controls the type of information which is logged. Available +# setting arguments are "default", "secure" or "verbose". The "verbose" setting +# argument is recommended for troubleshooting, though can quickly stretch +# available resources on limited hardware storage. +# +#log_level "default" +# +# If you have a problem with your MP3s ending abruptly it is recommended that +# you set this argument to "no" to attempt to fix the problem. If this solves +# the problem, it is highly recommended to fix the MP3 files with vbrfix +# (available from <http://www.willwap.co.uk/Programs/vbrfix.php>), at which +# point gapless MP3 playback can be enabled. +# +#gapless_mp3_playback "yes" +# +# This setting enables MPD to create playlists in a format usable by other +# music players. +# +#save_absolute_paths_in_playlists "no" +# +# This setting defines a list of tag types that will be extracted during the +# audio file discovery process. Optionally, 'comment' can be added to this +# list. +# +#metadata_to_use "artist,album,title,track,name,genre,date,composer,performer,disc" +# +# This setting enables automatic update of MPD's database when files in +# music_directory are changed. +# +auto_update "yes" +# +# Limit the depth of the directories being watched, 0 means only watch +# the music directory itself. There is no limit by default. +# +auto_update_depth "3" +# +############################################################################### + + +# Symbolic link behavior ###################################################### +# +# If this setting is set to "yes", MPD will discover audio files by following +# symbolic links outside of the configured music_directory. +# +follow_outside_symlinks "no" +# +# If this setting is set to "yes", MPD will discover audio files by following +# symbolic links inside of the configured music_directory. +# +#follow_inside_symlinks "yes" +# +############################################################################### + + +# Zeroconf / Avahi Service Discovery ########################################## +# +# If this setting is set to "yes", service information will be published with +# Zeroconf / Avahi. +# +#zeroconf_enabled "yes" +# +# The argument to this setting will be the Zeroconf / Avahi unique name for +# this MPD server on the network. +# +#zeroconf_name "Music Player" +# +############################################################################### + + +# Permissions ################################################################# +# +# If this setting is set, MPD will require password authorization. The password +# can setting can be specified multiple times for different password profiles. +# +#password "password@read,add,control,admin" +# +# This setting specifies the permissions a user has who has not yet logged in. +# +#default_permissions "read,add,control,admin" +# +############################################################################### + + +# Input ####################################################################### +# + +#input { +# plugin "curl" +# proxy "proxy.isp.com:8080" +# proxy_user "user" +# proxy_password "password" +#} + +# +############################################################################### + +# Audio Output ################################################################ +# +# MPD supports various audio output types, as well as playing through multiple +# audio outputs at the same time, through multiple audio_output settings +# blocks. Setting this block is optional, though the server will only attempt +# autodetection for one sound card. +# +# See <http://mpd.wikia.com/wiki/Configuration#Audio_Outputs> for examples of +# other audio outputs. +# +# board specific examples ##################################################### +# (feel free to add futher) +# +# gumstix overo (tested with TOBI expansion board) +#audio_output { +# type "alsa" +# name "overo" +# mixer_control "Headset" +# mixer_index "0" +#} + +audio_output { + type "pipewire" + name "AGL PipeWire" +} + +# general examples ############################################################ +# +# An example of an ALSA output: +# +#audio_output { +# type "alsa" +# name "My ALSA Device" +## device "hw:0,0" # optional +## format "44100:16:2" # optional +## mixer_type "hardware" # optional +## mixer_device "default" # optional +## mixer_control "PCM" # optional +## mixer_index "0" # optional +#} +# +# An example of an OSS output: +# +#audio_output { +# type "oss" +# name "My OSS Device" +## device "/dev/dsp" # optional +## format "44100:16:2" # optional +## mixer_type "hardware" # optional +## mixer_device "/dev/mixer" # optional +## mixer_control "PCM" # optional +#} +# +# An example of a shout output (for streaming to Icecast): +# +#audio_output { +# type "shout" +# encoding "ogg" # optional +# name "My Shout Stream" +# host "localhost" +# port "8000" +# mount "/mpd.ogg" +# password "hackme" +# quality "5.0" +# bitrate "128" +# format "44100:16:1" +## protocol "icecast2" # optional +## user "source" # optional +## description "My Stream Description" # optional +## genre "jazz" # optional +## public "no" # optional +## timeout "2" # optional +## mixer_type "software" # optional +#} +# +# An example of a recorder output: +# +#audio_output { +# type "recorder" +# name "My recorder" +# encoder "vorbis" # optional, vorbis or lame +# path "/var/lib/mpd/recorder/mpd.ogg" +## quality "5.0" # do not define if bitrate is defined +# bitrate "128" # do not define if quality is defined +# format "44100:16:1" +#} +# +# An example of a httpd output (built-in HTTP streaming server): +# +#audio_output { +# type "httpd" +# name "My HTTP Stream" +# encoder "vorbis" # optional, vorbis or lame +# port "8000" +# bind_to_address "0.0.0.0" # optional, IPv4 or IPv6 +## quality "5.0" # do not define if bitrate is defined +# bitrate "128" # do not define if quality is defined +# format "44100:16:1" +# max_clients "0" # optional 0=no limit +#} +# +# An example of a pulseaudio output (streaming to a remote pulseaudio server) +# +#audio_output { +# type "pulse" +# name "My Pulse Output" +## server "remote_server" # optional +## sink "remote_server_sink" # optional +#} +# +## Example "pipe" output: +# +#audio_output { +# type "pipe" +# name "my pipe" +# command "aplay -f cd 2>/dev/null" +## Or if you're want to use AudioCompress +# command "AudioCompress -m | aplay -f cd 2>/dev/null" +## Or to send raw PCM stream through PCM: +# command "nc example.org 8765" +# format "44100:16:2" +#} +# +## An example of a null output (for no audio output): +# +#audio_output { +# type "null" +# name "My Null Output" +# mixer_type "none" # optional +#} +# +# This setting will change all decoded audio to be converted to the specified +# format before being passed to the audio outputs. By default, this setting is +# disabled. +# +#audio_output_format "44100:16:2" +# +# If MPD has been compiled with libsamplerate support, this setting specifies +# the sample rate converter to use. Possible values can be found in the +# mpd.conf man page or the libsamplerate documentation. By default, this is +# setting is disabled. +# +#samplerate_converter "Fastest Sinc Interpolator" +# +############################################################################### + + +# Normalization automatic volume adjustments ################################## +# +# This setting specifies the type of ReplayGain to use. This setting can have +# the argument "off", "album" or "track". See <http://www.replaygain.org> +# for more details. This setting is off by default. +# +#replaygain "album" +# +# This setting sets the pre-amp used for files that have ReplayGain tags. By +# default this setting is disabled. +# +#replaygain_preamp "0" +# +# This setting enables on-the-fly normalization volume adjustment. This will +# result in the volume of all playing audio to be adjusted so the output has +# equal "loudness". This setting is disabled by default. +# +#volume_normalization "no" +# +############################################################################### + + +# MPD Internal Buffering ###################################################### +# +# This setting adjusts the size of internal decoded audio buffering. Changing +# this may have undesired effects. Don't change this if you don't know what you +# are doing. +# +#audio_buffer_size "2048" +# +# This setting controls the percentage of the buffer which is filled before +# beginning to play. Increasing this reduces the chance of audio file skipping, +# at the cost of increased time prior to audio playback. +# +#buffer_before_play "10%" +# +############################################################################### + + +# Resource Limitations ######################################################## +# +# These settings are various limitations to prevent MPD from using too many +# resources. Generally, these settings should be minimized to prevent security +# risks, depending on the operating resources. +# +connection_timeout "120" +#max_connections "10" +#max_playlist_length "16384" +#max_command_list_size "2048" +#max_output_buffer_size "8192" +# +############################################################################### + + +# Character Encoding ########################################################## +# +# If file or directory names do not display correctly for your locale then you +# may need to modify this setting. +# +#filesystem_charset "UTF-8" +# +# This setting controls the encoding that ID3v1 tags should be converted from. +# +#id3v1_encoding "ISO-8859-1" +# +############################################################################### + + +# SIDPlay decoder ############################################################# +# +# songlength_database: +# Location of your songlengths file, as distributed with the HVSC. +# The sidplay plugin checks this for matching MD5 fingerprints. +# See http://www.c64.org/HVSC/DOCUMENTS/Songlengths.faq +# +# default_songlength: +# This is the default playing time in seconds for songs not in the +# songlength database, or in case you're not using a database. +# A value of 0 means play indefinitely. +# +# filter: +# Turns the SID filter emulation on or off. +# +#decoder { +# plugin "sidplay" +# songlength_database "/media/C64Music/DOCUMENTS/Songlengths.txt" +# default_songlength "120" +# filter "true" +#} +# +############################################################################### + diff --git a/recipes-multimedia/musicpd/mpd_0.23.%.bbappend b/recipes-multimedia/musicpd/mpd_0.23.%.bbappend new file mode 100644 index 00000000..5377a54c --- /dev/null +++ b/recipes-multimedia/musicpd/mpd_0.23.%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'mpd_agldemo.inc', '', d)} diff --git a/recipes-multimedia/musicpd/mpd_agldemo.inc b/recipes-multimedia/musicpd/mpd_agldemo.inc new file mode 100644 index 00000000..513aa509 --- /dev/null +++ b/recipes-multimedia/musicpd/mpd_agldemo.inc @@ -0,0 +1,50 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +# Remove curl dependency to disable WebDAV support. +# Ideally this should be addressed by adding a PACKAGECONFIG option +# in the upstream recipe. +DEPENDS:remove = "curl" + +SRC_URI += "file://mpd-volatiles.conf" + +# This also needs to be pushed upstream. +PACKAGECONFIG[pipewire] = "-Dpipewire=enabled,-Dpipewire=disabled,pipewire" + +# Prune the default configuration a bit to remove various streaming/server +# options that are not required. +PACKAGECONFIG = " \ + ${@bb.utils.contains("LICENSE_FLAGS_ACCEPTED", "commercial", "aac", "", d)} \ + bzip2 \ + daemon \ + ${@bb.utils.contains("LICENSE_FLAGS_ACCEPTED", "commercial", "ffmpeg aac", "", d)} \ + flac \ + libsamplerate \ + mpg123 \ + sndfile \ + opus \ + vorbis \ + wavpack \ + zlib \ + pipewire \ + id3tag \ +" + +SYSTEMD_AUTO_ENABLE = "enable" + +# Override default as AGL's PipeWire configuration does not make use of audio +# group. As opposed to using the group setting in mpd.conf, this keeps the +# files created in /var/lib/mpd as mpd.mpd, which seems safer. +USERADD_PARAM:${PN} = " \ + --system --no-create-home \ + --home ${localstatedir}/lib/mpd \ + --groups pipewire \ + --user-group mpd" + +# Install volatile redirect for /var/lib/mpd to avoid any chance of metadata +# corruption on reboot. This matches what as previously done with the +# lightmediascanner configuration. +do_install:append() { + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + install -D -m 0644 ${WORKDIR}/mpd-volatiles.conf ${D}${sysconfdir}/tmpfiles.d/mpd.conf + fi +} diff --git a/recipes-multimedia/openjtalk/openjtalk-voicedata_1.6.bb b/recipes-multimedia/openjtalk/openjtalk-voicedata_1.6.bb index 27ef7b57..f4e6a8d4 100644 --- a/recipes-multimedia/openjtalk/openjtalk-voicedata_1.6.bb +++ b/recipes-multimedia/openjtalk/openjtalk-voicedata_1.6.bb @@ -19,4 +19,4 @@ do_install() { install -m 0644 -p ${S}/Voice/mei/*.htsvoice ${D}/${datadir}/Voice/mei/ } -FILES_${PN} += " ${datadir}/Voice/mei/*.htsvoice " +FILES:${PN} += " ${datadir}/Voice/mei/*.htsvoice " diff --git a/recipes-multimedia/openjtalk/openjtalk_1.09.bb b/recipes-multimedia/openjtalk/openjtalk_1.09.bb index 5ac0771a..a5f73139 100644 --- a/recipes-multimedia/openjtalk/openjtalk_1.09.bb +++ b/recipes-multimedia/openjtalk/openjtalk_1.09.bb @@ -1,7 +1,7 @@ SUMMARY = "Open JTalk is a Japanese text-to-speech system." HOMEPAGE = "http://open-jtalk.sourceforge.net/" SECTION = "libs" -LICENSE = "BSD" +LICENSE = "BSD-3-Clause" LIC_FILES_CHKSUM = "file://COPYING;md5=ec9073c0ca40ff7c388b31cfd6a07a9e" @@ -12,7 +12,7 @@ SRC_URI = "\ file://fix-mecab-tool.patch \ " -SRC_URI_class-native = "\ +SRC_URI:class-native = "\ http://downloads.sourceforge.net/open-jtalk/open_jtalk-${PV}.tar.gz \ " @@ -21,10 +21,10 @@ SRC_URI[md5sum] = "5dfdbad432d892f044fb96129a524bfe" SRC_URI[sha256sum] = "8ed79238d825fee1d9e0a1c6c8a89e2cc707189be1caa3fa79e8eb72436079d7" DEPENDS = " hts-engine openjtalk-native " -DEPENDS_class-native = " hts-engine-native " +DEPENDS:class-native = " hts-engine-native " -RDEPENDS_${PN} = " openjtalk-voicedata " -RDEPENDS_${PN}_class-native = " " +RDEPENDS:${PN} = " openjtalk-voicedata " +RDEPENDS:${PN}:class-native = " " inherit autotools-brokensep @@ -36,14 +36,14 @@ EXTRA_OECONF = " \ --with-hts-engine-library-path=${PKG_CONFIG_SYSROOT_DIR}/usr/lib \ " -EXTRA_OECONF_class-native = " \ +EXTRA_OECONF:class-native = " \ --with-hts-engine-header-path=${includedir} \ --with-hts-engine-library-path=${libdir} \ " -do_install_append_class-native() { +do_install:append:class-native() { install -m 755 mecab/src/mecab-dict-index ${D}${bindir} } -FILES_${PN} += " ${datadir}/dic/* " +FILES:${PN} += " ${datadir}/dic/* " diff --git a/recipes-multimedia/wireplumber/files/30-v4l2-monitor.lua b/recipes-multimedia/wireplumber/files/30-v4l2-monitor.lua new file mode 100644 index 00000000..39438623 --- /dev/null +++ b/recipes-multimedia/wireplumber/files/30-v4l2-monitor.lua @@ -0,0 +1,59 @@ +-- V4L2 monitor config file; with selecting by default USB camera -- + +v4l2_monitor = {} +v4l2_monitor.properties = {} + +v4l2_monitor.rules = { + -- An array of matches/actions to evaluate. + { + -- Rules for matching a device or node. It is an array of + -- properties that all need to match the regexp. If any of the + -- matches work, the actions are executed for the object. + matches = { + { + -- This matches all cards. + { "device.name", "matches", "v4l2_device.*" }, + }, + }, + -- Apply properties on the matched object. + apply_properties = { + -- ["device.nick"] = "My Device", + }, + }, + { + matches = { + { + -- Matches all sources. + { "node.name", "matches", "v4l2_input.*" }, + }, + { + -- Matches all sinks. + { "node.name", "matches", "v4l2_output.*" }, + }, + }, + apply_properties = { + --["node.nick"] = "My Node", + --["priority.driver"] = 100, + --["priority.session"] = 100, + --["node.pause-on-idle"] = false, + }, + }, + { + matches = { + { + { "node.name", "matches", "v4l2_input*usb*" }, + }, + }, + apply_properties = { + ["priority.driver"] = 1300, + ["priority.session"] = 1300, + }, + }, +} + +function v4l2_monitor.enable() + load_monitor("v4l2", { + properties = v4l2_monitor.properties, + rules = v4l2_monitor.rules, + }) +end diff --git a/recipes-multimedia/wireplumber/wireplumber-config-agl_%.bbappend b/recipes-multimedia/wireplumber/wireplumber-config-agl_%.bbappend new file mode 100644 index 00000000..8f93868d --- /dev/null +++ b/recipes-multimedia/wireplumber/wireplumber-config-agl_%.bbappend @@ -0,0 +1,10 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI += "file://30-v4l2-monitor.lua" + +do_install:append() { + # override the one from meta-agl to be able to set as default USB camera + # such that camera-gstreamer and implicitly pipewire work out of the box + install -D -m 0644 ${WORKDIR}/30-v4l2-monitor.lua ${D}${sysconfdir}/wireplumber/host.lua.d/ +} + diff --git a/recipes-navigation/geoclue/files/geoclue.conf.agl b/recipes-navigation/geoclue/files/geoclue.conf.agl new file mode 100644 index 00000000..420eacd9 --- /dev/null +++ b/recipes-navigation/geoclue/files/geoclue.conf.agl @@ -0,0 +1,103 @@ +# Configuration file for Geoclue +# +# NOTE: All configurations settings below are mandatory and the defaults are +# what you see before you edit them. If you want to keep the default +# values around, copy and comment out the appropriate line(s) before +# changing them. + +# Agent configuration options +[agent] + +# Whitelist of desktop IDs (without .desktop part) of all agents we recognise, +# separated by a ';'. +whitelist= + +# Network NMEA source configuration options +[network-nmea] + +# Fetch location from NMEA sources on local network? +enable=true + +# 3G source configuration options +[3g] + +# Enable 3G source +enable=true + +# CDMA source configuration options +[cdma] + +# Enable CDMA source +enable=true + +# Modem GPS source configuration options +[modem-gps] + +# Enable Modem-GPS source +enable=true + +# WiFi source configuration options +[wifi] + +# Enable WiFi source +enable=true + +# URL to the wifi geolocation service. The key can currenty be anything, just +# needs to be present but that is likely going to change in future. +url=https://location.services.mozilla.com/v1/geolocate?key=geoclue + +# To use the Google geolocation service instead of mozilla's, simply uncomment +# this url while changing API_KEY to your Google API key and comment out or +# remove the url above. +# +# WARNING: Please make sure that you are complying with the Google's ToS and +# policies if you uncomment this: +# +# https://developers.google.com/maps/documentation/geolocation/policies +# +#url=https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_KEY + +# Submit data to Mozilla Location Service +# If set to true, geoclue will automatically submit network data to Mozilla +# each time it gets a GPS lock. +# +submit-data=false + +# URL to submission API of Mozilla Location Service +submission-url=https://location.services.mozilla.com/v1/submit?key=geoclue + +# A nickname to submit network data with. A nickname must be 2-32 characters long. +submission-nick=geoclue + +# Application configuration options +# +# NOTE: Having an entry here for an application with allowed=true means that +# geoclue will not ask agent to authorize the application. This is to +# ensure that applications with built-in authorization mechanism (e.g web +# browsers) do not have to be bound to agents. +# +# If your application is denied access to location information and your +# operating system doesn't provide any mechanism to change that, it is +# likely a bug in your operation system (or geoclue). The solution is to +# report the issue with all details, rather than adding your application +# to this list. +# +# Format: +# +# # Desktop ID of application without .desktop part +# [random-app] +# +# # Allowed access to location information? +# allowed=true|false +# +# # Is application a system component? +# system=true|false +# +# # List of UIDs of all users for which this application is allowed location +# # info access, separate by ';'. Keep it empty for allowing it for all users. +# users= + +[geoclue-binding] +allowed=true +system=true +users= diff --git a/recipes-navigation/geoclue/geoclue_%.bbappend b/recipes-navigation/geoclue/geoclue_%.bbappend new file mode 100644 index 00000000..eb1eef6b --- /dev/null +++ b/recipes-navigation/geoclue/geoclue_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'geoclue_agldemo.inc', '', d)} diff --git a/recipes-navigation/geoclue/geoclue_agldemo.inc b/recipes-navigation/geoclue/geoclue_agldemo.inc new file mode 100644 index 00000000..14f730ee --- /dev/null +++ b/recipes-navigation/geoclue/geoclue_agldemo.inc @@ -0,0 +1,9 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI += "file://geoclue.conf.agl" + +PACKAGECONFIG = "nmea lib" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/geoclue.conf.agl ${D}${sysconfdir}/geoclue/geoclue.conf +} diff --git a/recipes-navigation/gpsd/gpsd-machine-conf_%.bbappend b/recipes-navigation/gpsd/gpsd-machine-conf_%.bbappend new file mode 100644 index 00000000..77c0ef8a --- /dev/null +++ b/recipes-navigation/gpsd/gpsd-machine-conf_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'gpsd-machine-conf_agldemo.inc', '', d)} diff --git a/recipes-navigation/gpsd/gpsd-machine-conf_agldemo.inc b/recipes-navigation/gpsd/gpsd-machine-conf_agldemo.inc new file mode 100644 index 00000000..f2bca1a6 --- /dev/null +++ b/recipes-navigation/gpsd/gpsd-machine-conf_agldemo.inc @@ -0,0 +1,8 @@ +# Mark package as machine specific, which the upstream stub recipe +# does not do for unclear reasons. +PACKAGE_ARCH = "${MACHINE_ARCH}" + +# Allow an empty package as results from the upstream stub recipe. +# This allows using the package without needing machine specific +# hooks. +ALLOW_EMPTY:${PN} = "1" diff --git a/recipes-navigation/gpsd/gpsd/sw-device-hook b/recipes-navigation/gpsd/gpsd/sw-device-hook new file mode 100644 index 00000000..e1e6f7a4 --- /dev/null +++ b/recipes-navigation/gpsd/gpsd/sw-device-hook @@ -0,0 +1,23 @@ +#!/bin/sh + +# Figure out the parent usb device +USBDEV=`ls -l "$1" |sed -ne 's!^c[^ ]* [0-9]* [^ ]* [^ ]* \([0-9]*\), \([0-9]*\) .*!/sys/dev/char/\1:\2/device/../..!p'` + +# Silently ignore any non-USB ports +if [ ! -r "$USBDEV/idVendor" ] || [ ! -r "$USBDEV/idProduct" ]; then + exit 0 +fi + +VID=`cat "$USBDEV/idVendor"` +PID=`cat "$USBDEV/idProduct"` +case "$2" in + ACTIVATE) CMD=START ;; + *) CMD=STOP ;; +esac + +case "$VID:$PID" in + "1199:9071"|"1199:9079") echo \$GPS_$CMD >"$1" ;; + *) ;; +esac + +exit 0 diff --git a/recipes-navigation/gpsd/gpsd_%.bbappend b/recipes-navigation/gpsd/gpsd_%.bbappend new file mode 100644 index 00000000..ac56bfb8 --- /dev/null +++ b/recipes-navigation/gpsd/gpsd_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'gpsd_agldemo.inc', '', d)} diff --git a/recipes-navigation/gpsd/gpsd_agldemo.inc b/recipes-navigation/gpsd/gpsd_agldemo.inc new file mode 100644 index 00000000..cb26510d --- /dev/null +++ b/recipes-navigation/gpsd/gpsd_agldemo.inc @@ -0,0 +1,10 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/gpsd:" + +SRC_URI += "file://sw-device-hook" + +do_install:append() { + # Install device-hook script for starting NMEA output on Sierra Wireless modems + install -d ${D}${sysconfdir}/gpsd + install -m 0755 ${WORKDIR}/sw-device-hook ${D}${sysconfdir}/gpsd/device-hook +} + diff --git a/recipes-navigation/osmium/osmium_git.bb b/recipes-navigation/osmium/osmium_git.bb deleted file mode 100644 index a7178dbc..00000000 --- a/recipes-navigation/osmium/osmium_git.bb +++ /dev/null @@ -1,18 +0,0 @@ -SUMMARY = "libosmium library" -DESCRIPTION = "Fast and flexible C++ library for working with OpenStreetMap data. " -HOMEPAGE = "http://osmcode.org/libosmium" -SECTION = "apps" - -LICENSE = "BSL-1.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=e4224ccaecb14d942c71d31bef20d78c" - -SRC_URI = "git://github.com/osmcode/libosmium.git;protocol=http" -SRCREV = "28c676054064c6b75204f0981c21fb3e265c9319" - -S = "${WORKDIR}/git" - -EXTRA_OECMAKE += "-DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF" - -DEPENDS = "boost protozero" - -inherit cmake pkgconfig diff --git a/recipes-navigation/osrm-backend/files/0001-cmake-fix-search-paths-for-OE-building.patch b/recipes-navigation/osrm-backend/files/0001-cmake-fix-search-paths-for-OE-building.patch deleted file mode 100644 index 80a7b6f8..00000000 --- a/recipes-navigation/osrm-backend/files/0001-cmake-fix-search-paths-for-OE-building.patch +++ /dev/null @@ -1,36 +0,0 @@ -From a45781fbd39426c0be6d57dcce7ce4679ee63b87 Mon Sep 17 00:00:00 2001 -From: Matt Ranostay <matt.ranostay@konsulko.com> -Date: Fri, 3 Nov 2017 16:53:34 -0700 -Subject: [PATCH] cmake: fix search paths for OE building - -For gcc-6 -isystem breaks #include_next so put recipes -staging include directory before others - -Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> ---- - CMakeLists.txt | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 175791651..c5a214102 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -113,6 +113,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - endif() - endif() - -+include_directories(BEFORE ${STAGING_DIR_HOST}/usr/include/) - include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/) - include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/) - include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sol2/) -@@ -589,7 +590,6 @@ if (ENABLE_STXXL) - endif() - - add_definitions(${OSRM_DEFINES}) --include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS}) - - set(BOOST_BASE_LIBRARIES - ${Boost_DATE_TIME_LIBRARY} --- -2.14.2 - diff --git a/recipes-navigation/osrm-backend/osrm-backend_git.bb b/recipes-navigation/osrm-backend/osrm-backend_git.bb deleted file mode 100644 index be93e210..00000000 --- a/recipes-navigation/osrm-backend/osrm-backend_git.bb +++ /dev/null @@ -1,24 +0,0 @@ -SUMMARY = "Open Source Routing Machine" -DESCRIPTION = "Open Source Routing Machine C++ backend" -HOMEPAGE = "http://map.project-osrm.org" -SECTION = "apps" - -LICENSE = "BSD" -LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=d7862bc7b1d9f5fbeee5657b31075df1" - -SRC_URI = "git://github.com/Project-OSRM/osrm-backend.git;protocol=http \ - file://0001-cmake-fix-search-paths-for-OE-building.patch \ - " - -SRCREV = "5b58445535633eb1d6840ef4e8786ff521622867" - -FILES_${PN} += " \ - ${datadir}/osrm/profiles/*.lua \ - ${datadir}/osrm/profiles/*/*.lua \ - " - -S = "${WORKDIR}/git" - -DEPENDS = "boost bzip2 tbb libzip lua osmium protozero expat" - -inherit cmake pkgconfig diff --git a/recipes-navigation/protozero/protozero_git.bb b/recipes-navigation/protozero/protozero_git.bb deleted file mode 100644 index 3625dcad..00000000 --- a/recipes-navigation/protozero/protozero_git.bb +++ /dev/null @@ -1,20 +0,0 @@ -SUMMARY = "protozero library" -DESCRIPTION = "Minimalist protocol buffer decoder and encoder in C++" - -HOMEPAGE = "https://github.com/mapbox/protozero" -SECTION = "apps" - -LICENSE = "BSD & Apache-2.0" -LIC_FILES_CHKSUM = "\ - file://LICENSE.md;md5=bb1a27fdd409f635a3f92106ef78d30a \ - file://LICENSE.from_folly;md5=2ee41112a44fe7014dce33e26468ba93 \ - " - -SRC_URI = "git://github.com/mapbox/protozero.git;protocol=http" -SRCREV = "aa8b304cf63831589f52c254b5af2c688bdc2fc4" - -S = "${WORKDIR}/git" - -CFLAGS_prepend = " -I${STAGING_DIR_HOST}/include" - -inherit cmake pkgconfig diff --git a/recipes-platform/images/agl-cluster-demo-platform-flutter.bb b/recipes-platform/images/agl-cluster-demo-platform-flutter.bb new file mode 100644 index 00000000..5cf3daf9 --- /dev/null +++ b/recipes-platform/images/agl-cluster-demo-platform-flutter.bb @@ -0,0 +1,37 @@ +SUMMARY = "Baseline Flutter Image for Release" + +LICENSE = "MIT" + +require recipes-platform/images/agl-image-compositor.bb +require agl-demo-features.inc + +IMAGE_FEATURES += "splash package-management ssh-server-openssh" + +# KUKSA.val databroker is not installed with "agl-demo-preload" +# feature enabled, since demo unit configuration points at the +# databroker on the IVI board in that setup. +IMAGE_FEATURES += " \ + kuksa-val-databroker-client \ + ${@bb.utils.contains("AGL_FEATURES", "agl-demo-preload", "", "kuksa-val-databroker", d)} \ +" + +# Generic +IMAGE_INSTALL += "\ + ${@bb.utils.contains("AGL_FEATURES", "agl-demo-preload", "psplash-inverted-config", "", d)} \ + ${@bb.utils.contains("AGL_FEATURES", "agl-demo-preload", "weston-ini-conf-landscape-inverted", "weston-ini-conf-landscape", d)} \ + \ + packagegroup-agl-networking \ + cluster-receiver \ + \ + simple-can-simulator \ + " + +# Flutter +IMAGE_INSTALL += "\ + flutter-cluster-dashboard \ + ${@bb.utils.contains("AGL_FEATURES", "agl-demo-preload", "flutter-cluster-dashboard-conf-demo", "flutter-cluster-dashboard-conf", d)} \ + cluster-demo-config-flutter \ + flutter-auto \ + " + +CLANGSDK = "1" diff --git a/recipes-platform/images/agl-cluster-demo-platform.bb b/recipes-platform/images/agl-cluster-demo-platform.bb new file mode 100644 index 00000000..c427af66 --- /dev/null +++ b/recipes-platform/images/agl-cluster-demo-platform.bb @@ -0,0 +1,29 @@ +DESCRIPTION = "AGL Cluster Demo Platform image currently contains a simple cluster interface." + +LICENSE = "MIT" + +require recipes-platform/images/agl-image-compositor.bb +require agl-demo-features.inc + +IMAGE_FEATURES += "splash package-management ssh-server-openssh" + +inherit features_check + +REQUIRED_DISTRO_FEATURES = "wayland" + +# KUKSA.val databroker is not installed with "agl-demo-preload" +# feature enabled, since demo unit configuration points at the +# databroker on the IVI board in that setup. +IMAGE_FEATURES += " \ + kuksa-val-databroker-client \ + ${@bb.utils.contains("AGL_FEATURES", "agl-demo-preload", "", "kuksa-val-databroker", d)} \ +" + +# add packages for cluster demo platform (include demo apps) here +IMAGE_INSTALL += " \ + packagegroup-agl-cluster-demo-platform \ + kuksa-certificates-agl-ca \ + ${@bb.utils.contains("AGL_FEATURES", "agl-demo-preload", "cluster-demo-config", "", d)} \ + ${@bb.utils.contains("AGL_FEATURES", "agl-demo-preload", "weston-ini-conf-landscape-inverted", "weston-ini-conf-landscape", d)} \ + ${@bb.utils.contains("AGL_FEATURES", "AGLCI", "qemu-set-display", "", d)} \ + " diff --git a/recipes-platform/images/agl-cluster-demo-qtcompositor.bb b/recipes-platform/images/agl-cluster-demo-qtcompositor.bb new file mode 100644 index 00000000..69dee2df --- /dev/null +++ b/recipes-platform/images/agl-cluster-demo-qtcompositor.bb @@ -0,0 +1,11 @@ +DESCRIPTION = "AGL Cluster Demo Qtwayland Compositor image currently contains a \ +simple cluster interface." + +LICENSE = "MIT" + +require recipes-platform/images/agl-image-weston.bb + +IMAGE_FEATURES += "splash package-management ssh-server-dropbear" + +# Add packages for qtcompositor demo +IMAGE_INSTALL += "cluster-gauges-qtcompositor" diff --git a/recipes-platform/images/agl-demo-container-guest-integration.inc b/recipes-platform/images/agl-demo-container-guest-integration.inc new file mode 100644 index 00000000..f835761f --- /dev/null +++ b/recipes-platform/images/agl-demo-container-guest-integration.inc @@ -0,0 +1,18 @@ +IMAGE_CONTAINER_GUEST_APPEND = " base-files-guest-fstab" +IMAGE_INSTALL:append = " \ + ${@bb.utils.contains('AGL_FEATURES', 'agl-container-guest-demo', '${IMAGE_CONTAINER_GUEST_APPEND}', '', d)} \ +" + +fixupfstab_for_container_guest_images() { + rm -f ${IMAGE_ROOTFS}/${sysconfdir}/fstab + ln -s fstab-guest ${IMAGE_ROOTFS}/${sysconfdir}/fstab +} + +rmboot_for_container_guest_images() { + rm -rf ${IMAGE_ROOTFS}/boot +} + +ROOTFS_POSTPROCESS_COMMAND += " \ + ${@bb.utils.contains('AGL_FEATURES', 'agl-container-guest-demo', 'fixupfstab_for_container_guest_images;', '', d)} \ + ${@bb.utils.contains('AGL_FEATURES', 'agl-container-guest-demo', 'rmboot_for_container_guest_images;', '', d)} \ +" diff --git a/recipes-platform/images/agl-demo-features.inc b/recipes-platform/images/agl-demo-features.inc new file mode 100644 index 00000000..a8112c83 --- /dev/null +++ b/recipes-platform/images/agl-demo-features.inc @@ -0,0 +1,10 @@ +FEATURE_PACKAGES_can-test-tools = " \ + can-utils \ + cannelloni \ +" + +FEATURE_PACKAGES_kuksa-val-databroker-client = " \ + kuksa-certificates-agl-ca \ + ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'packagegroup-agl-kuksa-val-databroker-devel' , '', d)} \ +" +FEATURE_PACKAGES_kuksa-val-databroker = "packagegroup-agl-kuksa-val-databroker" diff --git a/recipes-platform/images/agl-demo-platform-crosssdk.bb b/recipes-platform/images/agl-demo-platform-crosssdk.bb index a814b694..70daba00 100755..120000 --- a/recipes-platform/images/agl-demo-platform-crosssdk.bb +++ b/recipes-platform/images/agl-demo-platform-crosssdk.bb @@ -1,81 +1 @@ -SUMMARY = "Cross SDK of Full AGL Distribution for IVI profile" - -DESCRIPTION = "SDK image for full AGL Distribution for IVI profile. \ -It includes the full meta-toolchain, plus developement headers and libraries \ -to form a standalone cross SDK." - -require agl-demo-platform.bb - -LICENSE = "MIT" - -IMAGE_FEATURES_append = " dev-pkgs" -IMAGE_INSTALL_append = " kernel-dev kernel-devsrc" - -inherit populate_sdk populate_sdk_qt5 - -# Task do_populate_sdk and do_rootfs can't be exec simultaneously. -# Both exec "createrepo" on the same directory, and so one of them -# can failed (randomly). -addtask do_populate_sdk after do_rootfs - -# native tools to support Chromium build inside SDK (SPEC-942) -TOOLCHAIN_HOST_TASK += " \ - nativesdk-gn \ - nativesdk-ninja \ - nativesdk-gperf \ - nativesdk-zlib \ - nativesdk-xz \ - nativesdk-nspr-dev \ - nativesdk-nss-dev \ - nativesdk-lua \ - " - -# required dependencies for Chromium build inside SDK (SPEC-942) -TOOLCHAIN_TARGET_TASK += " \ - pciutils-dev \ - ${@bb.utils.contains('DISTRO_FEATURES', 'pulseaudio', 'pulseaudio-dev' , '', d)} \ - cairo-dev \ - nss-dev \ - cups-dev \ - gconf-dev \ - libexif-dev \ - pango-dev \ - libdrm-dev \ - lua-dev \ - lua-staticdev \ - libafb-helpers-staticdev \ - libafb-helpers-qt-staticdev \ - libappcontroller-staticdev \ - ${@bb.utils.contains('LICENSE_FLAGS_WHITELIST', 'commercial', 'ffmpeg-dev', '', d)} \ - " - -# Add wayland-scanner to SDK (SPEC-945) -# Use TOOLCHAIN_HOST_TASK instead of adding to the packagegroup -# wayland-scanner is in nativesdk-wayland-dev ! -# option: add also nativesdk-qtwayland-tools -TOOLCHAIN_HOST_TASK_append = " nativesdk-wayland nativesdk-wayland-dev" - -TOOLCHAIN_HOST_TASK_append = " nativesdk-perl-modules " - -# Add mosquitto to support building the telematics demo application. -# This is currently required for CI, as it uses agl-demo-platform-crosssdk -# to build everything. An agenda item has been tabled for the May 2019 F2F -# meeting to discuss the path forward (separate versus superset SDKs), this -# should be reviewed after that. -TOOLCHAIN_TARGET_TASK += "mosquitto-dev" - -# Add nlohmann-json to support building the speech services. -# Required until either the agl-speech-framework feature is added as a -# dependency of agl-demo, or the speech services are migrated into the -# core profile. -TOOLCHAIN_TARGET_TASK += "nlohmann-json-dev" - -# Add libstdc++-staticdev to support building agl-service-voice-high or -# other users of the C++17 filesystem standard library feature. -# Can be removed upon upgrade to gcc 9.x, as it will no longer be necessary. -TOOLCHAIN_TARGET_TASK += "libstdc++-staticdev" - -# Add gcc-sanitizers to support building applications using the SDK with -# AddressSanitizer support to detect use-after-frees along with other -# memory issue. -TOOLCHAIN_TARGET_TASK += "gcc-sanitizers" +agl-ivi-demo-platform-crosssdk.bb
\ No newline at end of file diff --git a/recipes-platform/images/agl-demo-platform-html5.bb b/recipes-platform/images/agl-demo-platform-html5.bb index 2d3490fd..fabf5e35 100644..120000 --- a/recipes-platform/images/agl-demo-platform-html5.bb +++ b/recipes-platform/images/agl-demo-platform-html5.bb @@ -1,14 +1 @@ -SUMMARY = "DEMO platform of AGL HTML5 profile" -DESCRIPTION = "Contains the web runtime and sample web apps" - -require agl-demo-platform.inc - -LICENSE = "MIT" - -IMAGE_FEATURES_append = " \ - " - -# add packages for demo platform (include demo apps) here -IMAGE_INSTALL_append = " \ - packagegroup-agl-demo-platform-html5 \ - " +agl-ivi-demo-platform-html5.bb
\ No newline at end of file diff --git a/recipes-platform/images/agl-demo-platform-qa.bb b/recipes-platform/images/agl-demo-platform-qa.bb deleted file mode 100644 index fa3f717d..00000000 --- a/recipes-platform/images/agl-demo-platform-qa.bb +++ /dev/null @@ -1,13 +0,0 @@ -SUMMARY = "A full set of AGL Distribution for testing as Quality Assurance" - -DESCRIPTION = "A full set of AGL Distribution. This image also has additional \ -packages (e.g. commandline tools) for Quality Assurance(QA)." - -LICENSE = "MIT" - -require agl-demo-platform.bb - -IMAGE_INSTALL_append = " \ - packagegroup-ivi-common-test \ - packagegroup-agl-demo-platform-qa \ - " diff --git a/recipes-platform/images/agl-demo-platform.bb b/recipes-platform/images/agl-demo-platform.bb index 297cb706..ff29cf3e 100644..120000 --- a/recipes-platform/images/agl-demo-platform.bb +++ b/recipes-platform/images/agl-demo-platform.bb @@ -1,15 +1 @@ -DESCRIPTION = "AGL Demo Platform image currently contains a simple HMI and \ -demos." - -require agl-demo-platform.inc - -LICENSE = "MIT" - -IMAGE_FEATURES_append = " \ - " - -# add packages for demo platform (include demo apps) here -IMAGE_INSTALL_append = " \ - packagegroup-agl-demo-platform \ - " - +agl-ivi-demo-platform.bb
\ No newline at end of file diff --git a/recipes-platform/images/agl-demo-platform.inc b/recipes-platform/images/agl-demo-platform.inc deleted file mode 100644 index 203fcc07..00000000 --- a/recipes-platform/images/agl-demo-platform.inc +++ /dev/null @@ -1,3 +0,0 @@ -# Base image -require recipes-platform/images/agl-image-ivi.inc - diff --git a/recipes-platform/images/agl-image-ivi-crosssdk.bb b/recipes-platform/images/agl-image-ivi-crosssdk.bb index 93537feb..be008832 100644 --- a/recipes-platform/images/agl-image-ivi-crosssdk.bb +++ b/recipes-platform/images/agl-image-ivi-crosssdk.bb @@ -1,2 +1,11 @@ -# just for backward compatibility -require recipes-platform/images/agl-image-minimal-crosssdk.bb +require agl-image-ivi.bb + +SUMMARY = "Cross SDK of minimal AGL Distribution for IVI profile" + +DESCRIPTION = "SDK image for minimal AGL Distribution for IVI profile. \ +It includes the full toolchain, plus development headers and libraries \ +to form a standalone cross SDK." + +inherit agl-crosssdk + +require agl-ivi-crosssdk.inc diff --git a/recipes-platform/images/agl-image-ivi-qa.bb b/recipes-platform/images/agl-image-ivi-qa.bb deleted file mode 100644 index 01743945..00000000 --- a/recipes-platform/images/agl-image-ivi-qa.bb +++ /dev/null @@ -1,14 +0,0 @@ -SUMMARY = "A basic system of AGL distribution of IVI profile for Quality Assurance(QA)" - -DESCRIPTION = "A basic set of AGL Distribution. This image also has additional \ -packages (e.g. commandline tools) for Quality Assurance(QA)." - -require agl-image-ivi.bb - -LICENSE = "MIT" - -IMAGE_INSTALL_append = " \ - packagegroup-agl-test \ - packagegroup-ivi-common-test \ - " - diff --git a/recipes-platform/images/agl-image-ivi.bb b/recipes-platform/images/agl-image-ivi.bb index dd4f89b1..69d0ed99 100644 --- a/recipes-platform/images/agl-image-ivi.bb +++ b/recipes-platform/images/agl-image-ivi.bb @@ -2,16 +2,22 @@ SUMMARY = "A basic system of AGL distribution of IVI profile" DESCRIPTION = "Basic image for baseline of AGL Distribution for IVI profile." -require agl-image-ivi.inc - LICENSE = "MIT" -IMAGE_INSTALL_append = "\ - packagegroup-agl-image-ivi \ +require recipes-platform/images/agl-image-compositor.bb + +IMAGE_INSTALL += " \ + packagegroup-agl-ivi-connectivity \ + packagegroup-agl-ivi-graphics \ + packagegroup-agl-ivi-multimedia \ + packagegroup-agl-ivi-multimedia-hardware \ + packagegroup-agl-ivi-navigation \ + packagegroup-agl-ivi-identity \ + packagegroup-agl-ivi-services-applaunchd \ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-audio", "", "packagegroup-agl-ivi-services-platform", d)} \ + iproute2 \ " -DISTRO_FEATURES_append = " agl-core-image-profile" +IMAGE_FEATURES += "splash package-management ssh-server-openssh" + -IMAGE_INSTALL += "\ - agl-desktop-config \ - " diff --git a/recipes-platform/images/agl-image-ivi.inc b/recipes-platform/images/agl-image-ivi.inc deleted file mode 100644 index 610d4e46..00000000 --- a/recipes-platform/images/agl-image-ivi.inc +++ /dev/null @@ -1,3 +0,0 @@ -require recipes-platform/images/agl-image-minimal.inc - -IMAGE_FEATURES += "splash package-management ssh-server-dropbear" diff --git a/recipes-platform/images/agl-ivi-crosssdk.inc b/recipes-platform/images/agl-ivi-crosssdk.inc new file mode 100644 index 00000000..f9f99d8d --- /dev/null +++ b/recipes-platform/images/agl-ivi-crosssdk.inc @@ -0,0 +1,24 @@ +# +# Common IVI SDK configuration +# +# Only host tool additions should done here +# + +# Add wayland-scanner to SDK (SPEC-945) +# Use TOOLCHAIN_HOST_TASK instead of adding to the packagegroup +# wayland-scanner is in nativesdk-wayland-dev ! +# option: add also nativesdk-qtwayland-tools +TOOLCHAIN_HOST_TASK += "nativesdk-wayland nativesdk-wayland-dev" + +TOOLCHAIN_HOST_TASK += "nativesdk-perl-modules" + +# add grpc for building natively for grpc_cpp_plugin +TOOLCHAIN_HOST_TASK += "nativesdk-grpc nativesdk-grpc-dev" + +# Add gcc-sanitizers to support building applications using the SDK with +# AddressSanitizer support to detect use-after-frees along with other +# memory issue. +TOOLCHAIN_SANITIZERS_TASKS = "gcc-sanitizers" +# gcc-sanitizers is currently (scarthgap) not supported on RISC-V +TOOLCHAIN_SANITIZERS_TASKS:riscv64 = "" +TOOLCHAIN_TARGET_TASK += "${TOOLCHAIN_SANITIZERS_TASKS}" diff --git a/recipes-platform/images/agl-ivi-demo-base-flutter.bb b/recipes-platform/images/agl-ivi-demo-base-flutter.bb new file mode 100644 index 00000000..ce2ea6bb --- /dev/null +++ b/recipes-platform/images/agl-ivi-demo-base-flutter.bb @@ -0,0 +1,8 @@ +require agl-ivi-demo-base.bb + +DESCRIPTION = "AGL Flutter demo base image" + +IMAGE_INSTALL += " \ + packagegroup-agl-demo-platform-flutter \ + ${@bb.utils.contains("AGL_FEATURES", "agl-demo-preload", "", "weston-terminal-conf", d)} \ +" diff --git a/recipes-platform/images/agl-ivi-demo-base.bb b/recipes-platform/images/agl-ivi-demo-base.bb new file mode 100644 index 00000000..da4d2684 --- /dev/null +++ b/recipes-platform/images/agl-ivi-demo-base.bb @@ -0,0 +1,19 @@ +require agl-image-ivi.bb + +DESCRIPTION = "AGL demo base image" + +require agl-ivi-demo-features.inc +require agl-demo-container-guest-integration.inc + +AGL_DEVEL_INSTALL += "\ + simple-can-simulator \ + unzip \ + mpc \ +" + +AGL_APPS_INSTALL = "" + +IMAGE_INSTALL += " \ + ${AGL_APPS_INSTALL} \ + ${@bb.utils.contains("DISTRO_FEATURES", "agl-devel", "${AGL_DEVEL_INSTALL}" , "", d)} \ +" diff --git a/recipes-platform/images/agl-ivi-demo-control-panel.bb b/recipes-platform/images/agl-ivi-demo-control-panel.bb new file mode 100644 index 00000000..21785cae --- /dev/null +++ b/recipes-platform/images/agl-ivi-demo-control-panel.bb @@ -0,0 +1,27 @@ +require recipes-platform/images/agl-image-weston.bb + +SUMMARY = "AGL demo control panel image" + +IMAGE_FEATURES += "splash package-management ssh-server-openssh" + +# NOTE: The client key and certificate in kuksa-certificates-agl-client +# seem required by kuksa-client at the moment even though client +# certification has been deprecated upstream, this needs further +# investigation so it can be dropped from the image. +# +IMAGE_KUKSA_PACKAGES = " \ + kuksa-client \ + kuksa-certificates-agl-ca \ + kuksa-certificates-agl-client \ +" + +IMAGE_INSTALL += "\ + packagegroup-agl-networking \ + weston-ini-conf-landscape \ + weston-agl-driver-conf \ + ${IMAGE_KUKSA_PACKAGES} \ + agl-demo-control-panel \ + qtwayland \ + qtwayland-plugins \ + qtwayland-qmlplugins \ +" diff --git a/recipes-platform/images/agl-ivi-demo-features.inc b/recipes-platform/images/agl-ivi-demo-features.inc new file mode 100644 index 00000000..9aabaafe --- /dev/null +++ b/recipes-platform/images/agl-ivi-demo-features.inc @@ -0,0 +1,19 @@ +require agl-demo-features.inc + +FEATURE_PACKAGES_agl-demo-preload = "packagegroup-agl-demo-preload" + +FEATURE_PACKAGES_agl-demo-cluster-support = " \ + tbtnavi \ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-kuksa", "tbtnavi-conf-kvm-demo", "tbtnavi-conf", d)} \ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-kuksa", "", "kuksa-databroker-agl-demo-cluster", d)} \ +" + +IMAGE_FEATURES += " \ + ${@bb.utils.contains("DISTRO_FEATURES", "agl-devel", "can-test-tools" , "", d)} \ + ${@bb.utils.filter("AGL_FEATURES", "agl-demo-preload agl-demo-cluster-support", d)} \ +" + +IMAGE_FEATURES += " \ + kuksa-val-databroker-client \ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-kuksa", "", "kuksa-val-databroker", d)} \ +" diff --git a/recipes-platform/images/agl-ivi-demo-platform-crosssdk.bb b/recipes-platform/images/agl-ivi-demo-platform-crosssdk.bb new file mode 100644 index 00000000..c9ed07a0 --- /dev/null +++ b/recipes-platform/images/agl-ivi-demo-platform-crosssdk.bb @@ -0,0 +1,16 @@ +require agl-ivi-demo-platform.bb + +SUMMARY = "Cross SDK of demo AGL Distribution for IVI profile" + +DESCRIPTION = "SDK image for full AGL Distribution for IVI profile. \ +It includes the full toolchain, plus development headers and libraries \ +for everything in the demo platform to form a standalone cross SDK." + +inherit agl-crosssdk + +require agl-ivi-crosssdk.inc + +inherit populate_sdk_qt5 + +# Add qtwaylandscanner to the SDK +TOOLCHAIN_HOST_TASK += "nativesdk-qtwayland-tools" diff --git a/recipes-platform/images/agl-ivi-demo-platform-flutter-simple.bb b/recipes-platform/images/agl-ivi-demo-platform-flutter-simple.bb new file mode 100644 index 00000000..f1932df5 --- /dev/null +++ b/recipes-platform/images/agl-ivi-demo-platform-flutter-simple.bb @@ -0,0 +1,20 @@ +require agl-ivi-demo-base-flutter.bb + +DESCRIPTION = "AGL Flutter Demo Platform image" + +AGL_APPS_INSTALL += " \ + flutter-homescreen \ + flutter-dashboard \ + flutter-hvac \ + ondemandnavi \ + settings \ + mediaplayer \ + messaging \ + phone \ + radio \ +" + +IMAGE_INSTALL += " \ + qtquickcontrols2-agl \ + qtquickcontrols2-agl-style \ +" diff --git a/recipes-platform/images/agl-ivi-demo-platform-flutter.bb b/recipes-platform/images/agl-ivi-demo-platform-flutter.bb new file mode 100644 index 00000000..81a1c804 --- /dev/null +++ b/recipes-platform/images/agl-ivi-demo-platform-flutter.bb @@ -0,0 +1,11 @@ +require agl-ivi-demo-base-flutter.bb + +DESCRIPTION = "AGL Flutter Demo Platform image" + +AGL_APPS_INSTALL += " \ + flutter-ics-homescreen \ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-kuksa", "flutter-ics-homescreen-conf-kvm-demo", "flutter-ics-homescreen-conf", d)} \ + camera-gstreamer \ + ondemandnavi \ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-kuksa", "ondemandnavi-conf-kvm-demo", "ondemandnavi-conf", d)} \ +" diff --git a/recipes-platform/images/agl-ivi-demo-platform-html5.bb b/recipes-platform/images/agl-ivi-demo-platform-html5.bb new file mode 100644 index 00000000..520b443e --- /dev/null +++ b/recipes-platform/images/agl-ivi-demo-platform-html5.bb @@ -0,0 +1,13 @@ +require agl-image-ivi.bb + +SUMMARY = "DEMO platform of AGL HTML5 profile" +DESCRIPTION = "Contains the web runtime and sample web apps" + +require agl-demo-container-guest-integration.inc + +CLANGSDK = "1" + +# add packages for demo platform (include demo apps) here +IMAGE_INSTALL += " \ + packagegroup-agl-demo-platform-html5 \ +" diff --git a/recipes-platform/images/agl-ivi-demo-platform.bb b/recipes-platform/images/agl-ivi-demo-platform.bb new file mode 100644 index 00000000..2854462c --- /dev/null +++ b/recipes-platform/images/agl-ivi-demo-platform.bb @@ -0,0 +1,23 @@ +require agl-ivi-demo-base.bb + +DESCRIPTION = "AGL Qt Demo Platform image" + +AGL_APPS_INSTALL += " \ + dashboard \ + hvac \ + ondemandnavi \ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-kuksa", "ondemandnavi-conf-kvm-demo", "ondemandnavi-conf", d)} \ + settings \ + mediaplayer \ + messaging \ + phone \ + radio \ + window-management-client-grpc \ + camera-gstreamer \ +" + +IMAGE_INSTALL += " \ + packagegroup-agl-demo-platform \ + ${@bb.utils.contains("AGL_FEATURES", "agl-demo-preload", "", "weston-terminal-conf", d)} \ +" + diff --git a/recipes-platform/images/agl-kvm-demo-platform.bb b/recipes-platform/images/agl-kvm-demo-platform.bb new file mode 100644 index 00000000..ddb2ddb4 --- /dev/null +++ b/recipes-platform/images/agl-kvm-demo-platform.bb @@ -0,0 +1,96 @@ +DESCRIPTION = "AGL KVM+QEMU Demo Platform image." + +LICENSE = "MIT" + +require recipes-platform/images/agl-image-compositor.bb +require agl-demo-features.inc + +IMAGE_FEATURES += "splash package-management ssh-server-openssh" + +# If building with "agl-kvm-host-kuksa", the databroker and likely +# some clients run on the host +IMAGE_FEATURES += " \ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-kuksa", "kuksa-val-databroker kuksa-val-databroker-client", "", d)} \ + ${@bb.utils.contains("DISTRO_FEATURES", "agl-devel", "can-test-tools" , "", d)} \ +" + +# Add packages for KVM+QEMU demo platform here +IMAGE_INSTALL += " \ + packagegroup-agl-core-connectivity \ + kernel-image \ + agl-compositor \ + weston-ini-conf-kvm \ + output-udev-conf \ + native-shell-client \ + qemu \ + ${QEMU_GUEST_CONFIGS} \ + util-linux-taskset \ + screen \ + simple-can-simulator \ + alsa-utils \ +" + +# Until virtio sound is workable with QEMU, run the audio using +# services on the host for a better demo experience. At the +# moment, this also includes the HVAC service since it does not +# make sense to try to make things more fine-grained with respect +# to configuration for where things expect to find the databroker. +# It will need to be revisited when virtio-snd, virtio-gpio, etc. +# become feasible to use. +HOST_AUDIO_INSTALL = " \ + packagegroup-agl-ivi-services-platform \ + agl-service-radio-conf-kvm-demo \ + packagegroup-pipewire \ + wireplumber-config-agl \ + wireplumber-policy-config-agl \ + mpd \ + udisks2 \ + ${@bb.utils.contains("DISTRO_FEATURES", "agl-devel", "packagegroup-pipewire-tools mpc" , "", d)} \ +" + +IMAGE_INSTALL += "\ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-kuksa", "kuksa-databroker-agl-demo-cluster", "", d)} \ + ${@bb.utils.contains("AGL_FEATURES", "agl-kvm-host-audio", "${HOST_AUDIO_INSTALL}", "", d)} \ +" + +# Potential size reduction options +#IMAGE_LINGUAS = " " +#NO_RECOMMENDATIONS = "1" + +GUEST_MACHINE ?= "virtio-${TUNE_ARCH}" + +GUEST_VM1_IMAGE ?= "agl-ivi-demo-platform-flutter" +GUEST_VM2_IMAGE ?= "agl-cluster-demo-platform-flutter" + +GUEST_IMAGES ?= "agl-kvm-guest:${GUEST_VM1_IMAGE} agl-kvm-guest:${GUEST_VM2_IMAGE}" + +QEMU_GUEST_CONFIGS ?= "" + +python __anonymous() { + for c in (d.getVar('GUEST_IMAGES') or "").split(): + (mc, image) = c.split(':') + dependency = 'mc::' + mc + ':' + image + ':do_image_complete' + d.appendVarFlag('do_rootfs', 'mcdepends', ' ' + dependency) + + # Assume there is a qemu-config-X package for guest image X + d.appendVar('QEMU_GUEST_CONFIGS', ' ' + 'qemu-config-' + image) +} + +install_guest_images() { + for c in ${GUEST_IMAGES}; do + config=${c%:*} + image=${c#*:} + name=${image} + rm -rf ${IMAGE_ROOTFS}/var/lib/machines/${name} + install -m 0755 -d ${IMAGE_ROOTFS}/var/lib/machines/${name} + src="${TOPDIR}/tmp-${config}/deploy/images/${GUEST_MACHINE}/${image}-${GUEST_MACHINE}.ext4" + bbnote "Installing ${src}" + install -m 0600 ${src} ${IMAGE_ROOTFS}/var/lib/machines/${name}/ + # Placeholder until booting from kernel in VM image is worked out + install -m 0600 ${TOPDIR}/tmp-${config}/deploy/images/${GUEST_MACHINE}/Image-${GUEST_MACHINE}.bin ${IMAGE_ROOTFS}/var/lib/machines/${name}/ + done +} + +ROOTFS_POSTPROCESS_COMMAND += "install_guest_images; " + +IMAGE_ROOTFS_EXTRA_SPACE:append = "${@bb.utils.contains("DISTRO_FEATURES", "systemd", " + 4096", "" ,d)}" diff --git a/recipes-platform/images/agl-telematics-demo-platform.bb b/recipes-platform/images/agl-telematics-demo-platform.bb new file mode 100644 index 00000000..7a113b65 --- /dev/null +++ b/recipes-platform/images/agl-telematics-demo-platform.bb @@ -0,0 +1,13 @@ +DESCRIPTION = "AGL Telematics Demo Platform image." + +LICENSE = "MIT" + +require recipes-platform/images/agl-image-minimal.bb + +inherit features_check + +REQUIRED_DISTRO_FEATURES = "3g" + +IMAGE_INSTALL += " \ + packagegroup-agl-telematics-demo-platform \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-cluster-demo-platform.bb b/recipes-platform/packagegroups/packagegroup-agl-cluster-demo-platform.bb new file mode 100644 index 00000000..4cd03b66 --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-cluster-demo-platform.bb @@ -0,0 +1,29 @@ +SUMMARY = "The software for demo platform of AGL cluster profile" +DESCRIPTION = "A set of packages belong to AGL Cluster Demo Platform" + +LICENSE = "MIT" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-cluster-demo-platform \ + " + +ALLOW_EMPTY:${PN} = "1" + +RDEPENDS:${PN} += "\ + packagegroup-agl-ttf-fonts \ + packagegroup-agl-source-han-sans-ttf-fonts \ + packagegroup-agl-networking \ + " + +AGL_APPS = " \ + cluster-dashboard \ + cluster-receiver \ + qt-cluster-receiver \ + " + +RDEPENDS:${PN}:append = " \ + can-utils \ + ${AGL_APPS} \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-cluster-demo-qtcompositor.bb b/recipes-platform/packagegroups/packagegroup-agl-cluster-demo-qtcompositor.bb new file mode 100644 index 00000000..a5c8b78e --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-cluster-demo-qtcompositor.bb @@ -0,0 +1,32 @@ +SUMMARY = "The software for AGL Cluster Demo Qtwayland Compositor" +DESCRIPTION = "A set of packages belong to AGL Cluster Demo Qtwayland Compositor" + +LICENSE = "MIT" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-cluster-demo-qtcompositor \ + " + +ALLOW_EMPTY:${PN} = "1" + +RDEPENDS:${PN} += "\ + packagegroup-agl-profile-cluster-qtcompositor \ + packagegroup-agl-ttf-fonts \ + packagegroup-agl-networking \ + " + +AGL_SERVICE = " \ + " + +AGL_APPS = " \ + cluster-gauges-qtcompositor \ + " + +RDEPENDS:${PN}:append = " \ + linux-firmware-ralink \ + can-utils \ + ${AGL_SERVICE} \ + ${AGL_APPS} \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-demo-platform-flutter.bb b/recipes-platform/packagegroups/packagegroup-agl-demo-platform-flutter.bb new file mode 100644 index 00000000..3fba1b8c --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-demo-platform-flutter.bb @@ -0,0 +1,23 @@ +SUMMARY = "The software for Flutter Demo platform of AGL IVI profile" +DESCRIPTION = "A set of packages for AGL Flutter Demo Platform" + +LICENSE = "MIT" + +inherit packagegroup + +PROVIDES = "${PACKAGES}" +PACKAGES = "\ + packagegroup-agl-demo-platform-flutter \ + " + +RDEPENDS:${PN} += "\ + packagegroup-agl-demo \ + " + +RDEPENDS:${PN}:append = " \ + agl-compositor \ + flutter-auto \ + agl-flutter-env \ + applaunchd-template-agl-app-flutter \ + psplash-portrait-config \ + " diff --git a/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb b/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb index 6ec717bd..c5a9209b 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb @@ -1,32 +1,43 @@ -SUMMARY = "The software for DEMO platform of AGL HTML5 profile" -DESCRIPTION = "Packages required to demo the HTML5 profile and sample web apps" +SUMMARY = "The software for DEMO platform of AGL IVI profile" +DESCRIPTION = "A set of packages belong to AGL Demo Platform" LICENSE = "MIT" inherit packagegroup +PROVIDES = "${PACKAGES}" PACKAGES = "\ packagegroup-agl-demo-platform-html5 \ " -ALLOW_EMPTY_${PN} = "1" - -RDEPENDS_${PN} += "\ - packagegroup-agl-image-ivi \ - packagegroup-agl-profile-graphical-html5 \ +RDEPENDS:${PN} += "\ packagegroup-agl-demo \ " +# TODO(jdapena): replace this with HTML5 apps. AGL_APPS = " \ - html5-homescreen \ + html5-dashboard \ html5-launcher \ + html5-homescreen \ html5-hvac \ - html5-settings \ - html5-mixer \ html5-mediaplayer \ - html5-dashboard \ + html5-mixer \ + html5-settings \ + html5-aquarium \ + html5-youtube \ + html5-jitsi \ + html5-examples \ " -RDEPENDS_${PN}_append = " \ +RDEPENDS:${PN}:append = " \ + wam \ + weston-ini-conf-landscape-no-activate \ + ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'unzip' , '', d)} \ + qtquickcontrols2-agl \ + qtquickcontrols2-agl-style \ ${AGL_APPS} \ " + +# nss-agl-driver-db is required to connect to kuksa +RDEPENDS:${PN}:append = " nss-agl-driver-db " + diff --git a/recipes-platform/packagegroups/packagegroup-agl-demo-platform-qa.bb b/recipes-platform/packagegroups/packagegroup-agl-demo-platform-qa.bb deleted file mode 100644 index 739f859b..00000000 --- a/recipes-platform/packagegroups/packagegroup-agl-demo-platform-qa.bb +++ /dev/null @@ -1,15 +0,0 @@ -SUMMARY = "The software for DEMO platform of AGL IVI profile" -DESCRIPTION = "A set of packages belong to AGL Demo Platform includes utilities for testing distribution as Quality Assurance" - -LICENSE = "MIT" - -inherit packagegroup - -PACKAGES = "\ - packagegroup-agl-demo-platform-qa \ - " - -ALLOW_EMPTY_${PN} = "1" - -RDEPENDS_${PN} += "\ - " diff --git a/recipes-platform/packagegroups/packagegroup-agl-demo-platform.bb b/recipes-platform/packagegroups/packagegroup-agl-demo-platform.bb index 28777e2b..28f79cf2 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-demo-platform.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-demo-platform.bb @@ -5,86 +5,20 @@ LICENSE = "MIT" inherit packagegroup +PROVIDES = "${PACKAGES}" PACKAGES = "\ packagegroup-agl-demo-platform \ " -ALLOW_EMPTY_${PN} = "1" - -RDEPENDS_${PN} += "\ - packagegroup-agl-image-ivi \ - " - -RDEPENDS_${PN} += "\ - packagegroup-agl-profile-graphical-qt5 \ +RDEPENDS:${PN} += "\ packagegroup-agl-demo \ " - -AGL_APPS = " \ - dashboard \ - hvac \ - mediaplayer \ - virtual/navigation \ - phone \ - poiapp \ - radio \ - settings \ - messaging \ - ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'taskmanager' , '', d)} \ - ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'unzip' , '', d)} \ - low-can-demo \ - virtual/mixer \ - ${@bb.utils.contains('IMAGE_FEATURES', 'agl-voiceagent-alexa', 'alexa-viewer' , '', d)} \ - " - -QTAGLEXTRAS = "${@bb.utils.contains("DISTRO_FEATURES", "agl-hmi-framework", " qtaglextras", "",d)}" -QTAGLEXTRAS_append = " libqtappfw" - -# add support for websocket in Qt and QML -QTAGLEXTRAS_append = " qtwebsockets qtwebsockets-qmlplugins" -PREFERRED_PROVIDER_virtual/webruntime = "web-runtime" - -#QTAGLEXTRAS_append = " ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'qtwebengine', '', d)}" -#QTAGLEXTRAS_append = " qtsmarthome cinematicexperience qt5everywheredemo qt5-demo-extrafiles" -#IMAGE_INSTALL_append = " qtwebengine-examples" - -# packages from hmi-framework aka homescreen-2017 -HOMESCREEN = "packagegroup-hmi-framework" - -# Cluster demo support. -# ATM no cluster map viewer is supported with the older navigation application. -MAPVIEWER = "${@bb.utils.contains("PREFERRED_RPROVIDER_virtual/navigation", "ondemandnavi", "tbtnavi", "",d)}" -CLUSTER_SUPPORT_PACKAGES = " \ - ${MAPVIEWER} \ - cluster-demo-network-config \ - cluster-lin-bridging-config \ - cluster-demo-simulator \ -" -CLUSTER_SUPPORT = "${@bb.utils.contains("DISTRO_FEATURES", "agl-cluster-demo-support", "${CLUSTER_SUPPORT_PACKAGES}", "",d)}" - -DEMO_UNIT_CONF ?= "" -# Hook for demo platform configuration -# ATM used for: -# 1) Adding udev configuration and scripts for supporting USB attached -# I2C devices for RTC and HVAC LED support. -DEMO_UNIT_CONF += " demo-i2c-udev-conf " - -# Preload poi API key for demo if requested, and potentially maps for older -# navigation application if it is configured. -DEMO_MAPS_LOCALE ?= "uk" -DEMO_PRELOAD_MAPS = "${@bb.utils.contains("PREFERRED_RPROVIDER_virtual/navigation", "navigation", " navigation-maps-${DEMO_MAPS_LOCALE}", "",d)}" - -# Preload only if agl-demo-preload is set -DEMO_PRELOAD = "${@bb.utils.contains("DISTRO_FEATURES", "agl-demo-preload", " ${DEMO_PRELOAD_MAPS} ${DEMO_UNIT_CONF} poiapp-api-key", "",d)}" - - -RDEPENDS_${PN}_append = " \ +RDEPENDS:${PN}:append = " \ + weston-ini-conf-no-activate \ + homescreen \ + launcher \ qtquickcontrols2-agl \ qtquickcontrols2-agl-style \ - ${AGL_APPS} \ - ${QTAGLEXTRAS} \ - ${CLUSTER_SUPPORT} \ - ${DEMO_PRELOAD} \ - ${HOMESCREEN} \ + psplash-portrait-config \ " diff --git a/recipes-platform/packagegroups/packagegroup-agl-demo-preload.bb b/recipes-platform/packagegroups/packagegroup-agl-demo-preload.bb new file mode 100644 index 00000000..808c93c6 --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-demo-preload.bb @@ -0,0 +1,23 @@ +SUMMARY = "Extra software and configuration for tradeshow demo with AGL IVI profile demo platform" +LICENSE = "MIT" + +inherit packagegroup + +PROVIDES = "${PACKAGES}" +PACKAGES = " \ + packagegroup-agl-demo-preload \ +" + +# NOTES: +# - demo-i2c-udev-conf: +# Adds udev configuration and scripts for supporting USB attached +# I2C devices for RTC and HVAC LED support. +# - simple-can-simulator: +# CAN message simulator for vehicle and engine speed message +# generation, with some support for the cruise control events from +# the steering wheel used in the demo setup. +# +RDEPENDS:${PN} = "\ + demo-i2c-udev-conf \ + simple-can-simulator \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-demo.bb b/recipes-platform/packagegroups/packagegroup-agl-demo.bb index 86da3403..90283e06 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-demo.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-demo.bb @@ -9,50 +9,12 @@ PACKAGES = "\ packagegroup-agl-demo \ " -ALLOW_EMPTY_${PN} = "1" - -# MOST out-of-tree kernel drivers -################################# -MOST_DRIVERS ??= " \ - most \ - " -# These boards use different kernels - needs to be checked -MOST_DRIVERS_dragonboard-410c ?= "" -MOST_DRIVERS_cyclone5 ?= "" - - -# HVAC dependencies -################### -LIN_DRIVERS ??= " sllin sllin-virtual" -# These boards use different kernels - needs to be checked -LIN_DRIVERS_dra7xx-evm ?= "sllin-virtual" -LIN_DRIVERS_dragonboard-410c ?= "sllin-virtual" - -# UNICENS service -UNICENS ?= " \ - unicens-config \ - agl-service-unicens \ - agl-service-unicens-controller \ - " - # Hook for demo platform configuration # ATM, only used to disable btwilink module on [MH]3ULCB + Kingfisher by default, # setting DEMO_ENABLE_BTWILINK to "true" in local.conf / site.conf re-enables. DEMO_ENABLE_BTWILINK ?= "" DEMO_PLATFORM_CONF = "" -DEMO_PLATFORM_CONF_append_ulcb = "${@bb.utils.contains("DEMO_ENABLE_BTWILINK", "true", "", " btwilink-disable-conf", d)}" - -SMARTDEVICELINK = "${@bb.utils.contains('DISTRO_FEATURES', 'agl-sdl', \ - 'packagegroup-agl-smartdevicelink', '', d)}" - -# removed: now all enablers are in meta-agl-devel/meta-audio-soundmanager-framework -# old audio package -# AUDIO-OLD = "audiomanager" - -RDEPENDS_${PN} += "\ - udisks2 \ - ${SMARTDEVICELINK} \ - " +DEMO_PLATFORM_CONF:append:ulcb = "${@bb.utils.contains("DEMO_ENABLE_BTWILINK", "true", "", " btwilink-disable-conf", d)}" # fonts TTF_FONTS = " \ @@ -64,22 +26,14 @@ TTF_FONTS = " \ source-han-sans-cn-fonts \ source-han-sans-jp-fonts \ source-han-sans-tw-fonts \ + source-han-sans-kr-fonts \ " - -RDEPENDS_${PN} += " \ +RDEPENDS:${PN} += " \ + udisks2 \ linux-firmware-ath9k \ linux-firmware-ralink \ - can-utils \ iproute2 \ - python-curses \ - dhcp-client \ - ${UNICENS} \ - ${MOST_DRIVERS} \ - ${LIN_DRIVERS} \ ${DEMO_PLATFORM_CONF} \ ${TTF_FONTS} \ - ${@bb.utils.contains('DISTRO_FEATURES', 'webruntime', 'virtual/webruntime', '', d)} \ " - - diff --git a/recipes-platform/packagegroups/packagegroup-agl-image-ivi.bb b/recipes-platform/packagegroups/packagegroup-agl-image-ivi.bb deleted file mode 100644 index acaa405a..00000000 --- a/recipes-platform/packagegroups/packagegroup-agl-image-ivi.bb +++ /dev/null @@ -1,27 +0,0 @@ -SUMMARY = "The middlewares for AGL IVI profile" -DESCRIPTION = "The set of packages required for AGL Distribution" -LICENSE = "MIT" - -inherit packagegroup - -PACKAGES = "\ - packagegroup-agl-image-ivi \ - " - -ALLOW_EMPTY_${PN} = "1" - -RDEPENDS_${PN} += "\ - packagegroup-agl-image-minimal \ -" - -RDEPENDS_${PN} += "\ - packagegroup-agl-ivi-connectivity \ - packagegroup-agl-ivi-graphics \ - packagegroup-agl-ivi-multimedia \ - packagegroup-agl-ivi-navigation \ - packagegroup-agl-ivi-services \ - " - -RDEPENDS_${PN} += "\ - agl-login-manager \ - " diff --git a/recipes-platform/packagegroups/packagegroup-agl-ivi-connectivity.bb b/recipes-platform/packagegroups/packagegroup-agl-ivi-connectivity.bb index 17d0d4b6..aa87db52 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-ivi-connectivity.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-ivi-connectivity.bb @@ -8,13 +8,11 @@ PACKAGES = "\ packagegroup-agl-ivi-connectivity \ " -ALLOW_EMPTY_${PN} = "1" +ALLOW_EMPTY:${PN} = "1" -RDEPENDS_${PN} += "\ +RDEPENDS:${PN} += "\ bluez5-obex \ ${@bb.utils.contains("DISTRO_FEATURES", "3g", "libqmi", "", d)} \ rtl-sdr \ - neard \ - neardal-tools \ ofono \ " diff --git a/recipes-platform/packagegroups/packagegroup-agl-ivi-graphics.bb b/recipes-platform/packagegroups/packagegroup-agl-ivi-graphics.bb index 8831e10a..c5807ed2 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-ivi-graphics.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-ivi-graphics.bb @@ -8,8 +8,7 @@ PACKAGES = "\ packagegroup-agl-ivi-graphics \ " -ALLOW_EMPTY_${PN} = "1" +ALLOW_EMPTY:${PN} = "1" -RDEPENDS_${PN} += "\ - opencv \ +RDEPENDS:${PN} += "\ " diff --git a/recipes-platform/packagegroups/packagegroup-agl-ivi-identity.bb b/recipes-platform/packagegroups/packagegroup-agl-ivi-identity.bb new file mode 100644 index 00000000..3cd16378 --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-ivi-identity.bb @@ -0,0 +1,11 @@ +SUMMARY = "The middlewares for AGL IVI profile" +DESCRIPTION = "The set of packages required for identity services" +LICENSE = "MIT" + +inherit packagegroup + +ALLOW_EMPTY:${PN} = "1" + +RDEPENDS:${PN} += "\ +" + diff --git a/recipes-platform/packagegroups/packagegroup-agl-ivi-multimedia-hardware.bb b/recipes-platform/packagegroups/packagegroup-agl-ivi-multimedia-hardware.bb new file mode 100644 index 00000000..e52e8ef5 --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-ivi-multimedia-hardware.bb @@ -0,0 +1,21 @@ +SUMMARY = "The middlewares for AGL IVI profile" +DESCRIPTION = "Hardware-specific packages required by Multimedia Subsystem" +LICENSE = "MIT" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-ivi-multimedia-hardware \ + " + +ALLOW_EMPTY:${PN} = "1" + +RDEPENDS:${PN} = "" + +RDEPENDS:${PN}:append:rcar-gen3 = "\ + ${@bb.utils.contains('MACHINE_FEATURES', 'multimedia', 'packagegroup-multimedia-kernel-modules', '', d)} \ + ${@bb.utils.contains('MACHINE_FEATURES', 'multimedia', 'packagegroup-multimedia-libs', '', d)} \ + ${@bb.utils.contains('MACHINE_FEATURES', 'multimedia', 'packagegroup-gstreamer1.0-plugins', '', d)} \ + " diff --git a/recipes-platform/packagegroups/packagegroup-agl-ivi-multimedia.bb b/recipes-platform/packagegroups/packagegroup-agl-ivi-multimedia.bb index 34622efd..78c96faf 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-ivi-multimedia.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-ivi-multimedia.bb @@ -8,20 +8,18 @@ PACKAGES = "\ packagegroup-agl-ivi-multimedia \ " -ALLOW_EMPTY_${PN} = "1" +ALLOW_EMPTY:${PN} = "1" -RDEPENDS_${PN} += "\ - gstreamer1.0-plugins-base-meta \ - gstreamer1.0-plugins-good-meta \ - lightmediascanner-meta \ - " - -# for now: enable here for the AGL IVI demo (image-ivi and demo-platform) -# tbd: change based on usage in profiles -PIPEWIRE = "\ - ${@bb.utils.contains('DISTRO_FEATURES', 'pipewire', 'packagegroup-pipewire', '', d)}\ +PIPEWIRE_PACKAGES = " \ + packagegroup-pipewire \ + ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'packagegroup-pipewire-tools alsa-utils', '', d)} \ + wireplumber-config-agl \ + wireplumber-policy-config-agl \ " -RDEPENDS_${PN} += "\ - ${PIPEWIRE} \ +RDEPENDS:${PN} += "\ + ${@bb.utils.contains('DISTRO_FEATURES', 'pipewire', '${PIPEWIRE_PACKAGES}', '', d)} \ + gstreamer1.0-plugins-base-meta \ + gstreamer1.0-plugins-good-meta \ + ${@bb.utils.contains('AGL_FEATURES', 'agl-kvm-host-audio', '', 'mpd', d)} \ " diff --git a/recipes-platform/packagegroups/packagegroup-agl-ivi-navigation.bb b/recipes-platform/packagegroups/packagegroup-agl-ivi-navigation.bb index 90daf923..f6c5e155 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-ivi-navigation.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-ivi-navigation.bb @@ -10,8 +10,8 @@ PACKAGES = "\ packagegroup-agl-ivi-navigation \ " -RDEPENDS_${PN} += "\ +RDEPENDS:${PN} += "\ gpsd \ - virtual/gpsd-conf \ + gpsd-machine-conf \ geoclue \ " diff --git a/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bb b/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bb index 40359ed3..c3a53d50 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bb @@ -1,30 +1,26 @@ -DESCRIPTION = "The minimal set of packages for AGL IVI Connectivity Subsystem" +DESCRIPTION = "The minimal set of services to support AGL IVI demo" LICENSE = "MIT" inherit packagegroup PACKAGES = "\ packagegroup-agl-ivi-services \ - " + packagegroup-agl-ivi-services-platform \ + packagegroup-agl-ivi-services-applaunchd \ +" -ALLOW_EMPTY_${PN} = "1" +RDEPENDS:${PN}-applaunchd += " \ + applaunchd \ + applaunchd-template-agl-app \ +" -RDEPENDS_${PN} += "\ -agl-service-bluetooth \ -agl-service-bluetooth-map \ -agl-service-bluetooth-pbap \ -agl-service-can-high-level-viwi \ -agl-service-can-low-level \ -agl-service-geoclue \ -agl-service-geofence \ -agl-service-gps \ -agl-service-identity-agent \ -agl-service-iiodevices \ -agl-service-mediascanner \ -agl-service-navigation \ -agl-service-nfc \ -agl-service-signal-composer \ -agl-service-steering-wheel \ -agl-service-unicens \ -agl-service-weather \ - " +RDEPENDS:${PN}-platform += " \ + agl-service-hvac \ + agl-service-audiomixer \ + agl-service-radio \ +" + +RDEPENDS:${PN} += " \ + packagegroup-agl-ivi-services-applaunchd \ + packagegroup-agl-ivi-services-platform \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-kuksa-val-databroker.bb b/recipes-platform/packagegroups/packagegroup-agl-kuksa-val-databroker.bb new file mode 100644 index 00000000..a9382e5b --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-kuksa-val-databroker.bb @@ -0,0 +1,21 @@ +SUMMARY = "KUKSA.val databroker packages" +LICENSE = "MIT" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-kuksa-val-databroker \ + packagegroup-agl-kuksa-val-databroker-devel \ +" + +RDEPENDS:packagegroup-agl-kuksa-val-databroker = "\ + kuksa-databroker \ + kuksa-databroker-agl \ + kuksa-certificates-agl \ + kuksa-dbc-feeder \ + agl-vss-helper \ +" + +RDEPENDS:packagegroup-agl-kuksa-val-databroker-devel = "\ + kuksa-databroker-cli \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-kuksa-val-server.bb b/recipes-platform/packagegroups/packagegroup-agl-kuksa-val-server.bb new file mode 100644 index 00000000..82a5b020 --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-kuksa-val-server.bb @@ -0,0 +1,15 @@ +SUMMARY = "KUKSA.val server packages" +LICENSE = "MIT" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-kuksa-val-server \ +" + +RDEPENDS:packagegroup-agl-kuksa-val-server = "\ + kuksa-val \ + kuksa-val-agl \ + kuksa-certificates-agl \ + kuksa-dbc-feeder \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-networking.bb b/recipes-platform/packagegroups/packagegroup-agl-networking.bb new file mode 100644 index 00000000..74f7757a --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-networking.bb @@ -0,0 +1,21 @@ +SUMMARY = "The networking for AGL" +DESCRIPTION = "A set of packages for AGL cluster's networking" + +LICENSE = "MIT" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-networking \ + " + +ALLOW_EMPTY:${PN} = "1" + + +# fonts +RDEPENDS:${PN}:append = " \ + connman \ + connman-client \ + connman-tools \ + iproute2 \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-source-han-sans-ttf-fonts.bb b/recipes-platform/packagegroups/packagegroup-agl-source-han-sans-ttf-fonts.bb new file mode 100644 index 00000000..0afb9505 --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-source-han-sans-ttf-fonts.bb @@ -0,0 +1,20 @@ +SUMMARY = "The Source Han Sans ttf fonts for AGL" +DESCRIPTION = "A set of packages for source Han Sans ttf fonts" + +LICENSE = "MIT" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-source-han-sans-ttf-fonts \ + " + +ALLOW_EMPTY:${PN} = "1" + + +# fonts +RDEPENDS:${PN}:append = " \ + source-han-sans-cn-fonts \ + source-han-sans-jp-fonts \ + source-han-sans-tw-fonts \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-speech-services.bb b/recipes-platform/packagegroups/packagegroup-agl-speech-services.bb new file mode 100644 index 00000000..ceffd093 --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-speech-services.bb @@ -0,0 +1,11 @@ +DESCRIPTION = "The set of packages for AGL Speech Subsystem" +LICENSE = "MIT" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-speech-services \ + " + +RDEPENDS:${PN} += "\ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-telematics-demo-platform.bb b/recipes-platform/packagegroups/packagegroup-agl-telematics-demo-platform.bb new file mode 100644 index 00000000..96ad7138 --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-telematics-demo-platform.bb @@ -0,0 +1,18 @@ +SUMMARY = "The software for AGL telematics profile demo platform" +DESCRIPTION = "A set of packages belonging to the AGL telematics demo platform" + +LICENSE = "MIT" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-telematics-demo-platform \ + " + +RDEPENDS:${PN}:append = " \ + gpsd \ + sw-gpsd-udev-conf \ + usb-can-udev-conf \ + simple-can-simulator \ + ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'ofono-tests gps-utils' , '', d)} \ +" diff --git a/recipes-platform/packagegroups/packagegroup-agl-ttf-fonts.bb b/recipes-platform/packagegroups/packagegroup-agl-ttf-fonts.bb new file mode 100644 index 00000000..4bc11de6 --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-agl-ttf-fonts.bb @@ -0,0 +1,21 @@ +SUMMARY = "The ttf fonts for AGL" +DESCRIPTION = "A set of packages for fonts" + +LICENSE = "MIT" + +inherit packagegroup + +PACKAGES = "\ + packagegroup-agl-ttf-fonts \ + " + +ALLOW_EMPTY:${PN} = "1" + + +# fonts +RDEPENDS:${PN}:append = " \ + ttf-bitstream-vera \ + ttf-dejavu-sans \ + ttf-dejavu-sans-mono \ + ttf-dejavu-serif \ +" diff --git a/recipes-platform/packagegroups/packagegroup-hmi-framework.bb b/recipes-platform/packagegroups/packagegroup-hmi-framework.bb deleted file mode 100644 index cf704e63..00000000 --- a/recipes-platform/packagegroups/packagegroup-hmi-framework.bb +++ /dev/null @@ -1,23 +0,0 @@ -SUMMARY = "The software for the AGL hmi framework 2017" -DESCRIPTION = "A set of packages belong to the hmi framework 2017" - -LICENSE = "MIT" - -# need to bump manually due to: -# - nothing provides libqthomescreenwrapper0 needed by packagegroup-hmi-framework-1.0-r0.noarch -PR = "2" - -inherit packagegroup - -RDEPENDS_${PN} += " \ - agl-service-windowmanager \ - agl-service-homescreen \ - homescreen \ - libwindowmanager \ - qlibwindowmanager \ - libhomescreen \ - qlibhomescreen \ - runxdg \ - hmi-debug \ - launcher \ -" diff --git a/recipes-platform/packagegroups/packagegroup-qt5-toolchain-target.bbappend b/recipes-platform/packagegroups/packagegroup-qt5-toolchain-target.bbappend new file mode 100644 index 00000000..3583515f --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-qt5-toolchain-target.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'packagegroup-qt5-toolchain-target_agldemo.inc', '', d)} diff --git a/recipes-platform/packagegroups/packagegroup-qt5-toolchain-target_agldemo.inc b/recipes-platform/packagegroups/packagegroup-qt5-toolchain-target_agldemo.inc new file mode 100644 index 00000000..a677f40d --- /dev/null +++ b/recipes-platform/packagegroups/packagegroup-qt5-toolchain-target_agldemo.inc @@ -0,0 +1,18 @@ +# add missing dependencies for SDK + +RDEPENDS:${PN} += " \ + qttools-plugins \ + qtquickcontrols-dev \ + qtquickcontrols-qmlplugins \ + qtquickcontrols2-dev \ + qtquickcontrols2-mkspecs \ + qtquickcontrols2-qmlplugins \ +" + +# remove dependency on qtwebkit (still added to SDK by packagegroup-qt5-toolchain-target) +# see SPEC-1159 +RDEPENDS:${PN}:remove = " \ + qtwebkit-dev \ + qtwebkit-mkspecs \ + qtwebkit-qmlplugins \ +" diff --git a/recipes-qt/qt-qrcode/qt-qrcode/0001-rework-library-build.patch b/recipes-qt/qt-qrcode/qt-qrcode/0001-rework-library-build.patch deleted file mode 100644 index 76795268..00000000 --- a/recipes-qt/qt-qrcode/qt-qrcode/0001-rework-library-build.patch +++ /dev/null @@ -1,181 +0,0 @@ -Rework library build - -Rework qmake files to build libraries out of the quickitem and widget -code instead of sample programs. This allows using the associated -classes without copying the source and running afoul of the LGPL -licensing. Also add pkgconfig file generation to simplify usage, fix -header installation, and use pkgconfig to pull in libqrencode instead -of having to clone a copy in-tree and building it. - -Upstream-Status: inappropriate [embedded-specific] - -Signed-off-by: Scott Murray <scott.murray@konsulko.com> - -diff --git a/lib/lib.pro b/lib/lib.pro -index d046bc4..6b6c199 100644 ---- a/lib/lib.pro -+++ b/lib/lib.pro -@@ -1,6 +1,9 @@ - TARGET = qtqrcode - TEMPLATE = lib - -+CONFIG += link_pkgconfig create_pc create_prl no_install_prl -+PKGCONFIG += libqrencode -+ - DEFINES += \ - QTQRCODE_LIBRARY \ - QTQRCODE_PLUS_FEATURES -@@ -12,7 +15,8 @@ contains(DEFINES, QTQRCODE_PLUS_FEATURES) { - qtqrcodepainter.cpp - - HEADERS +=\ -- qtqrcodepainter.h -+ qtqrcodepainter.h \ -+ QtQrCodePainter - - } else { - QT -= gui -@@ -23,16 +27,29 @@ SOURCES += \ - - HEADERS +=\ - qtqrcode_global.h \ -- qtqrcode.h -+ qtqrcode.h \ -+ QtQrCode - - INCLUDEPATH += $$PWD - - include(../defaults.pri) --include(libqrencode.pri) - # Default rules for deployment. - include(deployment.pri) - - unix { -+ headers.path = /usr/include - target.path = /usr/lib -- INSTALLS += target - } -+ -+headers.files = $$HEADERS -+ -+INSTALLS += headers -+ -+QMAKE_PKGCONFIG_NAME = qtqrcode -+QMAKE_PKGCONFIG_FILE = $${QMAKE_PKGCONFIG_NAME} -+QMAKE_PKGCONFIG_VERSION = $${VERSION} -+QMAKE_PKGCONFIG_DESCRIPTION = A wrapper interface for qrencode for Qt -+QMAKE_PKGCONFIG_LIBDIR = ${prefix}/lib -+QMAKE_PKGCONFIG_INCDIR = ${prefix}/include -+QMAKE_PKGCONFIG_REQUIRES = libqrencode -+QMAKE_PKGCONFIG_DESTDIR = pkgconfig -diff --git a/lib/qtqrcode.h b/lib/qtqrcode.h -index 2a7a1ff..0830826 100644 ---- a/lib/qtqrcode.h -+++ b/lib/qtqrcode.h -@@ -31,7 +31,7 @@ - #include <QByteArray> - #include <QSharedDataPointer> - --#include "libqrencode/qrencode.h" -+#include <qrencode.h> - - class QtQrCodeData; - -diff --git a/quickitem/quickitem.pro b/quickitem/quickitem.pro -index ecfef1b..067dc46 100644 ---- a/quickitem/quickitem.pro -+++ b/quickitem/quickitem.pro -@@ -1,5 +1,7 @@ --TEMPLATE = app --TARGET = QuickItem -+TEMPLATE = lib -+TARGET = qtqrcode-quickitem -+ -+CONFIG += create_pc create_prl no_install_prl - - QT += qml quick widgets - -@@ -7,7 +9,7 @@ LIBS += -L../lib -lqtqrcode - - DEFINES += - --SOURCES += main.cpp \ -+SOURCES += \ - QtQrCodeQuickItem.cpp - - HEADERS += \ -@@ -21,3 +23,21 @@ QML_IMPORT_PATH = - include(../defaults.pri) - # Default rules for deployment. - include(deployment.pri) -+ -+unix { -+ headers.path = /usr/include -+ target.path = /usr/lib -+} -+ -+headers.files = $$HEADERS -+ -+INSTALLS += headers -+ -+QMAKE_PKGCONFIG_NAME = qtqrcode-quickitem -+QMAKE_PKGCONFIG_FILE = $${QMAKE_PKGCONFIG_NAME} -+QMAKE_PKGCONFIG_VERSION = $${VERSION} -+QMAKE_PKGCONFIG_DESCRIPTION = Qt QuickItem wrapper for qt-qrcode library -+QMAKE_PKGCONFIG_LIBDIR = ${prefix}/lib -+QMAKE_PKGCONFIG_INCDIR = ${prefix}/include -+QMAKE_PKGCONFIG_REQUIRES = qtqrcode -+QMAKE_PKGCONFIG_DESTDIR = pkgconfig -diff --git a/widget/widget.pro b/widget/widget.pro -index 2e26a8c..63add50 100644 ---- a/widget/widget.pro -+++ b/widget/widget.pro -@@ -1,5 +1,7 @@ --TEMPLATE = app --TARGET = Widget -+TEMPLATE = lib -+TARGET = qtqrcode-widget -+ -+CONFIG += create_pc create_prl no_install_prl - - greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -@@ -9,18 +11,28 @@ LIBS += -L../lib -lqtqrcode - - DEFINES += - --SOURCES += main.cpp\ -- MainWindow.cpp \ -- QtQrCodeWidget.cpp -- --HEADERS += MainWindow.hpp \ -- QtQrCodeWidget.hpp -+SOURCES += QtQrCodeWidget.cpp - --FORMS += MainWindow.ui -- --CONFIG += mobility --MOBILITY = -+HEADERS += QtQrCodeWidget.hpp - - include(../defaults.pri) - # Default rules for deployment. - include(deployment.pri) -+ -+unix { -+ headers.path = /usr/include -+ target.path = /usr/lib -+} -+ -+headers.files = $$HEADERS -+ -+INSTALLS += headers -+ -+QMAKE_PKGCONFIG_NAME = qtqrcode-widget -+QMAKE_PKGCONFIG_FILE = $${QMAKE_PKGCONFIG_NAME} -+QMAKE_PKGCONFIG_VERSION = $${VERSION} -+QMAKE_PKGCONFIG_DESCRIPTION = Qt widget wrapper for qt-qrcode library -+QMAKE_PKGCONFIG_LIBDIR = ${prefix}/lib -+QMAKE_PKGCONFIG_INCDIR = ${prefix}/include -+QMAKE_PKGCONFIG_REQUIRES = qtqrcode -+QMAKE_PKGCONFIG_DESTDIR = pkgconfig diff --git a/recipes-qt/qt-qrcode/qt-qrcode_git.bb b/recipes-qt/qt-qrcode/qt-qrcode_git.bb deleted file mode 100644 index 8b3ff79a..00000000 --- a/recipes-qt/qt-qrcode/qt-qrcode_git.bb +++ /dev/null @@ -1,18 +0,0 @@ -SUMMARY = "Qt QR code library" -DESCRIPTION = "Qt/C++ library for encoding and visualization of data in a \ -QR Code symbol. This library consists of a Qt wrapper for libqrencode, and \ -Qt components that are able to visualize the result." -LICENSE = "LGPLv3+" -LIC_FILES_CHKSUM = "file://LICENSE;md5=94a3f3bdf61243b5e5cf569fbfbbea52" - -DEPENDS = "qtbase qtdeclarative qtquickcontrols2 qtsvg qrencode" - -SRC_URI = "git://github.com/danielsanfr/qt-qrcode.git;protocol=https \ - file://0001-rework-library-build.patch \ -" -SRCREV = "2d57d9c6e2341689d10f9360a16a08831a4a820b" - -PV = "git${SRCPV}" -S = "${WORKDIR}/git/" - -inherit qmake5 diff --git a/recipes-qt/qt/qtbase_%.bbappend b/recipes-qt/qt/qtbase_%.bbappend new file mode 100644 index 00000000..ff8fe687 --- /dev/null +++ b/recipes-qt/qt/qtbase_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'qtbase_agldemo.inc', '', d)} diff --git a/recipes-qt/qt/qtbase_agldemo.inc b/recipes-qt/qt/qtbase_agldemo.inc new file mode 100644 index 00000000..b2bfe374 --- /dev/null +++ b/recipes-qt/qt/qtbase_agldemo.inc @@ -0,0 +1,5 @@ +# Enable EGL and KMS platform plugins to allow demos of Qt compositor +# without Wayland +PACKAGECONFIG_GL:append = "${@bb.utils.contains('DISTRO_FEATURES', 'opengl', ' eglfs kms gbm', '', d)}" + +PACKAGECONFIG:append = " xkbcommon icu fontconfig sql-sqlite" diff --git a/recipes-qt/qt/qtmultimedia/0001-metadata-image-support-with-the-data-URL-scheme-for-.patch b/recipes-qt/qt/qtmultimedia/0001-metadata-image-support-with-the-data-URL-scheme-for-.patch new file mode 100644 index 00000000..007e4676 --- /dev/null +++ b/recipes-qt/qt/qtmultimedia/0001-metadata-image-support-with-the-data-URL-scheme-for-.patch @@ -0,0 +1,80 @@ +From ed61f1d932c5c6d38458fcd2e1d5d154383f017e Mon Sep 17 00:00:00 2001 +From: Tasuku Suzuki <tasuku.suzuki@qt.io> +Date: Mon, 12 Dec 2016 16:32:47 +0900 +Subject: [PATCH] metadata image support with the "data" URL scheme for QtQuick + +add posterImage, coverArtImage and thumbnailImage to metadata + +Change-Id: I10b9bae10c219ffa41506d6e6b345020790217a6 +--- + .../multimedia/qdeclarativemediametadata_p.h | 33 ++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/src/imports/multimedia/qdeclarativemediametadata_p.h b/src/imports/multimedia/qdeclarativemediametadata_p.h +index ede7f87..6a6a815 100644 +--- a/src/imports/multimedia/qdeclarativemediametadata_p.h ++++ b/src/imports/multimedia/qdeclarativemediametadata_p.h +@@ -51,6 +51,9 @@ + // We mean it. + // + ++#include <QtCore/QBuffer> ++#include <QtGui/QImage> ++#include <QtGui/QImageWriter> + #include <QtQml/qqml.h> + #include <QtMultimedia/qmediametadata.h> + #include <QtMultimedia/qmediaservice.h> +@@ -153,6 +156,9 @@ class QDeclarativeMediaMetaData : public QObject + Q_PROPERTY(QVariant gpsProcessingMethod READ gpsProcessingMethod WRITE setGPSProcessingMethod NOTIFY metaDataChanged) + Q_PROPERTY(QVariant gpsAreaInformation READ gpsAreaInformation WRITE setGPSAreaInformation NOTIFY metaDataChanged) + ++ Q_PROPERTY(QVariant posterImage READ posterImage NOTIFY metaDataChanged) ++ Q_PROPERTY(QVariant coverArtImage READ coverArtImage NOTIFY metaDataChanged) ++ Q_PROPERTY(QVariant thumbnailImage READ thumbnailImage NOTIFY metaDataChanged) + public: + QDeclarativeMediaMetaData(QMediaObject *player, QObject *parent = 0) + : QObject(parent) +@@ -425,6 +431,16 @@ QT_WARNING_POP + void setGPSAreaInformation(const QVariant &information) { + setMetaData(QMediaMetaData::GPSAreaInformation, information); } + ++ QVariant posterImage() const { ++ return convertImageToUrl(m_mediaObject->metaData(QMediaMetaData::PosterImage)); ++ } ++ QVariant coverArtImage() const { ++ return convertImageToUrl(m_mediaObject->metaData(QMediaMetaData::CoverArtImage)); ++ } ++ QVariant thumbnailImage() const { ++ return convertImageToUrl(m_mediaObject->metaData(QMediaMetaData::ThumbnailImage)); ++ } ++ + Q_SIGNALS: + void metaDataChanged(); + +@@ -440,6 +456,23 @@ private: + m_writerControl->setMetaData(key, value); + } + ++ QUrl convertImageToUrl(const QVariant &variant) const ++ { ++ if (variant.type() != QVariant::Image) ++ return QUrl(); ++ ++ QImage image = variant.value<QImage>(); ++ QByteArray data; ++ QBuffer buffer(&data); ++ buffer.open(QBuffer::WriteOnly); ++ QImageWriter png(&buffer, "png"); ++ if (!png.write(image)) { ++ return QUrl(); ++ } ++ buffer.close(); ++ return QUrl(QStringLiteral("data:image/png;base64,") + data.toBase64()); ++ } ++ + QMediaObject *m_mediaObject; + QMetaDataWriterControl *m_writerControl; + bool m_requestedWriterControl; +-- +2.7.4 + diff --git a/recipes-qt/qt/qtmultimedia_%.bbappend b/recipes-qt/qt/qtmultimedia_%.bbappend new file mode 100644 index 00000000..dacca3bd --- /dev/null +++ b/recipes-qt/qt/qtmultimedia_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'qtmultimedia_agldemo.inc', '', d)} diff --git a/recipes-qt/qt/qtmultimedia_agldemo.inc b/recipes-qt/qt/qtmultimedia_agldemo.inc new file mode 100644 index 00000000..0734a366 --- /dev/null +++ b/recipes-qt/qt/qtmultimedia_agldemo.inc @@ -0,0 +1,7 @@ +FILESEXTRAPATHS:append := ":${THISDIR}/qtmultimedia" + +PACKAGECONFIG:append = " gstreamer" + +SRC_URI:append = " \ + file://0001-metadata-image-support-with-the-data-URL-scheme-for-.patch \ + " diff --git a/recipes-qt/qt/qtsystems_%.bbappend b/recipes-qt/qt/qtsystems_%.bbappend new file mode 100644 index 00000000..4fe0f28c --- /dev/null +++ b/recipes-qt/qt/qtsystems_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'qtsystems_agldemo.inc', '', d)} diff --git a/recipes-qt/qt/qtsystems_agldemo.inc b/recipes-qt/qt/qtsystems_agldemo.inc new file mode 100644 index 00000000..9cd33c8a --- /dev/null +++ b/recipes-qt/qt/qtsystems_agldemo.inc @@ -0,0 +1,3 @@ +DEPENDS:remove = "bluez4" +# currently Qt5 does not support bluez5 "Nothing PROVIDES 'gconfbluez5'" +#DEPENDS:append = "bluez5" diff --git a/recipes-qt/qt/qtwayland/0001-qwaylandintegration-Keep-previous-check-related-to-i.patch b/recipes-qt/qt/qtwayland/0001-qwaylandintegration-Keep-previous-check-related-to-i.patch new file mode 100644 index 00000000..b34f84d4 --- /dev/null +++ b/recipes-qt/qt/qtwayland/0001-qwaylandintegration-Keep-previous-check-related-to-i.patch @@ -0,0 +1,33 @@ +From 81213fb5e1bdd19f4f8135bcddcc1efaeb1b42a5 Mon Sep 17 00:00:00 2001 +From: Marius Vlad <marius.vlad@collabora.com> +Date: Wed, 26 Jul 2023 13:57:30 +0300 +Subject: [PATCH] qwaylandintegration: Keep previous check related to + inputContext() + +Avoid touching inputContext() when QT_LOGGING_RULES are enabled. This +check ensures we're still able to debug Qt issues. + +Bug-AGL: SPEC-4770 +Signed-off-by: Marius Vlad <marius.vlad@collabora.com> +--- + src/client/qwaylandintegration.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp +index c53ccb78..6d3d9559 100644 +--- a/src/client/qwaylandintegration.cpp ++++ b/src/client/qwaylandintegration.cpp +@@ -479,7 +479,9 @@ void QWaylandIntegration::reconfigureInputContext() + } + #endif + +- qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>"); ++ bool mUsingInputContextFromCompositor = qobject_cast<QWaylandInputContext *>(mInputContext.data()); ++ if (mUsingInputContextFromCompositor) ++ qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className(); + } + + QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName) +-- +2.35.1 + diff --git a/recipes-qt/qt/qtwayland/0001-qwaylandwindow-Short-circuit-isExposed.patch b/recipes-qt/qt/qtwayland/0001-qwaylandwindow-Short-circuit-isExposed.patch new file mode 100644 index 00000000..4dc55c5d --- /dev/null +++ b/recipes-qt/qt/qtwayland/0001-qwaylandwindow-Short-circuit-isExposed.patch @@ -0,0 +1,39 @@ +From f7fdce7a47e717107385408de1eae3b723e4d53c Mon Sep 17 00:00:00 2001 +From: Marius Vlad <marius.vlad@collabora.com> +Date: Mon, 25 Apr 2022 16:34:18 +0300 +Subject: [PATCH] qwaylandwindow: Short-circuit isExposed() + +This patch short-circuits isExposed() to allow sending +xdg_shell:set_window_geometry() when re-sizing the window. + +isExposed() depends on mFrameCallbackTimedOut begin set-up, which takes +precedence on checking isExposed() from mShellSurface. + +As such, this patch allows to take into consideration the fact that +geometry did indeed changed and requires sending a new +set_window_geometry() request, in order to to avoid a protocol error as +the compositor already geometry provided by the client instead of +computing one for itself, so we need to send a new set_window_geometry() +with newer dimensions. + +Signed-off-by: Marius Vlad <marius.vlad@collabora.com> +--- + src/client/qwaylandwindow.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index e875af3a..7a13e06e 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -365,7 +365,7 @@ void QWaylandWindow::setGeometry(const QRect &rect) + if (isExposed() && !mInResizeFromApplyConfigure && exposeGeometry != mLastExposeGeometry) + sendExposeEvent(exposeGeometry); + +- if (mShellSurface && isExposed()) ++ if (mShellSurface && (isExposed() || exposeGeometry != mLastExposeGeometry)) + mShellSurface->setWindowGeometry(windowContentGeometry()); + + if (isOpaque() && mMask.isEmpty()) +-- +2.35.1 + diff --git a/recipes-qt/qt/qtwayland_%.bbappend b/recipes-qt/qt/qtwayland_%.bbappend new file mode 100644 index 00000000..f9ab5fc8 --- /dev/null +++ b/recipes-qt/qt/qtwayland_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'qtwayland_agldemo.inc', '', d)} diff --git a/recipes-qt/qt/qtwayland_agldemo.inc b/recipes-qt/qt/qtwayland_agldemo.inc new file mode 100644 index 00000000..dc5ee3dc --- /dev/null +++ b/recipes-qt/qt/qtwayland_agldemo.inc @@ -0,0 +1,6 @@ +FILESEXTRAPATHS:append := ":${THISDIR}/qtwayland" + +SRC_URI:append = "\ + file://0001-qwaylandwindow-Short-circuit-isExposed.patch \ + file://0001-qwaylandintegration-Keep-previous-check-related-to-i.patch \ + " diff --git a/recipes-qt/qt/qtwebkit_%.bbappend b/recipes-qt/qt/qtwebkit_%.bbappend new file mode 100644 index 00000000..d0b1302c --- /dev/null +++ b/recipes-qt/qt/qtwebkit_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'qtwebkit_agldemo.inc', '', d)} diff --git a/recipes-qt/qt/qtwebkit_agldemo.inc b/recipes-qt/qt/qtwebkit_agldemo.inc new file mode 100644 index 00000000..0420578e --- /dev/null +++ b/recipes-qt/qt/qtwebkit_agldemo.inc @@ -0,0 +1 @@ +PACKAGECONFIG = "gstreamer qtlocation qtmultimedia qtsensors" diff --git a/recipes-sdl/packagegroups/packagegroup-agl-smartdevicelink.bb b/recipes-sdl/packagegroups/packagegroup-agl-smartdevicelink.bb deleted file mode 100644 index 108e9b7d..00000000 --- a/recipes-sdl/packagegroups/packagegroup-agl-smartdevicelink.bb +++ /dev/null @@ -1,14 +0,0 @@ -DESCRIPTION = "Set of packages for SmartDeviceLink" -LICENSE = "MIT" - -inherit packagegroup - -PACKAGES = "\ - packagegroup-agl-smartdevicelink \ - " - -ALLOW_EMPTY_${PN} = "1" - -RDEPENDS_${PN} += "\ - sdl-core \ - " diff --git a/recipes-support/icu/icu_74-1.bbappend b/recipes-support/icu/icu_74-1.bbappend new file mode 100644 index 00000000..cf4061e9 --- /dev/null +++ b/recipes-support/icu/icu_74-1.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'icu_74-1_agldemo.inc', '', d)} diff --git a/recipes-support/icu/icu_74-1_agldemo.inc b/recipes-support/icu/icu_74-1_agldemo.inc new file mode 100644 index 00000000..957fe083 --- /dev/null +++ b/recipes-support/icu/icu_74-1_agldemo.inc @@ -0,0 +1,27 @@ +PACKAGECONFIG:append = " make-icudata" + +do_compile:append () { + # just adding below does not enforce a full rebuild + # thus force rebuild and investigate + echo "new" +} + +do_make_icudata:class-native () { + ${@bb.utils.contains('PACKAGECONFIG', 'make-icudata', '', 'exit 0', d)} + cd ${S} + rm -rf data + cp -a ${WORKDIR}/data . + AR='${BUILD_AR}' \ + CC='${BUILD_CC}' \ + CPP='${BUILD_CPP}' \ + CXX='${BUILD_CXX}' \ + RANLIB='${BUILD_RANLIB}' \ + CFLAGS='${BUILD_CFLAGS}' \ + CPPFLAGS='${BUILD_CPPFLAGS}' \ + CXXFLAGS='${BUILD_CXXFLAGS}' \ + LDFLAGS='${BUILD_LDFLAGS}' \ + ICU_DATA_FILTER_FILE=${WORKDIR}/filter.json \ + ./runConfigureICU Linux --with-data-packaging=archive + oe_runmake + install -Dm644 ${S}/data/out/icudt${ICU_MAJOR_VER}l.dat ${S}/data/in/icudt${ICU_MAJOR_VER}l.dat +} diff --git a/recipes-support/lin-config/lin-config_git.bb b/recipes-support/lin-config/lin-config_git.bb index e83f7160..a8c8f4fc 100644 --- a/recipes-support/lin-config/lin-config_git.bb +++ b/recipes-support/lin-config/lin-config_git.bb @@ -1,14 +1,14 @@ DESCRIPTION = "lin-config tool for the sllin driver module" -LICENSE = "GPLv2" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" +LICENSE = "GPL-2.0-only" +LIC_FILES_CHKSUM = "file://lin_config.c;beginline=4;endline=9;md5=196a29df19a30dbc752937bdfc819d7a" DEPENDS += "libnl libxml2" -SRC_URI = "git://github.com/trainman419/linux-lin.git;protocol=https" -SRCREV = "155d885e8ccc907a56f6c86c4b159fac27ef6fec" +SRC_URI = "git://github.com/lin-bus/linux-lin.git;protocol=https;branch=master" +SRCREV = "beb057d7505e0c4d7c61f3f4927b76916ec00e88" S = "${WORKDIR}/git/lin_config/src" -SRC_URI_append = " \ +SRC_URI:append = " \ file://0001-Change-Makefile-to-use-pkg-config-for-libxml-2.0.patch \ file://0002-Change-Makefile-to-use-LDFLAGS.patch \ " @@ -19,7 +19,7 @@ PV = "0.1+git${SRCPV}" do_configure[noexec] = "1" -do_install_append() { +do_install:append() { install -d ${D}/${bindir} install -m 755 ${S}/lin_config ${D}/${bindir} } diff --git a/recipes-support/qemu-set-display/qemu-set-display_git.bb b/recipes-support/qemu-set-display/qemu-set-display_git.bb new file mode 100644 index 00000000..870ac6b8 --- /dev/null +++ b/recipes-support/qemu-set-display/qemu-set-display_git.bb @@ -0,0 +1,14 @@ +DESCRIPTION = "Helper tool to enable the secondandary vnc displays" +LICENSE = "GPL-2.0-or-later" +LIC_FILES_CHKSUM = "file://COPYING;md5=361b6b837cad26c6900a926b62aada5f" + + +SRC_URI = "git://github.com/dhobsong/qemu-set-display.git;protocol=https;branch=main" +SRCREV = "${AUTOREV}" +S = "${WORKDIR}/git" + +DEPENDS += "libvncserver" + +inherit meson pkgconfig + +PV = "0.1+git${SRCPV}" diff --git a/recipes-support/rng-tools/files/default b/recipes-support/rng-tools/files/default new file mode 100644 index 00000000..6e2f2ca9 --- /dev/null +++ b/recipes-support/rng-tools/files/default @@ -0,0 +1 @@ +EXTRA_ARGS="-r /dev/hwrng -x jitter" diff --git a/recipes-support/rng-tools/rng-tools_%.bbappend b/recipes-support/rng-tools/rng-tools_%.bbappend new file mode 100644 index 00000000..8ec7f750 --- /dev/null +++ b/recipes-support/rng-tools/rng-tools_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'rng-tools_agldemo.inc', '', d)} diff --git a/recipes-support/rng-tools/rng-tools_agldemo.inc b/recipes-support/rng-tools/rng-tools_agldemo.inc new file mode 100644 index 00000000..283c8a4c --- /dev/null +++ b/recipes-support/rng-tools/rng-tools_agldemo.inc @@ -0,0 +1,7 @@ +# Pick up modified default configuration for virtual machines +# that disables jitter entropy source, as it is not useful when +# the VMs are effectively driven by the host RNG via virtio-rng. +# This also helps boot speed, as otherwise the guests have rngd +# potentially somewhat pointlessly burning a lot of CPU on boot, +# in addition to the host's own rngd. +FILESEXTRAPATHS:prepend:virtio-all := "${THISDIR}/files:" diff --git a/recipes-support/udisks/files/99-udisks2.rules b/recipes-support/udisks/files/99-udisks2.rules new file mode 100644 index 00000000..996e4343 --- /dev/null +++ b/recipes-support/udisks/files/99-udisks2.rules @@ -0,0 +1,5 @@ +# UDISKS_FILESYSTEM_SHARED +# ==1: mount filesystem to a shared directory (/media/VolumeName) +# ==0: mount filesystem to a private directory (/run/media/$USER/VolumeName) +# See udisks(8) +ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{UDISKS_FILESYSTEM_SHARED}="1" diff --git a/recipes-support/udisks/files/automount.service b/recipes-support/udisks/files/automount.service new file mode 100644 index 00000000..b1651519 --- /dev/null +++ b/recipes-support/udisks/files/automount.service @@ -0,0 +1,9 @@ +[Unit] +Description=Automount Disk Manager +After=udisks2.service + +[Service] +ExecStart=/usr/libexec/automount.sh + +[Install] +WantedBy=multi-user.target diff --git a/recipes-support/udisks/files/automount.sh b/recipes-support/udisks/files/automount.sh new file mode 100644 index 00000000..23679191 --- /dev/null +++ b/recipes-support/udisks/files/automount.sh @@ -0,0 +1,93 @@ +#!/bin/sh + +MOUNT_OPTIONS_DEFAULT="ro,noexec" +MOUNT_OPTIONS_VFAT="umask=0022" +MOUNT_OPTIONS_EXT="" +MOUNT_OPTIONS_NTFS="" +MOUNT_OPTIONS_ISO9660="" + +VERBOSE=false + +# Source a configuration file that can override mount options if exists +[ -f /etc/automount.conf ] && . /etc/automount.conf + +mount_device() { + MOUNT_OPTIONS="" + FSTYPE="$( udevadm info "${1}" "${2}" | awk -v FS== '/ID_FS_TYPE/ {print $2}' )" + DEVNAME="$( udevadm info "${1}" "${2}" | awk -v FS== '/DEVNAME/ {print $2}' )" + case $FSTYPE in + vfat) + MOUNT_OPTIONS="${MOUNT_OPTIONS_VFAT}" + ;; + ext[2-4]) + MOUNT_OPTIONS="${MOUNT_OPTIONS_EXT}" + ;; + ntfs) + MOUNT_OPTIONS="${MOUNT_OPTIONS_NTFS}" + ;; + iso9660) + MOUNT_OPTIONS="${MOUNT_OPTIONS_ISO9660}" + ;; + "") + if $VERBOSE; then + echo "[INFO][${DEVNAME}] Not a partition with a filesystem!" + fi + return + ;; + *) + echo "[WARNING][${DEVNAME}] The filesystem '${FSTYPE}' is not supported!" + return + ;; + esac + + if [ -n "${MOUNT_OPTIONS_DEFAULT}" ]; then + if [ -z "${MOUNT_OPTIONS}" ]; then + MOUNT_OPTIONS="${MOUNT_OPTIONS_DEFAULT}" + else + MOUNT_OPTIONS="${MOUNT_OPTIONS_DEFAULT},${MOUNT_OPTIONS}" + fi + fi + if $VERBOSE; then + echo "[INFO][${DEVNAME}] Mounting a ${FSTYPE}'s filesystem with options: ${MOUNT_OPTIONS}" + fi + + if command -v udisksctl > /dev/null 2>&1; then + if [ -n "${MOUNT_OPTIONS}" ]; then + MOUNT_OPTIONS="-o ${MOUNT_OPTIONS}" + fi + udisksctl mount -t "${FSTYPE}" -b "${DEVNAME}" ${MOUNT_OPTIONS} + elif command -v udisks >/dev/null 2>&1; then + if [ -n "${MOUNT_OPTIONS}" ]; then + MOUNT_OPTIONS="--mount-options ${MOUNT_OPTIONS}" + fi + udisks --mount-fstype "${FSTYPE}" --mount "${DEVNAME}" ${MOUNT_OPTIONS} + else + echo "[ERROR] Unable to find binary for mounting ${DEVNAME}" >&2 + return + fi + if [ "$?" -ne "0" ]; then + echo "[ERROR] Failed to mount the device ${DEVNAME} of type ${FSTYPE} with options ${MOUNT_OPTIONS}" >&2 + fi +} + +# At startup, remove empty directories that may exists +rmdir /media/* > /dev/null 2>&1 + +# Mount already plugged devices +for DEVICE in $( lsblk -dn | cut -d' ' -f1 ); do + REMOVABLE=$( cat "/sys/block/${DEVICE}/removable" ) + if [ "${REMOVABLE}" -eq "1" ]; then + for PART in "/dev/${DEVICE}"*; do + mount_device -n "${PART}" + done + fi +done + +# Wait for plug events and mount devices +stdbuf -oL -- udevadm monitor --udev -s block | +while read -r -- _ _ EVENT DEVPATH _ +do + if [ "${EVENT}" = "add" ]; then + mount_device -p "/sys/${DEVPATH}" + fi +done diff --git a/recipes-support/udisks/udisks2_%.bbappend b/recipes-support/udisks/udisks2_%.bbappend new file mode 100644 index 00000000..a36862b9 --- /dev/null +++ b/recipes-support/udisks/udisks2_%.bbappend @@ -0,0 +1 @@ +require ${@bb.utils.contains('AGL_FEATURES', 'agldemo', 'udisks2_agldemo.inc', '', d)} diff --git a/recipes-support/udisks/udisks2_agldemo.inc b/recipes-support/udisks/udisks2_agldemo.inc new file mode 100644 index 00000000..a3b2ac4d --- /dev/null +++ b/recipes-support/udisks/udisks2_agldemo.inc @@ -0,0 +1,27 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI:append = " file://automount.service \ + file://automount.sh \ + file://99-udisks2.rules \ +" + +SYSTEMD_AUTO_ENABLE = "enable" +SYSTEMD_SERVICE:${PN}:append = " automount.service" + +do_install:append () { + sed -i 's/^WantedBy=.*/WantedBy=multi-user.target/' ${D}${systemd_unitdir}/system/udisks2.service + + install -d ${D}${base_libdir}/systemd/system + install -m 0644 ${WORKDIR}/automount.service ${D}${systemd_unitdir}/system + + install -d ${D}${libexecdir} + install -m 0755 ${WORKDIR}/automount.sh ${D}${libexecdir}/automount.sh + + install -d ${D}${sysconfdir}/udev/rules.d + install -m 0644 ${WORKDIR}/99-udisks2.rules ${D}${sysconfdir}/udev/rules.d +} + +FILES:${PN}:append = " \ + ${base_libdir}/systemd/system/automount.service \ + ${libexecdir}/automount.sh \ +" diff --git a/recipes-support/vboxguestdrivers/vboxguestdrivers/Makefile.utils b/recipes-support/vboxguestdrivers/vboxguestdrivers/Makefile.utils deleted file mode 100644 index 495601f0..00000000 --- a/recipes-support/vboxguestdrivers/vboxguestdrivers/Makefile.utils +++ /dev/null @@ -1,45 +0,0 @@ -## ----------------------------------------------------------------------- -## -## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved -## -## This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, Inc., 53 Temple Place Ste 330, -## Boston MA 02111-1307, USA; either version 2 of the License, or -## (at your option) any later version; incorporated herein by reference. -## -## ----------------------------------------------------------------------- - -INCLUDES = -I. -I../vboxsf -I../vboxsf/include -MOD_DEFS = -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 \ - -DIN_SUP_R0 -DVBOX -DVBOX_WITH_HGCM -DIN_MODULE -DIN_GUEST_R0 -CFLAGS = ${INCLUDES} ${MOD_DEFS} -LDFLAGS = - -SRCS = mount.vboxsf.c \ - vbsfmount.c - -OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) - -.SUFFIXES: .c .o .i .s .S - - -all: mount.vboxsf - -clean: - -rm -f *.o mount.vboxsf - -spotless: clean - -rm -f *~ - -mount.vboxsf: $(OBJS) - $(CC) $(LDFLAGS) -o $@ $^ - -%.o: %.c - $(CC) $(UMAKEDEPS) $(CFLAGS) -c -o $@ $< -%.i: %.c - $(CC) $(UMAKEDEPS) $(CFLAGS) -E -o $@ $< -%.s: %.c - $(CC) $(UMAKEDEPS) $(CFLAGS) -S -o $@ $< - --include .*.d *.tmp diff --git a/recipes-support/vboxguestdrivers/vboxguestdrivers_6.1.2.bb b/recipes-support/vboxguestdrivers/vboxguestdrivers_6.1.2.bb deleted file mode 100644 index 62c2b509..00000000 --- a/recipes-support/vboxguestdrivers/vboxguestdrivers_6.1.2.bb +++ /dev/null @@ -1,81 +0,0 @@ -SUMMARY = "VirtualBox Linux Guest Drivers" -SECTION = "core" -LICENSE = "GPL-2.0" -LIC_FILES_CHKSUM = "file://${WORKDIR}/${VBOX_NAME}/COPYING;md5=e197d5641bb35b29d46ca8c4bf7f2660" - -DEPENDS = "virtual/kernel" - -inherit module kernel-module-split - -COMPATIBLE_MACHINE = "(qemux86|qemux86-64)" - -VBOX_NAME = "VirtualBox-${PV}" - -SRC_URI = "http://download.virtualbox.org/virtualbox/${PV}/${VBOX_NAME}.tar.bz2 \ - file://Makefile.utils \ -" -SRC_URI[md5sum] = "f4f42fd09857556b04b803fb99cc6905" -SRC_URI[sha256sum] = "4326576e8428ea3626194fc82646347576e94c61f11d412a669fc8a10c2a1e67" - -S = "${WORKDIR}/vbox_module" - -export BUILD_TARGET_ARCH="${ARCH}" -export BUILD_TARGET_ARCH_x86-64="amd64" - -EXTRA_OEMAKE += "KERN_DIR='${WORKDIR}/${KERNEL_VERSION}/build' KBUILD_VERBOSE=1" - -# otherwise 5.2.22 builds just vboxguest -MAKE_TARGETS = "all" - -addtask export_sources after do_patch before do_configure - -do_export_sources() { - mkdir -p "${S}" - ${WORKDIR}/${VBOX_NAME}/src/VBox/Additions/linux/export_modules.sh ${T}/vbox_modules.tar.gz - tar -C "${S}" -xzf ${T}/vbox_modules.tar.gz - - # add a mount utility to use shared folder from VBox Addition Source Code - mkdir -p "${S}/utils" - install ${WORKDIR}/${VBOX_NAME}/src/VBox/Additions/linux/sharedfolders/mount.vboxsf.c ${S}/utils - install ${WORKDIR}/${VBOX_NAME}/src/VBox/Additions/linux/sharedfolders/vbsfmount.c ${S}/utils - install ${S}/../Makefile.utils ${S}/utils/Makefile - -} - -do_configure_prepend() { - # vboxguestdrivers/5.2.6-r0/vbox_module/vboxguest/Makefile.include.header:99: *** The variable KERN_DIR must be a kernel build folder and end with /build without a trailing slash, or KERN_VER must be set. Stop. - # vboxguestdrivers/5.2.6-r0/vbox_module/vboxguest/Makefile.include.header:108: *** The kernel build folder path must end in <version>/build, or the variable KERN_VER must be set. Stop. - mkdir -p ${WORKDIR}/${KERNEL_VERSION} - ln -snf ${STAGING_KERNEL_DIR} ${WORKDIR}/${KERNEL_VERSION}/build -} - -# compile and install mount utility -do_compile() { - oe_runmake all - oe_runmake 'LD=${CC}' 'LDFLAGS=${LDFLAGS}' -C ${S}/utils - if ! [ -e vboxguest.ko -a -e vboxsf.ko -a -e vboxvideo.ko ] ; then - echo "ERROR: One of vbox*.ko modules wasn't built" - exit 1 - fi -} - -module_do_install() { - MODULE_DIR=${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel/misc - install -d $MODULE_DIR - install -m 644 vboxguest.ko $MODULE_DIR - install -m 644 vboxsf.ko $MODULE_DIR - install -m 644 vboxvideo.ko $MODULE_DIR -} - -do_install_append() { - install -d ${D}${base_sbindir} - install -m 755 ${S}/utils/mount.vboxsf ${D}${base_sbindir} -} - -PACKAGES += "kernel-module-vboxguest kernel-module-vboxsf kernel-module-vboxvideo" -RRECOMMENDS_${PN} += "kernel-module-vboxguest kernel-module-vboxsf kernel-module-vboxvideo" - -FILES_${PN} = "${base_sbindir}" - -# autoload if installed -KERNEL_MODULE_AUTOLOAD += "vboxguest vboxsf vboxvideo" diff --git a/recipes-wam/cef/cef_git.bb b/recipes-wam/cef/cef_git.bb new file mode 100644 index 00000000..4a87631b --- /dev/null +++ b/recipes-wam/cef/cef_git.bb @@ -0,0 +1,355 @@ +require gn-utils.inc + +inherit qemu python3native + +LICENSE = "Apache-2.0 & BSD-3-Clause & LGPL-2.0-only & LGPL-2.1-only" + +LIC_FILES_CHKSUM = "\ + file://LICENSE;md5=c408a301e3407c3803499ce9290515d6 \ + file://third_party/blink/renderer/core/LICENSE-LGPL-2;md5=36357ffde2b64ae177b2494445b79d21 \ + file://third_party/blink/renderer/core/LICENSE-LGPL-2.1;md5=a778a33ef338abbaf8b8a7c36b6eec80 \ +" + +CHROMIUM_VERSION = "118.0.5993.80" +BRANCH = "5993" +SRCREV = "3cffa575446727e2fe1f6499efa21f8e096e8ca0" + +PV = "${CHROMIUM_VERSION}.${BRANCH}+git" + +FILESEXTRAPATHS:prepend := "${THISDIR}/files/cef:" +FILESEXTRAPATHS:prepend := "${THISDIR}/files/chromium:" + +# The [agl]-prefixed patches are the changes needed to make WAM work with +# agl-compositor. The [meta-browser] patches comes from the https://github.com/OSSystems/meta-browser +# project that does similar work on keeping up to the new chromium milestones +# and the [MXX-Fix] patches are the fixes done by us to fix build issues for +# the current chromium milestone. +# For more information about the current milestones: https://chromiumdash.appspot.com/releases?platform=Linux +SRC_URI = "\ + https://commondatastorage.googleapis.com/chromium-browser-official/chromium-${CHROMIUM_VERSION}.tar.xz \ + file://0001-agl-compositor-Add-agl_shell_wrapper-AGL-wayland-ext.patch \ + file://0002-agl-Add-waylandwindow-window-tree-host-essential-par.patch \ + file://0003-agl-Only-bind-to-agl_shell-if-it-s-the-browser-proce.patch \ + file://0004-agl-Add-a-method-to-check-if-the-agl-window-is-confi.patch \ + file://0005-agl-Start-using-agl-shell-version-4.patch \ + file://0006-agl-Don-t-use-DRI-for-renesas.patch \ + file://0007-meta-browser-Remove-the-GN-settings-done-for-clang-t.patch \ + file://0008-meta-browser-Pass-no-static-libstdc-to-gen.py.patch \ + file://0009-meta-browser-IWYU-Add-includes-for-size_t-and-int64_.patch \ + file://0010-meta-browser-BUILD-do-not-specify-march-on-arm.patch \ + file://0011-meta-browser-Avoid-parenthesized-initialization-of-a.patch \ + file://0012-meta-browser-Fix-constexpr-variable-cannot-have-non-.patch \ + file://0013-meta-browser-Add-missing-typename-s.patch \ + file://0014-meta-browser-Avoid-std-ranges-find_if.patch \ + file://0015-meta-browser-Avoid-capturing-structured-bindings.patch \ + file://0016-meta-browser-Delete-compiler-options-not-available-i.patch \ + file://0017-meta-browser-Don-t-pass-disable-auto-upgrade-debug-i.patch \ + file://0018-meta-browser-Fix-undefined-symbol-PaintOpWriter-Seri.patch \ + file://0019-upstream-Initialize-ServerCvc-with-designated-initia.patch \ + file://0020-M118-fix-Don-t-look-for-depot_tools-in-chrommium-s-t.patch \ + file://0021-M118-fix-Add-multiple-missing-includes.patch \ + file://0022-M118-fix-Fix-aggregate-initialization-in-trace_log.patch \ + file://0023-M118-fix-Add-missing-typename-keyword-in-multiple-st.patch \ + file://0024-M118-fix-Fix-comparison-in-HostResolverCache.patch \ + file://0025-M118-fix-Avoid-using-std-ranges-any_of-find_if-none_.patch \ + file://0026-M118-fix-Add-deleted-constructors-operators.patch \ + file://0027-M118-fix-Initialize-percentages-member-on-blink-Font.patch \ + file://0028-M118-fix-Don-t-delete-ZstdSourceStream-copy-move-cto.patch \ + file://0029-M118-fix-Fix-issue-with-structured-bindinds-captured.patch \ + file://0030-M118-fix-Only-default-arm_use_neon-to-true-if-its-va.patch \ + file://0031-M118-fix-Add-a-way-to-set-different-lib-paths-host-a.patch \ + file://0032-M118-fix-zlib-Fix-arm-build.patch \ + file://0033-M118-fix-Fix-skia-linker-issues-for-arm-neon.patch \ + file://0034-v8-qemu-wrapper.patch \ + \ + git://bitbucket.org/chromiumembedded/cef.git;branch=${BRANCH};protocol=https;rev=${SRCREV};name=cef;destsuffix=chromium-${CHROMIUM_VERSION}/cef \ + file://0001-Add-an-option-to-use-an-output-directory-outside-src.patch;patchdir=cef \ + file://0002-Add-an-option-to-override-the-default-distrib-direct.patch;patchdir=cef \ + file://0003-Add-an-option-to-use-an-alternative-base-output-dire.patch;patchdir=cef \ + file://0004-Add-an-option-to-bypass-sysroot-checking-and-force.patch;patchdir=cef \ + file://0005-Add-AGL-wayland-window-related-calls.patch;patchdir=cef \ + file://0006-Add-a-method-to-check-if-the-agl-window-is-configure.patch;patchdir=cef \ + file://0007-Add-the-SetActivateRegion-method.patch;patchdir=cef \ + file://0008-Allow-passing-the-app_id-on-widget-creation.patch;patchdir=cef \ + file://0009-Update-generated-api.patch;patchdir=cef \ + file://0010-Make-patcher-work-outside-a-git-checkout.patch;patchdir=cef \ + file://0011-Avoid-the-RuntimeError-dictionary-changed-size-durin.patch;patchdir=cef \ +" + +SRC_URI[sha256sum] = "741c5528a151bc364999969077a13d7a283cfd0eaf34adf47de667a34e5e58ff" + +CHROMIUM_DIR = "${WORKDIR}/chromium-${CHROMIUM_VERSION}" +CEF_DIR = "${CHROMIUM_DIR}/cef" +DEPOT_TOOLS_DIR="${STAGING_DIR_NATIVE}${datadir}/depot_tools" +S = "${CHROMIUM_DIR}" +B = "${WORKDIR}/build" + +OUT_PATH = "${B}/out/Release_GN_${GN_TARGET_ARCH_NAME}" +DIST_PATH = "${OUT_PATH}/dist/cef-minimal_${GN_TARGET_ARCH_NAME}" +CEF_DATA_PATH = "${datadir}/cef" + +DEPENDS:append = " ca-certificates-native curl clang clang-native gperf-native dbus libcxx libcxx-native libpng libxslt jpeg jpeg-native compiler-rt libxkbcommon nss nss-native atk at-spi2-atk libdrm pango cairo virtual/egl qemu-native pciutils glib-2.0 pkgconfig-native pulseaudio xz-native compiler-rt compiler-rt-native expat-native" + +do_sync[depends] += "depot-tools-wam-native:do_populate_sysroot" +do_configure[depends] += "depot-tools-wam-native:do_populate_sysroot" +do_compile[depends] += "depot-tools-wam-native:do_populate_sysroot" + +# needs to fetch a font package +do_configure[network] = "1" + +GN_UNBUNDLE_LIBS = " libjpeg libpng libxslt" + +# gn defaults from CEF wiki, except for use_sysroot +GN_DEFINES = "use_sysroot=false \ + symbol_level=0 \ + is_cfi=false \ + use_thin_lto=false \ +" + +# Disable GTK and prevent cef from +# building its gtk demos +GN_DEFINES:append = " \ + use_gtk=false \ + cef_use_gtk=false \ +" + +GN_DEFINES:append = " \ + treat_warnings_as_errors=false \ + is_component_build=false \ + use_cups=false \ + use_kerberos=false \ + use_ozone=true \ + use_xkbcommon=true \ + use_wayland_gbm=true \ + use_gnome_keyring=false \ + enable_remoting=false \ + enable_js_type_check=false \ +" + +# ozone options +GN_DEFINES:append = " \ + use_ozone=true \ + ozone_auto_platforms=false \ + ozone_platform_headless=true \ + ozone_platform_wayland=true \ + ozone_platform_x11=false \ + use_system_minigbm=true \ + use_system_libdrm=true \ + use_system_libwayland=false \ + use_system_libffi=true \ +" + +GN_DEFINES:append = " \ + dcheck_always_on=false \ + is_debug=false \ + is_official_build=true \ +" + +GN_DEFINES:append = " \ + use_egl=true \ + use_glib=true \ + use_dri=false \ +" + +RUNTIME = "llvm" +TOOLCHAIN = "clang" +TOOLCHAIN:class-native = "clang" +LIBCPLUSPLUS = "-stdlib=libc++" + +BUILD_CPPFLAGS:append:runtime-llvm = " -isysroot=${STAGING_DIR_NATIVE} -stdlib=libc++" +BUILD_LDFLAGS:append:runtime-llvm = " -rtlib=libgcc -unwindlib=libgcc -stdlib=libc++ -lc++abi -rpath ${STAGING_LIBDIR_NATIVE}" +CXXFLAGS:append:runtime-llvm = " -isysroot=${STAGING_DIR_NATIVE} -stdlib=libc++" + +BUILD_AR:toolchain-clang = "llvm-ar" +BUILD_CC:toolchain-clang = "clang" +BUILD_CXX:toolchain-clang = "clang++" +BUILD_LD:toolchain-clang = "clang" + +COMPATIBLE_MACHINE = "(-)" +COMPATIBLE_MACHINE:aarch64 = "(.*)" +COMPATIBLE_MACHINE:armv6 = "(.*)" +COMPATIBLE_MACHINE:armv7a = "(.*)" +COMPATIBLE_MACHINE:armv7ve = "(.*)" +COMPATIBLE_MACHINE:x86 = "(.*)" +COMPATIBLE_MACHINE:x86-64 = "(.*)" + +# ARM builds need special additional flags (see ${S}/build/config/arm.gni). +# If we do not pass |arm_arch| and friends to GN, it will deduce a value that +# will then conflict with TUNE_CCARGS and CC. +# Note that as of M61 in some corner cases parts of the build system disable +# the "compiler_arm_fpu" GN config, whereas -mfpu is always passed via ${CC}. +# We might want to rework that if there are issues in the future. +def get_compiler_flag(params, param_name, d): + """Given a sequence of compiler arguments in |params|, returns the value of + an option |param_name| or an empty string if the option is not present.""" + for param in params: + if param.startswith(param_name): + return param.split('=')[1] + return '' + +ARM_FLOAT_ABI = "${@bb.utils.contains('TUNE_FEATURES', 'callconvention-hard', 'hard', 'softfp', d)}" +ARM_FPU = "${@get_compiler_flag(d.getVar('TUNE_CCARGS').split(), '-mfpu', d)}" +ARM_TUNE = "${@get_compiler_flag(d.getVar('TUNE_CCARGS').split(), '-mcpu', d)}" +ARM_VERSION:aarch64 = "8" +ARM_VERSION:armv7a = "7" +ARM_VERSION:armv7ve = "7" +ARM_VERSION:armv6 = "6" + +# GN computes and defaults to it automatically where needed +# forcing it from cmdline breaks build on places where it ends up +# overriding what GN wants +TUNE_CCARGS:remove = "-mthumb" + +GN_DEFINES:append:arm = " \ + arm_float_abi=\"${ARM_FLOAT_ABI}\" \ + arm_fpu=\"${ARM_FPU}\" \ + arm_tune=\"${ARM_TUNE}\" \ + arm_version=${ARM_VERSION} \ +" +# tcmalloc's atomicops-internals-arm-v6plus.h uses the "dmb" instruction that +# is not available on (some?) ARMv6 models, which causes the build to fail. +GN_DEFINES:append:armv6 = ' use_allocator="none"' +# The WebRTC code fails to build on ARMv6 when NEON is enabled. +# https://bugs.chromium.org/p/webrtc/issues/detail?id=6574 + +# Disable unknown attribute warnings that are generating tons of logs +# TODO(rzanoni): check if https://chromium-review.googlesource.com/c/chromium/src/+/4322480 +# needs to be reverted +BUILD_CXXFLAGS:remove = '-Wunknown-attributes' +BUILD_CXXFLAGS:append = ' -Wno-unknown-attributes' +BUILD_CPPFLAGS:remove = '-Wunknown-attributes' +BUILD_CPPFLAGS:append = ' -Wno-unknown-attributes' +CXXFLAGS:remove = '-Wunknown-attributes' +CXXFLAGS:append = ' -Wno-unknown-attributes' +CPPFLAGS:remove = '-Wunknown-attributes' +CPPFLAGS:append = ' -Wno-unknown-attributes' + +GN_DEFINES:append = ' \ + arm_use_neon=false \ + use_lld=true \ + use_gold=false \ + use_custom_libcxx_for_host=false \ + use_custom_libcxx=false \ + chrome_pgo_phase=0 \ + gold_path="" \ + is_clang=true \ + current_os="linux" \ + clang_use_chrome_plugins=false \ + clang_base_path="${STAGING_DIR_NATIVE}/usr" \ + clang_version="14.0.6" \ + clang_base_path_target="${STAGING_DIR_TARGET}/usr" \ + custom_toolchain="//build/toolchain/cros:target" \ + host_toolchain="//build/toolchain/cros:host" \ + v8_snapshot_toolchain="//build/toolchain/cros:v8_snapshot" \ + target_cpu="${@gn_target_arch_name(d)}" \ + use_v8_context_snapshot=false \ + custom_toolchain="//build/toolchain/yocto:yocto_target" \ + host_toolchain="//build/toolchain/yocto:yocto_native" \ + v8_snapshot_toolchain="//build/toolchain/yocto:yocto_target" \ +' + +PACKAGECONFIG ??= "upower use-egl" +PACKAGECONFIG[use-egl] = ",,virtual/egl virtual/libgles2" +PACKAGECONFIG[upower] = ",,,upower" + +GN_DEFINES:append = ' \ + ${PACKAGECONFIG_CONFARGS} \ +' + +python do_write_toolchain_file () { + """Writes a BUILD.gn file for Yocto detailing its toolchains.""" + toolchain_dir = d.expand("${S}/build/toolchain/yocto") + bb.utils.mkdirhier(toolchain_dir) + toolchain_file = os.path.join(toolchain_dir, "BUILD.gn") + write_toolchain_file(d, toolchain_file) +} +addtask write_toolchain_file after do_patch before do_configure + +# V8's JIT infrastructure requires binaries such as mksnapshot and +# mkpeephole to be run in the host during the build. However, these +# binaries must have the same bit-width as the target (e.g. a x86_64 +# host targeting ARMv6 needs to produce a 32-bit binary). Instead of +# depending on a third Yocto toolchain, we just build those binaries +# for the target and run them on the host with QEMU. +python do_create_v8_qemu_wrapper () { + """Creates a small wrapper that invokes QEMU to run some target V8 binaries + on the host.""" + qemu_libdirs = [d.expand('${STAGING_DIR_HOST}${libdir}'), + d.expand('${STAGING_DIR_HOST}${base_libdir}')] + qemu_cmd = qemu_wrapper_cmdline(d, d.getVar('STAGING_DIR_HOST', True), + qemu_libdirs) + wrapper_path = d.expand('${OUT_PATH}/v8-qemu-wrapper.sh') + with open(wrapper_path, 'w') as wrapper_file: + wrapper_file.write("""#!/bin/sh + +# This file has been generated automatically. +# It invokes QEMU to run binaries built for the target in the host during the +# build process. + +%s "$@" +""" % qemu_cmd) + os.chmod(wrapper_path, 0o755) +} +do_create_v8_qemu_wrapper[dirs] = "${OUT_PATH}" +addtask create_v8_qemu_wrapper after do_patch before do_configure + +do_configure () { + bbnote "do_configure:" + bbnote "Base out path: ${B}" + + export DEPOT_TOOLS_UPDATE=0 + export GCLIENT_PY3=1 + export PATH="${DEPOT_TOOLS_DIR}:$PATH" + export GN_DEFINES="${GN_DEFINES}" + export SSL_CERT_DIR="$OECORE_NATIVE_SYSROOT/etc/ssl/certs/" + cd ${S} + python3 ./build/linux/unbundle/replace_gn_files.py --system-libraries ${GN_UNBUNDLE_LIBS} + + # Download a few dependencies. Check the current chromium DEPS file when + # upgrading to a new milestone. + vpython3 third_party/depot_tools/download_from_google_storage.py --no_resume --extract --no_auth --bucket chromium-fonts -s third_party/test_fonts/test_fonts.tar.gz.sha1 + vpython3 third_party/depot_tools/download_from_google_storage.py --no_resume --extract --no_auth --bucket chromium-nodejs/16.13.0 -s third_party/node/linux/node-linux-x64.tar.gz.sha1 + vpython3 tools/rust/update_rust.py + + cd ${S}/cef + python3 tools/gclient_hook.py --base-out-path ${B} --bypass-sysroot-check +} + +do_compile[progress] = "outof:^\[(\d+)/(\d+)\]\s+" +do_compile () { + if [ ! -f ${OUT_PATH}/build.ninja ]; then + do_configure + fi + + export PATH="${DEPOT_TOOLS_DIR}:$PATH" + export PATH="$PATH:${S}/third_party/ninja" + ninja ${PARALLEL_MAKE} -C ${OUT_PATH} libcef chrome_sandbox +} + +do_install () { + cd ${S}/cef + python3 tools/make_distrib.py --output-dir ${OUT_PATH}/dist \ + --dist-path-name cef-minimal \ + --base-out-path ${B} \ + --no-docs \ + --no-symbols \ + --no-archive \ + --ninja-build \ + --minimal \ + --${GN_TARGET_ARCH_NAME}-build \ + --ozone + + install -d ${D}${CEF_DATA_PATH} + + cp -R --no-dereference --preserve=mode,links -v ${DIST_PATH}/* ${D}${CEF_DATA_PATH} + # TODO(rzanoni): Follow the wiki instructions to install the sandbox +} + +# TODO: fix QA issues, libraries in the wrong location +FILES:${PN} += " \ + ${CEF_DATA_PATH} \ +" + +INSANE_SKIP:${PN} += "libdir" + +PROVIDES:${PN} += "cef" diff --git a/recipes-wam/cef/files/cef/0001-Add-an-option-to-use-an-output-directory-outside-src.patch b/recipes-wam/cef/files/cef/0001-Add-an-option-to-use-an-output-directory-outside-src.patch new file mode 100644 index 00000000..af2ea0ba --- /dev/null +++ b/recipes-wam/cef/files/cef/0001-Add-an-option-to-use-an-output-directory-outside-src.patch @@ -0,0 +1,38 @@ +From 97e9e8dd589d7d3467d762f6ab25ec4a4f30505f Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 24 Apr 2023 10:52:57 +0200 +Subject: [PATCH 1/9] Add an option to use an output directory outside src + +--- + tools/make_distrib.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/tools/make_distrib.py b/tools/make_distrib.py +index c808ad7df..ea798b86f 100644 +--- a/tools/make_distrib.py ++++ b/tools/make_distrib.py +@@ -459,6 +459,12 @@ This utility builds the CEF Binary Distribution. + """ + + parser = OptionParser(description=disc) ++ ++parser.add_option( ++ '--base-out-path', ++ dest='baseoutpath', ++ default='', ++ help="Use an anternative base path for the generated gn outputs instead of using chromium source dir") + parser.add_option( + '--output-dir', + dest='outputdir', +@@ -700,6 +706,8 @@ else: + + # Determine the build directory paths. + out_dir = os.path.join(src_dir, 'out') ++if options.baseoutpath != '': ++ out_dir = os.path.join(options.baseoutpath, 'out') + build_dir_debug = os.path.join(out_dir, 'Debug' + build_dir_suffix) + build_dir_release = os.path.join(out_dir, 'Release' + build_dir_suffix) + +-- +2.42.0 + diff --git a/recipes-wam/cef/files/cef/0002-Add-an-option-to-override-the-default-distrib-direct.patch b/recipes-wam/cef/files/cef/0002-Add-an-option-to-override-the-default-distrib-direct.patch new file mode 100644 index 00000000..0061c4d1 --- /dev/null +++ b/recipes-wam/cef/files/cef/0002-Add-an-option-to-override-the-default-distrib-direct.patch @@ -0,0 +1,39 @@ +From d0ab00e0a22cab8f00d2b1b8c6904c68ff3fa09a Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 24 Apr 2023 13:56:10 +0200 +Subject: [PATCH 2/9] Add an option to override the default distrib directory + name + +--- + tools/make_distrib.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/tools/make_distrib.py b/tools/make_distrib.py +index ea798b86f..6ed748fe7 100644 +--- a/tools/make_distrib.py ++++ b/tools/make_distrib.py +@@ -465,6 +465,11 @@ parser.add_option( + dest='baseoutpath', + default='', + help="Use an anternative base path for the generated gn outputs instead of using chromium source dir") ++parser.add_option( ++ '--dist-path-name', ++ dest='distpathname', ++ default='', ++ help="Override the default name of the distribution output path.") + parser.add_option( + '--output-dir', + dest='outputdir', +@@ -677,6 +682,9 @@ else: + if options.ozone: + output_dir_name = output_dir_name + '_ozone' + ++if options.distpathname != '': ++ output_dir_name = options.distpathname + '_' + binary_arch ++ + output_dir = create_output_dir(output_dir_name, options.outputdir) + + # create the README.TXT file +-- +2.42.0 + diff --git a/recipes-wam/cef/files/cef/0003-Add-an-option-to-use-an-alternative-base-output-dire.patch b/recipes-wam/cef/files/cef/0003-Add-an-option-to-use-an-alternative-base-output-dire.patch new file mode 100644 index 00000000..600d59dc --- /dev/null +++ b/recipes-wam/cef/files/cef/0003-Add-an-option-to-use-an-alternative-base-output-dire.patch @@ -0,0 +1,61 @@ +From e54832c051aa34708025f350e81d08bafd3025f7 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Thu, 30 Mar 2023 15:22:32 +0200 +Subject: [PATCH 3/9] Add an option to use an alternative base output directory + +--- + tools/gclient_hook.py | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/tools/gclient_hook.py b/tools/gclient_hook.py +index c525984e3..3d4375ec0 100644 +--- a/tools/gclient_hook.py ++++ b/tools/gclient_hook.py +@@ -6,12 +6,23 @@ + from __future__ import absolute_import + from __future__ import print_function + from file_util import make_dir, write_file ++from optparse import OptionParser + from gclient_util import * + from gn_args import GetAllPlatformConfigs, GetConfigFileContents + import issue_1999 + import os + import sys + ++parser = OptionParser() ++ ++parser.add_option( ++ '--base-out-path', ++ dest='baseoutpath', ++ default='', ++ help="Use an anternative base path for the generated gn outputs instead of using chromium source dir") ++ ++(options, args) = parser.parse_args() ++ + # The CEF directory is the parent directory of _this_ script. + cef_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) + # The src directory is the parent directory of the CEF directory. +@@ -136,14 +147,18 @@ if platform == 'windows': + configs = GetAllPlatformConfigs(gn_args) + for dir, config in configs.items(): + # Create out directories and write the args.gn file. +- out_path = os.path.join(src_dir, 'out', dir) ++ base_out_dir = src_dir ++ if options.baseoutpath != '': ++ base_out_dir = options.baseoutpath ++ out_path = os.path.join(base_out_dir, 'out', dir) + make_dir(out_path, False) + args_gn_path = os.path.join(out_path, 'args.gn') + args_gn_contents = GetConfigFileContents(config) + write_file(args_gn_path, args_gn_contents) + + # Generate the Ninja config. +- cmd = ['gn', 'gen', os.path.join('out', dir)] ++ cmd = ['gn', 'gen', os.path.join('out', out_path)] ++ + if 'GN_ARGUMENTS' in os.environ.keys(): + cmd.extend(os.environ['GN_ARGUMENTS'].split(' ')) + RunAction(src_dir, cmd) +-- +2.42.0 + diff --git a/recipes-wam/cef/files/cef/0004-Add-an-option-to-bypass-sysroot-checking-and-force.patch b/recipes-wam/cef/files/cef/0004-Add-an-option-to-bypass-sysroot-checking-and-force.patch new file mode 100644 index 00000000..c5790744 --- /dev/null +++ b/recipes-wam/cef/files/cef/0004-Add-an-option-to-bypass-sysroot-checking-and-force.patch @@ -0,0 +1,134 @@ +From 26d02223b99765f4c6d5ce5807947d4e0c925a0b Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Tue, 16 May 2023 16:11:15 +0200 +Subject: [PATCH 4/9] Add an option to bypass sysroot checking and force + +--- + tools/gclient_hook.py | 8 +++++++- + tools/gn_args.py | 28 ++++++++++++++-------------- + 2 files changed, 21 insertions(+), 15 deletions(-) + +diff --git a/tools/gclient_hook.py b/tools/gclient_hook.py +index 3d4375ec0..c971b9399 100644 +--- a/tools/gclient_hook.py ++++ b/tools/gclient_hook.py +@@ -20,6 +20,12 @@ parser.add_option( + dest='baseoutpath', + default='', + help="Use an anternative base path for the generated gn outputs instead of using chromium source dir") ++parser.add_option( ++ '--bypass-sysroot-check', ++ action='store_true', ++ dest='bypasssysrootcheck', ++ default=False, ++ help='Don\'t chech if the sysroot exist while generating output directores.') + + (options, args) = parser.parse_args() + +@@ -144,7 +150,7 @@ if platform == 'windows': + gn_args['windows_sdk_path'] = os.environ['SDK_ROOT'] + gn_args['windows_sdk_version'] = os.environ['SDK_VERSION'] + +-configs = GetAllPlatformConfigs(gn_args) ++configs = GetAllPlatformConfigs(gn_args, bypass_sysroot_check=options.bypasssysrootcheck) + for dir, config in configs.items(): + # Create out directories and write the args.gn file. + base_out_dir = src_dir +diff --git a/tools/gn_args.py b/tools/gn_args.py +index c1acac17b..80545da49 100644 +--- a/tools/gn_args.py ++++ b/tools/gn_args.py +@@ -327,7 +327,7 @@ def GetMergedArgs(build_args): + return MergeDicts(dict, required) + + +-def ValidateArgs(args): ++def ValidateArgs(args, bypass_sysroot_check=False): + """ + Validate GN arg combinations that we know about. Also provide suggestions + where appropriate. +@@ -365,11 +365,11 @@ def ValidateArgs(args): + + if platform == 'linux': + if target_cpu == 'x86': +- assert use_sysroot, 'target_cpu="x86" requires use_sysroot=true' ++ assert use_sysroot or bypass_sysroot_check, 'target_cpu="x86" requires use_sysroot=true' + elif target_cpu == 'arm': +- assert use_sysroot, 'target_cpu="arm" requires use_sysroot=true' ++ assert use_sysroot or bypass_sysroot_check, 'target_cpu="arm" requires use_sysroot=true' + elif target_cpu == 'arm64': +- assert use_sysroot, 'target_cpu="arm64" requires use_sysroot=true' ++ assert use_sysroot or bypass_sysroot_check, 'target_cpu="arm64" requires use_sysroot=true' + + # ASAN requires Release builds. + if is_asan: +@@ -460,7 +460,7 @@ def ValidateArgs(args): + "visual_studio_path requires INCLUDE, LIB and PATH env variables" + + +-def GetConfigArgs(args, is_debug, cpu): ++def GetConfigArgs(args, is_debug, cpu, bypass_sysroot_check=False): + """ + Return merged GN args for the configuration and validate. + """ +@@ -490,11 +490,11 @@ def GetConfigArgs(args, is_debug, cpu): + if key.startswith('arm_'): + del result[key] + +- ValidateArgs(result) ++ ValidateArgs(result, bypass_sysroot_check) + return result + + +-def GetConfigArgsSandbox(platform, args, is_debug, cpu): ++def GetConfigArgsSandbox(platform, args, is_debug, cpu, bypass_sysroot_check=False): + """ + Return merged GN args for the cef_sandbox configuration and validate. + """ +@@ -566,7 +566,7 @@ def LinuxSysrootExists(cpu): + return os.path.isdir(os.path.join(sysroot_root, sysroot_name)) + + +-def GetAllPlatformConfigs(build_args): ++def GetAllPlatformConfigs(build_args, bypass_sysroot_check=False): + """ + Return a map of directory name to GN args for the current platform. + """ +@@ -586,10 +586,10 @@ def GetAllPlatformConfigs(build_args): + + if platform == 'linux': + use_sysroot = GetArgValue(args, 'use_sysroot') +- if use_sysroot: ++ if bypass_sysroot_check or use_sysroot: + # Only generate configurations for sysroots that have been installed. + for cpu in ('x64', 'arm', 'arm64'): +- if LinuxSysrootExists(cpu): ++ if bypass_sysroot_check or LinuxSysrootExists(cpu): + supported_cpus.append(cpu) + else: + msg('Not generating %s configuration due to missing sysroot directory' +@@ -611,17 +611,17 @@ def GetAllPlatformConfigs(build_args): + + for cpu in supported_cpus: + if create_debug: +- result['Debug_GN_' + cpu] = GetConfigArgs(args, True, cpu) +- result['Release_GN_' + cpu] = GetConfigArgs(args, False, cpu) ++ result['Debug_GN_' + cpu] = GetConfigArgs(args, True, cpu, bypass_sysroot_check) ++ result['Release_GN_' + cpu] = GetConfigArgs(args, False, cpu, bypass_sysroot_check) + + if platform in ('windows', 'mac') and GetArgValue(args, + 'is_official_build'): + # Build cef_sandbox.lib with a different configuration. + if create_debug: + result['Debug_GN_' + cpu + '_sandbox'] = GetConfigArgsSandbox( +- platform, args, True, cpu) ++ platform, args, True, cpu, bypass_sysroot_check) + result['Release_GN_' + cpu + '_sandbox'] = GetConfigArgsSandbox( +- platform, args, False, cpu) ++ platform, args, False, cpu, bypass_sysroot_check) + + return result + +-- +2.42.0 + diff --git a/recipes-wam/cef/files/cef/0005-Add-AGL-wayland-window-related-calls.patch b/recipes-wam/cef/files/cef/0005-Add-AGL-wayland-window-related-calls.patch new file mode 100644 index 00000000..d717b817 --- /dev/null +++ b/recipes-wam/cef/files/cef/0005-Add-AGL-wayland-window-related-calls.patch @@ -0,0 +1,198 @@ +From ee2c3e430fd0d1025e46c108a79a4e0b07608dff Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Thu, 18 May 2023 10:34:08 +0200 +Subject: [PATCH 5/9] Add AGL wayland window related calls + +--- + include/views/cef_window.h | 34 ++++++++++++++++ + libcef/browser/views/view_util.h | 10 +++++ + libcef/browser/views/view_util_aura.cc | 54 ++++++++++++++++++++++++++ + libcef/browser/views/window_impl.cc | 24 ++++++++++++ + libcef/browser/views/window_impl.h | 10 +++++ + 5 files changed, 132 insertions(+) + +diff --git a/include/views/cef_window.h b/include/views/cef_window.h +index ec3843b25..22fe2e2a1 100644 +--- a/include/views/cef_window.h ++++ b/include/views/cef_window.h +@@ -366,6 +366,40 @@ class CefWindow : public CefPanel { + /// + /*--cef()--*/ + virtual void RemoveAllAccelerators() = 0; ++ ++ // AGL-related calls ++ ++ /// ++ /// Tells the agl compositor to activate the app ++ /// ++ /*--cef()--*/ ++ virtual void AglActivateApp(const CefString& app) = 0; ++ ++ /// ++ /// Tells the agl compositor the application id ++ /// ++ /*--cef()--*/ ++ virtual void AglSetAppId(const CefString& app_id) = 0; ++ ++ /// ++ /// Tells the agl compositor that everything is set-up and good to go ++ /// ++ /*--cef()--*/ ++ virtual void AglSetAppReady() = 0; ++ ++ /// ++ /// Tells the agl compositor that the app is the background application ++ /// ++ /*--cef()--*/ ++ virtual void AglSetBackGroundApp() = 0; ++ ++ /// ++ /// Tells the agl compositor that the app is a panel ++ /// ++ /*--cef()--*/ ++ virtual void AglSetPanelApp(uint32_t edge) = 0; ++ ++ // ----------------- + }; + + #endif // CEF_INCLUDE_VIEWS_CEF_WINDOW_H_ +diff --git a/libcef/browser/views/view_util.h b/libcef/browser/views/view_util.h +index a5fb6e522..bc12a9ddc 100644 +--- a/libcef/browser/views/view_util.h ++++ b/libcef/browser/views/view_util.h +@@ -165,6 +165,16 @@ views::View* GetHostView(views::Widget* widget); + float GetNSWindowTitleBarHeight(views::Widget* widget); + #endif + ++// AGL-Related calls ++ ++void AglActivateApp(views::Widget* widget, const std::string& app); ++void AglSetAppId(views::Widget* widget, const std::string& app_id); ++void AglSetAppReady(views::Widget* widget); ++void AglSetBackGroundApp(views::Widget* widget); ++void AglSetPanelApp(views::Widget* widget, uint32_t edge); ++ ++// ----------------- ++ + } // namespace view_util + + #endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_UTIL_H_ +diff --git a/libcef/browser/views/view_util_aura.cc b/libcef/browser/views/view_util_aura.cc +index 24be3311b..2dabf5eae 100644 +--- a/libcef/browser/views/view_util_aura.cc ++++ b/libcef/browser/views/view_util_aura.cc +@@ -58,4 +58,58 @@ views::View* GetHostView(views::Widget* widget) { + return widget->GetNativeView()->GetProperty(views::kHostViewKey); + } + ++// AGL-Related calls ++ ++void AglActivateApp(views::Widget* widget, const std::string& app) { ++ if (!widget) { ++ return; ++ } ++ aura::Window* window = widget->GetNativeWindow(); ++ if (window && window->GetRootWindow()) { ++ return window->GetHost()->SetAglActivateApp(app); ++ } ++} ++ ++void AglSetAppId(views::Widget* widget, const std::string& app_id) { ++ if (!widget) { ++ return; ++ } ++ aura::Window* window = widget->GetNativeWindow(); ++ if (window && window->GetRootWindow()) { ++ return window->GetHost()->SetAglAppId(app_id); ++ } ++} ++ ++void AglSetAppReady(views::Widget* widget) { ++ if (!widget) { ++ return; ++ } ++ aura::Window* window = widget->GetNativeWindow(); ++ if (window && window->GetRootWindow()) { ++ return window->GetHost()->SetAglReady(); ++ } ++} ++ ++void AglSetBackGroundApp(views::Widget* widget) { ++ if (!widget) { ++ return; ++ } ++ aura::Window* window = widget->GetNativeWindow(); ++ if (window && window->GetRootWindow()) { ++ return window->GetHost()->SetAglBackground(); ++ } ++} ++ ++void AglSetPanelApp(views::Widget* widget, uint32_t edge) { ++ if (!widget) { ++ return; ++ } ++ aura::Window* window = widget->GetNativeWindow(); ++ if (window && window->GetRootWindow()) { ++ return window->GetHost()->SetAglPanel(edge); ++ } ++} ++ ++// ----------------- ++ + } // namespace view_util +diff --git a/libcef/browser/views/window_impl.cc b/libcef/browser/views/window_impl.cc +index 3da94b08a..8b347bf4a 100644 +--- a/libcef/browser/views/window_impl.cc ++++ b/libcef/browser/views/window_impl.cc +@@ -768,3 +768,27 @@ void CefWindowImpl::CreateWidget(gfx::AcceleratedWidget parent_widget) { + delegate()->OnWindowCreated(this); + } + } ++ ++// AGL-Related calls ++ ++void CefWindowImpl::AglActivateApp(const CefString& app) { ++ view_util::AglActivateApp(widget_, app); ++} ++ ++void CefWindowImpl::AglSetAppId(const CefString& app_id) { ++ view_util::AglSetAppId(widget_, app_id); ++} ++ ++void CefWindowImpl::AglSetAppReady() { ++ view_util::AglSetAppReady(widget_); ++} ++ ++void CefWindowImpl::AglSetBackGroundApp() { ++ view_util::AglSetBackGroundApp(widget_); ++} ++ ++void CefWindowImpl::AglSetPanelApp(uint32_t edge) { ++ view_util::AglSetPanelApp(widget_, edge); ++} ++ ++// ----------------- +diff --git a/libcef/browser/views/window_impl.h b/libcef/browser/views/window_impl.h +index fae0ae832..20514fc32 100644 +--- a/libcef/browser/views/window_impl.h ++++ b/libcef/browser/views/window_impl.h +@@ -134,6 +134,16 @@ class CefWindowImpl + views::Widget* widget() const { return widget_; } + bool initialized() const { return initialized_; } + ++ // AGL-Related calls ++ ++ void AglActivateApp(const CefString& app) override; ++ void AglSetAppId(const CefString& app_id) override; ++ void AglSetAppReady() override; ++ void AglSetBackGroundApp() override; ++ void AglSetPanelApp(uint32_t edge) override; ++ ++ // ----------------- ++ + private: + // Create a new implementation object. + // Always call Initialize() after creation. +-- +2.42.0 + diff --git a/recipes-wam/cef/files/cef/0006-Add-a-method-to-check-if-the-agl-window-is-configure.patch b/recipes-wam/cef/files/cef/0006-Add-a-method-to-check-if-the-agl-window-is-configure.patch new file mode 100644 index 00000000..0f5c4c5f --- /dev/null +++ b/recipes-wam/cef/files/cef/0006-Add-a-method-to-check-if-the-agl-window-is-configure.patch @@ -0,0 +1,129 @@ +From 7eefab1c1a8938145f9fb3a5d7a8fa58ca7ad695 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Fri, 30 Jun 2023 10:27:03 +0200 +Subject: [PATCH 6/9] Add a method to check if the agl window is configured + +--- + include/views/cef_window.h | 6 ++++++ + libcef/browser/views/view_util.h | 1 + + libcef/browser/views/view_util_aura.cc | 20 +++++++++++++++----- + libcef/browser/views/window_impl.cc | 4 ++++ + libcef/browser/views/window_impl.h | 1 + + 5 files changed, 27 insertions(+), 5 deletions(-) + +diff --git a/include/views/cef_window.h b/include/views/cef_window.h +index 22fe2e2a1..c34963302 100644 +--- a/include/views/cef_window.h ++++ b/include/views/cef_window.h +@@ -399,6 +399,12 @@ class CefWindow : public CefPanel { + /*--cef()--*/ + virtual void AglSetPanelApp(uint32_t edge) = 0; + ++ /// ++ /// Tells if the window wayland surface is configured ++ /// ++ /*--cef()--*/ ++ virtual bool IsSurfaceConfigured() = 0; ++ + // ----------------- + }; + +diff --git a/libcef/browser/views/view_util.h b/libcef/browser/views/view_util.h +index bc12a9ddc..bf657fd39 100644 +--- a/libcef/browser/views/view_util.h ++++ b/libcef/browser/views/view_util.h +@@ -172,6 +172,7 @@ void AglSetAppId(views::Widget* widget, const std::string& app_id); + void AglSetAppReady(views::Widget* widget); + void AglSetBackGroundApp(views::Widget* widget); + void AglSetPanelApp(views::Widget* widget, uint32_t edge); ++bool IsSurfaceConfigured(views::Widget* widget); + + // ----------------- + +diff --git a/libcef/browser/views/view_util_aura.cc b/libcef/browser/views/view_util_aura.cc +index 2dabf5eae..2946a2d81 100644 +--- a/libcef/browser/views/view_util_aura.cc ++++ b/libcef/browser/views/view_util_aura.cc +@@ -66,7 +66,7 @@ void AglActivateApp(views::Widget* widget, const std::string& app) { + } + aura::Window* window = widget->GetNativeWindow(); + if (window && window->GetRootWindow()) { +- return window->GetHost()->SetAglActivateApp(app); ++ window->GetHost()->SetAglActivateApp(app); + } + } + +@@ -76,7 +76,7 @@ void AglSetAppId(views::Widget* widget, const std::string& app_id) { + } + aura::Window* window = widget->GetNativeWindow(); + if (window && window->GetRootWindow()) { +- return window->GetHost()->SetAglAppId(app_id); ++ window->GetHost()->SetAglAppId(app_id); + } + } + +@@ -86,7 +86,7 @@ void AglSetAppReady(views::Widget* widget) { + } + aura::Window* window = widget->GetNativeWindow(); + if (window && window->GetRootWindow()) { +- return window->GetHost()->SetAglReady(); ++ window->GetHost()->SetAglReady(); + } + } + +@@ -96,7 +96,7 @@ void AglSetBackGroundApp(views::Widget* widget) { + } + aura::Window* window = widget->GetNativeWindow(); + if (window && window->GetRootWindow()) { +- return window->GetHost()->SetAglBackground(); ++ window->GetHost()->SetAglBackground(); + } + } + +@@ -106,7 +106,17 @@ void AglSetPanelApp(views::Widget* widget, uint32_t edge) { + } + aura::Window* window = widget->GetNativeWindow(); + if (window && window->GetRootWindow()) { +- return window->GetHost()->SetAglPanel(edge); ++ window->GetHost()->SetAglPanel(edge); ++ } ++} ++ ++bool IsSurfaceConfigured(views::Widget* widget) { ++ if (!widget) { ++ return false; ++ } ++ aura::Window* window = widget->GetNativeWindow(); ++ if (window && window->GetRootWindow()) { ++ return window->GetHost()->IsSurfaceConfigured(); + } + } + +diff --git a/libcef/browser/views/window_impl.cc b/libcef/browser/views/window_impl.cc +index 8b347bf4a..8edac98b5 100644 +--- a/libcef/browser/views/window_impl.cc ++++ b/libcef/browser/views/window_impl.cc +@@ -791,4 +791,8 @@ void CefWindowImpl::AglSetPanelApp(uint32_t edge) { + view_util::AglSetPanelApp(widget_, edge); + } + ++bool CefWindowImpl::IsSurfaceConfigured() { ++ return view_util::IsSurfaceConfigured(widget_); ++} ++ + // ----------------- +diff --git a/libcef/browser/views/window_impl.h b/libcef/browser/views/window_impl.h +index 20514fc32..7f7b47e1a 100644 +--- a/libcef/browser/views/window_impl.h ++++ b/libcef/browser/views/window_impl.h +@@ -141,6 +141,7 @@ class CefWindowImpl + void AglSetAppReady() override; + void AglSetBackGroundApp() override; + void AglSetPanelApp(uint32_t edge) override; ++ bool IsSurfaceConfigured() override; + + // ----------------- + +-- +2.42.0 + diff --git a/recipes-wam/cef/files/cef/0007-Add-the-SetActivateRegion-method.patch b/recipes-wam/cef/files/cef/0007-Add-the-SetActivateRegion-method.patch new file mode 100644 index 00000000..e2d87065 --- /dev/null +++ b/recipes-wam/cef/files/cef/0007-Add-the-SetActivateRegion-method.patch @@ -0,0 +1,101 @@ +From 6515114202a98f81950687b6656151fa7cfd5ab6 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Sun, 2 Jul 2023 12:08:59 +0200 +Subject: [PATCH 7/9] Add the SetActivateRegion method + +--- + include/views/cef_window.h | 6 ++++++ + libcef/browser/views/view_util.h | 1 + + libcef/browser/views/view_util_aura.cc | 17 +++++++++++++++++ + libcef/browser/views/window_impl.cc | 7 +++++++ + libcef/browser/views/window_impl.h | 1 + + 5 files changed, 32 insertions(+) + +diff --git a/include/views/cef_window.h b/include/views/cef_window.h +index c34963302..9f196a1e7 100644 +--- a/include/views/cef_window.h ++++ b/include/views/cef_window.h +@@ -405,6 +405,12 @@ class CefWindow : public CefPanel { + /*--cef()--*/ + virtual bool IsSurfaceConfigured() = 0; + ++ /// ++ /// A hint for the compositor to use a custom area, rather than inferring the activation area. ++ /// ++ /*--cef()--*/ ++ virtual void SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0; ++ + // ----------------- + }; + +diff --git a/libcef/browser/views/view_util.h b/libcef/browser/views/view_util.h +index bf657fd39..50037a198 100644 +--- a/libcef/browser/views/view_util.h ++++ b/libcef/browser/views/view_util.h +@@ -173,6 +173,7 @@ void AglSetAppReady(views::Widget* widget); + void AglSetBackGroundApp(views::Widget* widget); + void AglSetPanelApp(views::Widget* widget, uint32_t edge); + bool IsSurfaceConfigured(views::Widget* widget); ++void SetupActivationArea(views::Widget* widget, uint32_t x, uint32_t y, uint32_t width, uint32_t height); + + // ----------------- + +diff --git a/libcef/browser/views/view_util_aura.cc b/libcef/browser/views/view_util_aura.cc +index 2946a2d81..bf435078d 100644 +--- a/libcef/browser/views/view_util_aura.cc ++++ b/libcef/browser/views/view_util_aura.cc +@@ -120,6 +120,23 @@ bool IsSurfaceConfigured(views::Widget* widget) { + } + } + ++void SetupActivationArea(views::Widget* widget, ++ uint32_t x, ++ uint32_t y, ++ uint32_t width, ++ uint32_t height) { ++ if (!widget) { ++ return; ++ } ++ aura::Window* window = widget->GetNativeWindow(); ++ if (window && window->GetRootWindow()) { ++ window->GetHost()->SetupActivationArea(x, ++ y, ++ width, ++ height); ++ } ++} ++ + // ----------------- + + } // namespace view_util +diff --git a/libcef/browser/views/window_impl.cc b/libcef/browser/views/window_impl.cc +index 8edac98b5..12858364e 100644 +--- a/libcef/browser/views/window_impl.cc ++++ b/libcef/browser/views/window_impl.cc +@@ -795,4 +795,11 @@ bool CefWindowImpl::IsSurfaceConfigured() { + return view_util::IsSurfaceConfigured(widget_); + } + ++void CefWindowImpl::SetupActivationArea(uint32_t x, ++ uint32_t y, ++ uint32_t width, ++ uint32_t height) { ++ view_util::SetupActivationArea(widget_, x, y, width, height); ++} ++ + // ----------------- +diff --git a/libcef/browser/views/window_impl.h b/libcef/browser/views/window_impl.h +index 7f7b47e1a..aaca3c281 100644 +--- a/libcef/browser/views/window_impl.h ++++ b/libcef/browser/views/window_impl.h +@@ -142,6 +142,7 @@ class CefWindowImpl + void AglSetBackGroundApp() override; + void AglSetPanelApp(uint32_t edge) override; + bool IsSurfaceConfigured() override; ++ void SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override; + + // ----------------- + +-- +2.42.0 + diff --git a/recipes-wam/cef/files/cef/0008-Allow-passing-the-app_id-on-widget-creation.patch b/recipes-wam/cef/files/cef/0008-Allow-passing-the-app_id-on-widget-creation.patch new file mode 100644 index 00000000..e0a79b6c --- /dev/null +++ b/recipes-wam/cef/files/cef/0008-Allow-passing-the-app_id-on-widget-creation.patch @@ -0,0 +1,130 @@ +From 5a8d9996ee7b3ce77f7b3fd3c7839806a034ea16 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Tue, 4 Jul 2023 12:10:41 +0200 +Subject: [PATCH 08/10] Allow passing the app_id on widget creation + +--- + include/views/cef_window.h | 6 ++++++ + libcef/browser/views/window_impl.cc | 13 +++++++++---- + libcef/browser/views/window_impl.h | 6 ++++-- + libcef/browser/views/window_view.cc | 3 ++- + libcef/browser/views/window_view.h | 2 +- + 5 files changed, 22 insertions(+), 8 deletions(-) + +diff --git a/include/views/cef_window.h b/include/views/cef_window.h +index 9f196a1e7..16c854b09 100644 +--- a/include/views/cef_window.h ++++ b/include/views/cef_window.h +@@ -65,6 +65,12 @@ class CefWindow : public CefPanel { + CefRefPtr<CefWindowDelegate> delegate); + + /// ++ /// Create a new Window with the provided ID ++ /// ++ /*--cef()--*/ ++ static CefRefPtr<CefWindow> CreateTopLevelWindowWithId( ++ CefRefPtr<CefWindowDelegate> delegate, const CefString& app_id); ++ /// + /// Show the Window. + /// + /*--cef()--*/ +diff --git a/libcef/browser/views/window_impl.cc b/libcef/browser/views/window_impl.cc +index 12858364e..f0fe9dfb2 100644 +--- a/libcef/browser/views/window_impl.cc ++++ b/libcef/browser/views/window_impl.cc +@@ -110,14 +110,19 @@ CefRefPtr<CefWindow> CefWindow::CreateTopLevelWindow( + return CefWindowImpl::Create(delegate, gfx::kNullAcceleratedWidget); + } + ++CefRefPtr<CefWindow> CefWindow::CreateTopLevelWindowWithId( ++ CefRefPtr<CefWindowDelegate> delegate, const CefString& app_id) { ++ return CefWindowImpl::Create(delegate, gfx::kNullAcceleratedWidget, app_id); ++} ++ + // static + CefRefPtr<CefWindowImpl> CefWindowImpl::Create( + CefRefPtr<CefWindowDelegate> delegate, +- gfx::AcceleratedWidget parent_widget) { ++ gfx::AcceleratedWidget parent_widget, const CefString& app_id) { + CEF_REQUIRE_UIT_RETURN(nullptr); + CefRefPtr<CefWindowImpl> window = new CefWindowImpl(delegate); + window->Initialize(); +- window->CreateWidget(parent_widget); ++ window->CreateWidget(parent_widget, app_id); + return window; + } + +@@ -745,10 +750,10 @@ void CefWindowImpl::InitializeRootView() { + static_cast<CefWindowView*>(root_view())->Initialize(); + } + +-void CefWindowImpl::CreateWidget(gfx::AcceleratedWidget parent_widget) { ++void CefWindowImpl::CreateWidget(gfx::AcceleratedWidget parent_widget, const CefString& app_id) { + DCHECK(!widget_); + +- root_view()->CreateWidget(parent_widget); ++ root_view()->CreateWidget(parent_widget, app_id); + widget_ = root_view()->GetWidget(); + DCHECK(widget_); + +diff --git a/libcef/browser/views/window_impl.h b/libcef/browser/views/window_impl.h +index aaca3c281..1c5be736f 100644 +--- a/libcef/browser/views/window_impl.h ++++ b/libcef/browser/views/window_impl.h +@@ -36,7 +36,8 @@ class CefWindowImpl + // Create a new CefWindow instance. |delegate| may be nullptr. |parent_widget| + // will be used when creating a Chrome child window. + static CefRefPtr<CefWindowImpl> Create(CefRefPtr<CefWindowDelegate> delegate, +- gfx::AcceleratedWidget parent_widget); ++ gfx::AcceleratedWidget parent_widget, ++ const CefString& app_id = ""); + + // CefWindow methods: + void Show() override; +@@ -157,7 +158,8 @@ class CefWindowImpl + void InitializeRootView() override; + + // Initialize the Widget. +- void CreateWidget(gfx::AcceleratedWidget parent_widget); ++ void CreateWidget(gfx::AcceleratedWidget parent_widget, ++ const CefString& app_id = ""); + + views::Widget* widget_ = nullptr; + +diff --git a/libcef/browser/views/window_view.cc b/libcef/browser/views/window_view.cc +index 2331caaea..5e4cb6b53 100644 +--- a/libcef/browser/views/window_view.cc ++++ b/libcef/browser/views/window_view.cc +@@ -371,7 +371,7 @@ CefWindowView::CefWindowView(CefWindowDelegate* cef_delegate, + DCHECK(window_delegate_); + } + +-void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) { ++void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget, const CefString& app_id) { + DCHECK(!GetWidget()); + + // |widget| is owned by the NativeWidget and will be destroyed in response to +@@ -381,6 +381,7 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) { + + views::Widget::InitParams params; + params.delegate = this; ++ params.wayland_app_id = app_id; + + views::Widget* host_widget = nullptr; + +diff --git a/libcef/browser/views/window_view.h b/libcef/browser/views/window_view.h +index b065f3700..c15e75d65 100644 +--- a/libcef/browser/views/window_view.h ++++ b/libcef/browser/views/window_view.h +@@ -52,7 +52,7 @@ class CefWindowView + CefWindowView& operator=(const CefWindowView&) = delete; + + // Create the Widget. +- void CreateWidget(gfx::AcceleratedWidget parent_widget); ++ void CreateWidget(gfx::AcceleratedWidget parent_widget, const CefString& app_id); + + // Returns the CefWindow associated with this view. See comments on + // CefViewView::GetCefView. +-- +2.42.1 + diff --git a/recipes-wam/cef/files/cef/0009-Update-generated-api.patch b/recipes-wam/cef/files/cef/0009-Update-generated-api.patch new file mode 100644 index 00000000..aaf8dd14 --- /dev/null +++ b/recipes-wam/cef/files/cef/0009-Update-generated-api.patch @@ -0,0 +1,753 @@ +From c10306e9da62f9c36513b98affc4589ea5016677 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 6 Nov 2023 16:00:35 -0300 +Subject: [PATCH 09/10] Update generated api + +Command used: + +./translator.sh --classes CefWindow CefWindowDelegate CefView CefViewDeleate --root-dir +--- + include/capi/cef_cookie_capi.h | 6 +- + include/capi/cef_media_router_capi.h | 6 +- + include/capi/cef_scheme_capi.h | 10 +- + include/capi/views/cef_window_capi.h | 52 +++++++- + include/cef_api_hash.h | 8 +- + libcef_dll/cpptoc/views/window_cpptoc.cc | 153 ++++++++++++++++++++++- + libcef_dll/ctocpp/views/window_ctocpp.cc | 148 +++++++++++++++++++++- + libcef_dll/ctocpp/views/window_ctocpp.h | 12 +- + libcef_dll/wrapper/libcef_dll_dylib.cc | 72 +++++++---- + 9 files changed, 422 insertions(+), 45 deletions(-) + +diff --git a/include/capi/cef_cookie_capi.h b/include/capi/cef_cookie_capi.h +index 1be978bfd..f6f19ede2 100644 +--- a/include/capi/cef_cookie_capi.h ++++ b/include/capi/cef_cookie_capi.h +@@ -33,7 +33,7 @@ + // by hand. See the translator.README.txt file in the tools directory for + // more information. + // +-// $hash=598c6f530b2e2553197d8c6a72ad9e2bf72b5443$ ++// $hash=8093e45bcbd09f41f21c0cb7c8719166cc481529$ + // + + #ifndef CEF_INCLUDE_CAPI_CEF_COOKIE_CAPI_H_ +@@ -126,8 +126,8 @@ typedef struct _cef_cookie_manager_t { + /// cef_settings_t.cache_path if specified or in memory otherwise. If |callback| + /// is non-NULL it will be executed asnychronously on the UI thread after the + /// manager's storage has been initialized. Using this function is equivalent to +-/// calling cef_request_context_t::cef_request_context_get_global_context()->Get +-/// DefaultCookieManager(). ++/// calling cef_request_context_t::cef_request_context_get_global_context()- ++/// >GetDefaultCookieManager(). + /// + CEF_EXPORT cef_cookie_manager_t* cef_cookie_manager_get_global_manager( + struct _cef_completion_callback_t* callback); +diff --git a/include/capi/cef_media_router_capi.h b/include/capi/cef_media_router_capi.h +index 27f9d0e15..9df759013 100644 +--- a/include/capi/cef_media_router_capi.h ++++ b/include/capi/cef_media_router_capi.h +@@ -33,7 +33,7 @@ + // by hand. See the translator.README.txt file in the tools directory for + // more information. + // +-// $hash=de4a9b856c6951231f446991a9b1efb89096ad3b$ ++// $hash=d3f29de333c90768caac6aee2b7eb2db5f593515$ + // + + #ifndef CEF_INCLUDE_CAPI_CEF_MEDIA_ROUTER_CAPI_H_ +@@ -114,8 +114,8 @@ typedef struct _cef_media_router_t { + /// Returns the MediaRouter object associated with the global request context. + /// If |callback| is non-NULL it will be executed asnychronously on the UI + /// thread after the manager's storage has been initialized. Equivalent to +-/// calling cef_request_context_t::cef_request_context_get_global_context()->get +-/// _media_router(). ++/// calling cef_request_context_t::cef_request_context_get_global_context()- ++/// >get_media_router(). + /// + CEF_EXPORT cef_media_router_t* cef_media_router_get_global( + struct _cef_completion_callback_t* callback); +diff --git a/include/capi/cef_scheme_capi.h b/include/capi/cef_scheme_capi.h +index 5f8796287..bdcd6cc3b 100644 +--- a/include/capi/cef_scheme_capi.h ++++ b/include/capi/cef_scheme_capi.h +@@ -33,7 +33,7 @@ + // by hand. See the translator.README.txt file in the tools directory for + // more information. + // +-// $hash=6b6a7f754abc9ee5d6f775ba9eee802d3244faf5$ ++// $hash=794d4c01f06c656c425779b0189a3b52820498ed$ + // + + #ifndef CEF_INCLUDE_CAPI_CEF_SCHEME_CAPI_H_ +@@ -116,8 +116,8 @@ typedef struct _cef_scheme_handler_factory_t { + /// matches the specified |scheme_name| and optional |domain_name|. Returns + /// false (0) if an error occurs. This function may be called on any thread in + /// the browser process. Using this function is equivalent to calling cef_reques +-/// t_context_t::cef_request_context_get_global_context()->register_scheme_handl +-/// er_factory(). ++/// t_context_t::cef_request_context_get_global_context()- ++/// >register_scheme_handler_factory(). + /// + CEF_EXPORT int cef_register_scheme_handler_factory( + const cef_string_t* scheme_name, +@@ -128,8 +128,8 @@ CEF_EXPORT int cef_register_scheme_handler_factory( + /// Clear all scheme handler factories registered with the global request + /// context. Returns false (0) on error. This function may be called on any + /// thread in the browser process. Using this function is equivalent to calling +-/// cef_request_context_t::cef_request_context_get_global_context()->clear_schem +-/// e_handler_factories(). ++/// cef_request_context_t::cef_request_context_get_global_context()- ++/// >clear_scheme_handler_factories(). + /// + CEF_EXPORT int cef_clear_scheme_handler_factories(void); + +diff --git a/include/capi/views/cef_window_capi.h b/include/capi/views/cef_window_capi.h +index e5e04e83e..b0be32ad2 100644 +--- a/include/capi/views/cef_window_capi.h ++++ b/include/capi/views/cef_window_capi.h +@@ -33,7 +33,7 @@ + // by hand. See the translator.README.txt file in the tools directory for + // more information. + // +-// $hash=4b43fe0b493d860e8b28d7a6d892db49d1135b34$ ++// $hash=53e1bba9189f03819c0646670cab8f9caabc74d6$ + // + + #ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_CAPI_H_ +@@ -353,6 +353,49 @@ typedef struct _cef_window_t { + /// Remove all keyboard accelerators. + /// + void(CEF_CALLBACK* remove_all_accelerators)(struct _cef_window_t* self); ++ ++ /// ++ /// Tells the agl compositor to activate the app ++ /// ++ void(CEF_CALLBACK* agl_activate_app)(struct _cef_window_t* self, ++ const cef_string_t* app); ++ ++ /// ++ /// Tells the agl compositor the application id ++ /// ++ void(CEF_CALLBACK* agl_set_app_id)(struct _cef_window_t* self, ++ const cef_string_t* app_id); ++ ++ /// ++ /// Tells the agl compositor that everything is set-up and good to go ++ /// ++ void(CEF_CALLBACK* agl_set_app_ready)(struct _cef_window_t* self); ++ ++ /// ++ /// Tells the agl compositor that the app is the background application ++ /// ++ void(CEF_CALLBACK* agl_set_back_ground_app)(struct _cef_window_t* self); ++ ++ /// ++ /// Tells the agl compositor that the app is a panel ++ /// ++ void(CEF_CALLBACK* agl_set_panel_app)(struct _cef_window_t* self, ++ uint32_t edge); ++ ++ /// ++ /// Tells if the window wayland surface is configured ++ /// ++ int(CEF_CALLBACK* is_surface_configured)(struct _cef_window_t* self); ++ ++ /// ++ /// A hint for the compositor to use a custom area, rather than inferring the ++ /// activation area. ++ /// ++ void(CEF_CALLBACK* setup_activation_area)(struct _cef_window_t* self, ++ uint32_t x, ++ uint32_t y, ++ uint32_t width, ++ uint32_t height); + } cef_window_t; + + /// +@@ -361,6 +404,13 @@ typedef struct _cef_window_t { + CEF_EXPORT cef_window_t* cef_window_create_top_level( + struct _cef_window_delegate_t* delegate); + ++/// ++/// Create a new Window with the provided ID ++/// ++CEF_EXPORT cef_window_t* cef_window_create_top_level_with_id( ++ struct _cef_window_delegate_t* delegate, ++ const cef_string_t* app_id); ++ + #ifdef __cplusplus + } + #endif +diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h +index 90142ccb0..6af07332a 100644 +--- a/include/cef_api_hash.h ++++ b/include/cef_api_hash.h +@@ -42,13 +42,13 @@ + // way that may cause binary incompatibility with other builds. The universal + // hash value will change if any platform is affected whereas the platform hash + // values will change only if that particular platform is affected. +-#define CEF_API_HASH_UNIVERSAL "4acea2e5c7a3e281d9652802ae1d24b25eef299b" ++#define CEF_API_HASH_UNIVERSAL "7d1351328f7aeb7db3ae74b6d687b115ceec7695" + #if defined(OS_WIN) +-#define CEF_API_HASH_PLATFORM "3a181fdfaa42d2214c77cd83f76886b0657b0b53" ++#define CEF_API_HASH_PLATFORM "70c2a3fee7a3f4a4f6d44d4a3b3699ad23cf6f67" + #elif defined(OS_MAC) +-#define CEF_API_HASH_PLATFORM "06bfe874ee215bde0a415bac7ac37ecf4969d4ca" ++#define CEF_API_HASH_PLATFORM "9d9d39318398a7efaf43406ae25967a33c9d9787" + #elif defined(OS_LINUX) +-#define CEF_API_HASH_PLATFORM "1615f7e7079d89e2e81f683d4a8480455b5f2a60" ++#define CEF_API_HASH_PLATFORM "f828859cd19052fd3dab4b9f50f530d7011642b6" + #endif + + #ifdef __cplusplus +diff --git a/libcef_dll/cpptoc/views/window_cpptoc.cc b/libcef_dll/cpptoc/views/window_cpptoc.cc +index 93ee5341f..cbb4bb1a4 100644 +--- a/libcef_dll/cpptoc/views/window_cpptoc.cc ++++ b/libcef_dll/cpptoc/views/window_cpptoc.cc +@@ -9,7 +9,7 @@ + // implementations. See the translator.README.txt file in the tools directory + // for more information. + // +-// $hash=23777aea864e9abf38c2e2c5d79a40d6bd22876d$ ++// $hash=53b37fbf82615184d8b259a2e476431a3e699eea$ + // + + #include "libcef_dll/cpptoc/views/window_cpptoc.h" +@@ -48,6 +48,32 @@ CEF_EXPORT cef_window_t* cef_window_create_top_level( + return CefWindowCppToC::Wrap(_retval); + } + ++CEF_EXPORT cef_window_t* cef_window_create_top_level_with_id( ++ struct _cef_window_delegate_t* delegate, ++ const cef_string_t* app_id) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ // Verify param: delegate; type: refptr_diff ++ DCHECK(delegate); ++ if (!delegate) { ++ return NULL; ++ } ++ // Verify param: app_id; type: string_byref_const ++ DCHECK(app_id); ++ if (!app_id) { ++ return NULL; ++ } ++ ++ // Execute ++ CefRefPtr<CefWindow> _retval = CefWindow::CreateTopLevelWindowWithId( ++ CefWindowDelegateCToCpp::Wrap(delegate), CefString(app_id)); ++ ++ // Return type: refptr_same ++ return CefWindowCppToC::Wrap(_retval); ++} ++ + namespace { + + // MEMBER FUNCTIONS - Body may be edited by hand. +@@ -717,6 +743,124 @@ void CEF_CALLBACK window_remove_all_accelerators(struct _cef_window_t* self) { + CefWindowCppToC::Get(self)->RemoveAllAccelerators(); + } + ++void CEF_CALLBACK window_agl_activate_app(struct _cef_window_t* self, ++ const cef_string_t* app) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ DCHECK(self); ++ if (!self) { ++ return; ++ } ++ // Verify param: app; type: string_byref_const ++ DCHECK(app); ++ if (!app) { ++ return; ++ } ++ ++ // Execute ++ CefWindowCppToC::Get(self)->AglActivateApp(CefString(app)); ++} ++ ++void CEF_CALLBACK window_agl_set_app_id(struct _cef_window_t* self, ++ const cef_string_t* app_id) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ DCHECK(self); ++ if (!self) { ++ return; ++ } ++ // Verify param: app_id; type: string_byref_const ++ DCHECK(app_id); ++ if (!app_id) { ++ return; ++ } ++ ++ // Execute ++ CefWindowCppToC::Get(self)->AglSetAppId(CefString(app_id)); ++} ++ ++void CEF_CALLBACK window_agl_set_app_ready(struct _cef_window_t* self) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ DCHECK(self); ++ if (!self) { ++ return; ++ } ++ ++ // Execute ++ CefWindowCppToC::Get(self)->AglSetAppReady(); ++} ++ ++void CEF_CALLBACK window_agl_set_back_ground_app(struct _cef_window_t* self) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ DCHECK(self); ++ if (!self) { ++ return; ++ } ++ ++ // Execute ++ CefWindowCppToC::Get(self)->AglSetBackGroundApp(); ++} ++ ++void CEF_CALLBACK window_agl_set_panel_app(struct _cef_window_t* self, ++ uint32_t edge) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ DCHECK(self); ++ if (!self) { ++ return; ++ } ++ ++ // Execute ++ CefWindowCppToC::Get(self)->AglSetPanelApp(edge); ++} ++ ++int CEF_CALLBACK window_is_surface_configured(struct _cef_window_t* self) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ DCHECK(self); ++ if (!self) { ++ return 0; ++ } ++ ++ // Execute ++ bool _retval = CefWindowCppToC::Get(self)->IsSurfaceConfigured(); ++ ++ // Return type: bool ++ return _retval; ++} ++ ++void CEF_CALLBACK window_setup_activation_area(struct _cef_window_t* self, ++ uint32_t x, ++ uint32_t y, ++ uint32_t width, ++ uint32_t height) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ DCHECK(self); ++ if (!self) { ++ return; ++ } ++ ++ // Execute ++ CefWindowCppToC::Get(self)->SetupActivationArea(x, y, width, height); ++} ++ + struct _cef_window_t* CEF_CALLBACK window_as_window(struct _cef_panel_t* self) { + shutdown_checker::AssertNotShutdown(); + +@@ -2031,6 +2175,13 @@ CefWindowCppToC::CefWindowCppToC() { + GetStruct()->set_accelerator = window_set_accelerator; + GetStruct()->remove_accelerator = window_remove_accelerator; + GetStruct()->remove_all_accelerators = window_remove_all_accelerators; ++ GetStruct()->agl_activate_app = window_agl_activate_app; ++ GetStruct()->agl_set_app_id = window_agl_set_app_id; ++ GetStruct()->agl_set_app_ready = window_agl_set_app_ready; ++ GetStruct()->agl_set_back_ground_app = window_agl_set_back_ground_app; ++ GetStruct()->agl_set_panel_app = window_agl_set_panel_app; ++ GetStruct()->is_surface_configured = window_is_surface_configured; ++ GetStruct()->setup_activation_area = window_setup_activation_area; + GetStruct()->base.as_window = window_as_window; + GetStruct()->base.set_to_fill_layout = window_set_to_fill_layout; + GetStruct()->base.set_to_box_layout = window_set_to_box_layout; +diff --git a/libcef_dll/ctocpp/views/window_ctocpp.cc b/libcef_dll/ctocpp/views/window_ctocpp.cc +index 3a0423d28..aee3d62f1 100644 +--- a/libcef_dll/ctocpp/views/window_ctocpp.cc ++++ b/libcef_dll/ctocpp/views/window_ctocpp.cc +@@ -9,7 +9,7 @@ + // implementations. See the translator.README.txt file in the tools directory + // for more information. + // +-// $hash=b6b0a2a563b475163aa71b20af6ec2ac8c1f0cae$ ++// $hash=61eb77c4622382d6dda0136187c6acbd093f2e83$ + // + + #include "libcef_dll/ctocpp/views/window_ctocpp.h" +@@ -49,6 +49,33 @@ CefRefPtr<CefWindow> CefWindow::CreateTopLevelWindow( + return CefWindowCToCpp::Wrap(_retval); + } + ++NO_SANITIZE("cfi-icall") ++CefRefPtr<CefWindow> CefWindow::CreateTopLevelWindowWithId( ++ CefRefPtr<CefWindowDelegate> delegate, ++ const CefString& app_id) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ // Verify param: delegate; type: refptr_diff ++ DCHECK(delegate.get()); ++ if (!delegate.get()) { ++ return nullptr; ++ } ++ // Verify param: app_id; type: string_byref_const ++ DCHECK(!app_id.empty()); ++ if (app_id.empty()) { ++ return nullptr; ++ } ++ ++ // Execute ++ cef_window_t* _retval = cef_window_create_top_level_with_id( ++ CefWindowDelegateCppToC::Wrap(delegate), app_id.GetStruct()); ++ ++ // Return type: refptr_same ++ return CefWindowCToCpp::Wrap(_retval); ++} ++ + // VIRTUAL METHODS - Body may be edited by hand. + + NO_SANITIZE("cfi-icall") void CefWindowCToCpp::Show() { +@@ -707,6 +734,125 @@ NO_SANITIZE("cfi-icall") void CefWindowCToCpp::RemoveAllAccelerators() { + _struct->remove_all_accelerators(_struct); + } + ++NO_SANITIZE("cfi-icall") ++void CefWindowCToCpp::AglActivateApp(const CefString& app) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ cef_window_t* _struct = GetStruct(); ++ if (CEF_MEMBER_MISSING(_struct, agl_activate_app)) { ++ return; ++ } ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ // Verify param: app; type: string_byref_const ++ DCHECK(!app.empty()); ++ if (app.empty()) { ++ return; ++ } ++ ++ // Execute ++ _struct->agl_activate_app(_struct, app.GetStruct()); ++} ++ ++NO_SANITIZE("cfi-icall") ++void CefWindowCToCpp::AglSetAppId(const CefString& app_id) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ cef_window_t* _struct = GetStruct(); ++ if (CEF_MEMBER_MISSING(_struct, agl_set_app_id)) { ++ return; ++ } ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ // Verify param: app_id; type: string_byref_const ++ DCHECK(!app_id.empty()); ++ if (app_id.empty()) { ++ return; ++ } ++ ++ // Execute ++ _struct->agl_set_app_id(_struct, app_id.GetStruct()); ++} ++ ++NO_SANITIZE("cfi-icall") void CefWindowCToCpp::AglSetAppReady() { ++ shutdown_checker::AssertNotShutdown(); ++ ++ cef_window_t* _struct = GetStruct(); ++ if (CEF_MEMBER_MISSING(_struct, agl_set_app_ready)) { ++ return; ++ } ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ // Execute ++ _struct->agl_set_app_ready(_struct); ++} ++ ++NO_SANITIZE("cfi-icall") void CefWindowCToCpp::AglSetBackGroundApp() { ++ shutdown_checker::AssertNotShutdown(); ++ ++ cef_window_t* _struct = GetStruct(); ++ if (CEF_MEMBER_MISSING(_struct, agl_set_back_ground_app)) { ++ return; ++ } ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ // Execute ++ _struct->agl_set_back_ground_app(_struct); ++} ++ ++NO_SANITIZE("cfi-icall") void CefWindowCToCpp::AglSetPanelApp(uint32_t edge) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ cef_window_t* _struct = GetStruct(); ++ if (CEF_MEMBER_MISSING(_struct, agl_set_panel_app)) { ++ return; ++ } ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ // Execute ++ _struct->agl_set_panel_app(_struct, edge); ++} ++ ++NO_SANITIZE("cfi-icall") bool CefWindowCToCpp::IsSurfaceConfigured() { ++ shutdown_checker::AssertNotShutdown(); ++ ++ cef_window_t* _struct = GetStruct(); ++ if (CEF_MEMBER_MISSING(_struct, is_surface_configured)) { ++ return false; ++ } ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ // Execute ++ int _retval = _struct->is_surface_configured(_struct); ++ ++ // Return type: bool ++ return _retval ? true : false; ++} ++ ++NO_SANITIZE("cfi-icall") ++void CefWindowCToCpp::SetupActivationArea(uint32_t x, ++ uint32_t y, ++ uint32_t width, ++ uint32_t height) { ++ shutdown_checker::AssertNotShutdown(); ++ ++ cef_window_t* _struct = GetStruct(); ++ if (CEF_MEMBER_MISSING(_struct, setup_activation_area)) { ++ return; ++ } ++ ++ // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING ++ ++ // Execute ++ _struct->setup_activation_area(_struct, x, y, width, height); ++} ++ + NO_SANITIZE("cfi-icall") CefRefPtr<CefWindow> CefWindowCToCpp::AsWindow() { + shutdown_checker::AssertNotShutdown(); + +diff --git a/libcef_dll/ctocpp/views/window_ctocpp.h b/libcef_dll/ctocpp/views/window_ctocpp.h +index bc797350c..9931a7a3e 100644 +--- a/libcef_dll/ctocpp/views/window_ctocpp.h ++++ b/libcef_dll/ctocpp/views/window_ctocpp.h +@@ -9,7 +9,7 @@ + // implementations. See the translator.README.txt file in the tools directory + // for more information. + // +-// $hash=2a7aaed7d4296e29dca74345cf2b2d4db221a738$ ++// $hash=10cca846f56124ef20cd769e018ccfdf0aba26f5$ + // + + #ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_CTOCPP_H_ +@@ -86,6 +86,16 @@ class CefWindowCToCpp + bool alt_pressed) override; + void RemoveAccelerator(int command_id) override; + void RemoveAllAccelerators() override; ++ void AglActivateApp(const CefString& app) override; ++ void AglSetAppId(const CefString& app_id) override; ++ void AglSetAppReady() override; ++ void AglSetBackGroundApp() override; ++ void AglSetPanelApp(uint32_t edge) override; ++ bool IsSurfaceConfigured() override; ++ void SetupActivationArea(uint32_t x, ++ uint32_t y, ++ uint32_t width, ++ uint32_t height) override; + + // CefPanel methods. + CefRefPtr<CefWindow> AsWindow() override; +diff --git a/libcef_dll/wrapper/libcef_dll_dylib.cc b/libcef_dll/wrapper/libcef_dll_dylib.cc +index 21065db3b..b61ea0d4b 100644 +--- a/libcef_dll/wrapper/libcef_dll_dylib.cc ++++ b/libcef_dll/wrapper/libcef_dll_dylib.cc +@@ -9,7 +9,7 @@ + // implementations. See the translator.README.txt file in the tools directory + // for more information. + // +-// $hash=bcad216e5fef8b9c10a895524f8b1201608138f9$ ++// $hash=51d1746394ff61e17d4fbb3d1415a3b646004563$ + // + + #include <dlfcn.h> +@@ -249,6 +249,8 @@ struct libcef_pointers { + decltype(&cef_scroll_view_create) cef_scroll_view_create; + decltype(&cef_textfield_create) cef_textfield_create; + decltype(&cef_window_create_top_level) cef_window_create_top_level; ++ decltype(&cef_window_create_top_level_with_id) ++ cef_window_create_top_level_with_id; + decltype(&cef_api_hash) cef_api_hash; + decltype(&cef_version_info) cef_version_info; + decltype(&cef_get_min_log_level) cef_get_min_log_level; +@@ -463,6 +465,7 @@ int libcef_init_pointers(const char* path) { + INIT_ENTRY(cef_scroll_view_create); + INIT_ENTRY(cef_textfield_create); + INIT_ENTRY(cef_window_create_top_level); ++ INIT_ENTRY(cef_window_create_top_level_with_id); + INIT_ENTRY(cef_api_hash); + INIT_ENTRY(cef_version_info); + INIT_ENTRY(cef_get_min_log_level); +@@ -705,8 +708,8 @@ int cef_create_url(const struct _cef_urlparts_t* parts, cef_string_t* url) { + } + + NO_SANITIZE("cfi-icall") +-cef_string_userfree_t cef_format_url_for_security_display( +- const cef_string_t* origin_url) { ++cef_string_userfree_t ++ cef_format_url_for_security_display(const cef_string_t* origin_url) { + return g_libcef_pointers.cef_format_url_for_security_display(origin_url); + } + +@@ -978,9 +981,10 @@ void cef_server_create(const cef_string_t* address, + } + + NO_SANITIZE("cfi-icall") +-struct _cef_shared_process_message_builder_t* +-cef_shared_process_message_builder_create(const cef_string_t* name, +- size_t byte_size) { ++struct ++ _cef_shared_process_message_builder_t* cef_shared_process_message_builder_create( ++ const cef_string_t* name, ++ size_t byte_size) { + return g_libcef_pointers.cef_shared_process_message_builder_create(name, + byte_size); + } +@@ -1192,46 +1196,54 @@ struct _cef_translator_test_t* cef_translator_test_create() { + } + + NO_SANITIZE("cfi-icall") +-struct _cef_translator_test_ref_ptr_library_t* +-cef_translator_test_ref_ptr_library_create(int value) { ++struct ++ _cef_translator_test_ref_ptr_library_t* cef_translator_test_ref_ptr_library_create( ++ int value) { + return g_libcef_pointers.cef_translator_test_ref_ptr_library_create(value); + } + + NO_SANITIZE("cfi-icall") +-struct _cef_translator_test_ref_ptr_library_child_t* +-cef_translator_test_ref_ptr_library_child_create(int value, int other_value) { ++struct ++ _cef_translator_test_ref_ptr_library_child_t* cef_translator_test_ref_ptr_library_child_create( ++ int value, ++ int other_value) { + return g_libcef_pointers.cef_translator_test_ref_ptr_library_child_create( + value, other_value); + } + + NO_SANITIZE("cfi-icall") +-struct _cef_translator_test_ref_ptr_library_child_child_t* +-cef_translator_test_ref_ptr_library_child_child_create(int value, +- int other_value, +- int other_other_value) { ++struct ++ _cef_translator_test_ref_ptr_library_child_child_t* cef_translator_test_ref_ptr_library_child_child_create( ++ int value, ++ int other_value, ++ int other_other_value) { + return g_libcef_pointers + .cef_translator_test_ref_ptr_library_child_child_create( + value, other_value, other_other_value); + } + + NO_SANITIZE("cfi-icall") +-struct _cef_translator_test_scoped_library_t* +-cef_translator_test_scoped_library_create(int value) { ++struct ++ _cef_translator_test_scoped_library_t* cef_translator_test_scoped_library_create( ++ int value) { + return g_libcef_pointers.cef_translator_test_scoped_library_create(value); + } + + NO_SANITIZE("cfi-icall") +-struct _cef_translator_test_scoped_library_child_t* +-cef_translator_test_scoped_library_child_create(int value, int other_value) { ++struct ++ _cef_translator_test_scoped_library_child_t* cef_translator_test_scoped_library_child_create( ++ int value, ++ int other_value) { + return g_libcef_pointers.cef_translator_test_scoped_library_child_create( + value, other_value); + } + + NO_SANITIZE("cfi-icall") +-struct _cef_translator_test_scoped_library_child_child_t* +-cef_translator_test_scoped_library_child_child_create(int value, +- int other_value, +- int other_other_value) { ++struct ++ _cef_translator_test_scoped_library_child_child_t* cef_translator_test_scoped_library_child_child_create( ++ int value, ++ int other_value, ++ int other_other_value) { + return g_libcef_pointers + .cef_translator_test_scoped_library_child_child_create(value, other_value, + other_other_value); +@@ -1284,14 +1296,14 @@ void cef_display_get_alls(size_t* displaysCount, + } + + NO_SANITIZE("cfi-icall") +-cef_point_t cef_display_convert_screen_point_to_pixels( +- const cef_point_t* point) { ++cef_point_t ++ cef_display_convert_screen_point_to_pixels(const cef_point_t* point) { + return g_libcef_pointers.cef_display_convert_screen_point_to_pixels(point); + } + + NO_SANITIZE("cfi-icall") +-cef_point_t cef_display_convert_screen_point_from_pixels( +- const cef_point_t* point) { ++cef_point_t ++ cef_display_convert_screen_point_from_pixels(const cef_point_t* point) { + return g_libcef_pointers.cef_display_convert_screen_point_from_pixels(point); + } + +@@ -1342,6 +1354,14 @@ struct _cef_window_t* cef_window_create_top_level( + return g_libcef_pointers.cef_window_create_top_level(delegate); + } + ++NO_SANITIZE("cfi-icall") ++struct _cef_window_t* cef_window_create_top_level_with_id( ++ struct _cef_window_delegate_t* delegate, ++ const cef_string_t* app_id) { ++ return g_libcef_pointers.cef_window_create_top_level_with_id(delegate, ++ app_id); ++} ++ + NO_SANITIZE("cfi-icall") const char* cef_api_hash(int entry) { + return g_libcef_pointers.cef_api_hash(entry); + } +-- +2.42.1 + diff --git a/recipes-wam/cef/files/cef/0010-Make-patcher-work-outside-a-git-checkout.patch b/recipes-wam/cef/files/cef/0010-Make-patcher-work-outside-a-git-checkout.patch new file mode 100644 index 00000000..a59b4f3c --- /dev/null +++ b/recipes-wam/cef/files/cef/0010-Make-patcher-work-outside-a-git-checkout.patch @@ -0,0 +1,118 @@ +From 713ccd00a541ded20b20c84c7d985f87d3a88d00 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Wed, 18 Oct 2023 15:59:13 -0300 +Subject: [PATCH 10/11] Make patcher work outside a git checkout + +--- + tools/make_distrib.py | 21 +++++++++++---------- + tools/patch_util.py | 40 ++++++++++++++++++++++++++++++++++++++++ + tools/patcher.py | 3 +++ + 3 files changed, 54 insertions(+), 10 deletions(-) + create mode 100644 tools/patch_util.py + +diff --git a/tools/make_distrib.py b/tools/make_distrib.py +index 6ed748fe7..a8db7947e 100644 +--- a/tools/make_distrib.py ++++ b/tools/make_distrib.py +@@ -621,20 +621,21 @@ cef_url = git.get_url(cef_dir) + cef_rev = git.get_hash(cef_dir) + cef_commit_number = git.get_commit_number(cef_dir) + +-if not git.is_checkout(src_dir): +- raise Exception('Not a valid checkout: %s' % (src_dir)) +- +-# retrieve information for Chromium +-chromium_url = git.get_url(src_dir) +-chromium_rev = git.get_hash(src_dir) +- +-date = get_date() +- +-# format version strings + formatter = VersionFormatter() ++# format version strings + cef_ver = formatter.get_version_string() + chromium_ver = formatter.get_chromium_version_string() + ++if not git.is_checkout(src_dir): ++ chromium_url = git.get_url(src_dir) ++ chromium_rev = git.get_hash(src_dir) ++else: ++ # retrieve information for Chromium ++ chromium_rev = chromium_ver ++ chromium_url = 'https://commondatastorage.googleapis.com/chromium-browser-official/chromium-%s.tar.xz' % chromium_ver ++ ++date = get_date() ++ + # list of output directories to be archived + archive_dirs = [] + +diff --git a/tools/patch_util.py b/tools/patch_util.py +new file mode 100644 +index 000000000..2025e97e0 +--- /dev/null ++++ b/tools/patch_util.py +@@ -0,0 +1,40 @@ ++from __future__ import absolute_import ++from exec_util import exec_cmd ++import os ++import sys ++ ++def patch_apply_patch_file(patch_path, patch_dir): ++ """ Apply |patch_path| to files in |patch_dir|. """ ++ patch_name = os.path.basename(patch_path) ++ sys.stdout.write('\nApply %s in %s\n' % (patch_name, patch_dir)) ++ ++ if not os.path.isfile(patch_path): ++ sys.stdout.write('... patch file does not exist.\n') ++ return 'fail' ++ ++ # Apply the patch file. This should always succeed because the previous ++ # command succeeded. ++ ++ cmd = 'patch -p0 -N --dry-run --ignore-whitespace --input=%s' % patch_path ++ result = exec_cmd(cmd, patch_dir) ++ if result['ret'] != 0: ++ return 'skip' ++ ++ cmd = 'patch --ignore-whitespace -p0 --input=%s --verbose' % patch_path ++ result = exec_cmd(cmd, patch_dir) ++ ++ sys.stdout.write('Err: \t%s\n' % result['err']) ++ sys.stdout.write('Out: \t%s\n' % result['out']) ++ ++ if result['err'].find('FAILED') >= 0: ++ sys.stdout.write('... error applying patch.\n') ++ write_indented_output(result['err'].replace('<stdin>', patch_name)) ++ return 'fail' ++ ++ if result['err'] == '': ++ sys.stdout.write('... successfully applied.\n') ++ else: ++ sys.stdout.write('... successfully applied (with warnings):\n') ++ sys.stdout.write('\t%s\n' % result['err']) ++ return 'apply' ++ +diff --git a/tools/patcher.py b/tools/patcher.py +index 023e91d4b..fa6eb1946 100644 +--- a/tools/patcher.py ++++ b/tools/patcher.py +@@ -9,6 +9,7 @@ import os + import sys + from file_util import * + from git_util import git_apply_patch_file ++from patch_util import patch_apply_patch_file + + # Cannot be loaded as a module. + if __name__ != "__main__": +@@ -46,6 +47,8 @@ def apply_patch_file(patch_file, patch_dir): + return 'skip' + + result = git_apply_patch_file(patch_path, patch_dir) ++ if result == 'fail': ++ result = patch_apply_patch_file(patch_path, patch_dir) + if result == 'fail': + write_note('ERROR', + 'This patch failed to apply. Your build will not be correct.') +-- +2.42.1 + diff --git a/recipes-wam/cef/files/cef/0011-Avoid-the-RuntimeError-dictionary-changed-size-durin.patch b/recipes-wam/cef/files/cef/0011-Avoid-the-RuntimeError-dictionary-changed-size-durin.patch new file mode 100644 index 00000000..32527b79 --- /dev/null +++ b/recipes-wam/cef/files/cef/0011-Avoid-the-RuntimeError-dictionary-changed-size-durin.patch @@ -0,0 +1,26 @@ +From db006bee47fd4cd5f9138a0b916b81dff9bab3d0 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Wed, 8 Nov 2023 13:37:27 -0300 +Subject: [PATCH 11/11] Avoid the RuntimeError: dictionary changed size during + iteration + +--- + tools/gn_args.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/gn_args.py b/tools/gn_args.py +index 80545da49..9e2e9c061 100644 +--- a/tools/gn_args.py ++++ b/tools/gn_args.py +@@ -486,7 +486,7 @@ def GetConfigArgs(args, is_debug, cpu, bypass_sysroot_check=False): + + if platform == 'linux' and not cpu.startswith('arm'): + # Remove any arm-related values from non-arm configs. +- for key in result.keys(): ++ for key, value in list(result.items()): + if key.startswith('arm_'): + del result[key] + +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0001-agl-compositor-Add-agl_shell_wrapper-AGL-wayland-ext.patch b/recipes-wam/cef/files/chromium/0001-agl-compositor-Add-agl_shell_wrapper-AGL-wayland-ext.patch new file mode 100644 index 00000000..6ab4d5b8 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0001-agl-compositor-Add-agl_shell_wrapper-AGL-wayland-ext.patch @@ -0,0 +1,914 @@ +From 019d5dea79b9ac8ec17d5925546aab66473f67f5 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 15 May 2023 20:32:06 +0200 +Subject: [PATCH 01/33] [agl][compositor] Add agl_shell_wrapper / AGL wayland + extension + +This is a backport of the chages we did on top of chromium webosose to +be able to communicate with the agl-compositor + +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + ui/base/ui_base_switches.cc | 2 + + ui/base/ui_base_switches.h | 3 + + ui/ozone/platform/wayland/BUILD.gn | 7 + + .../platform/wayland/extensions/agl/BUILD.gn | 40 ++++ + .../agl/common/wayland_object_agl.cc | 26 +++ + .../agl/common/wayland_object_agl.h | 34 ++++ + .../extensions/agl/host/agl_shell_wrapper.cc | 113 +++++++++++ + .../extensions/agl/host/agl_shell_wrapper.h | 62 ++++++ + .../agl/host/wayland_extensions_agl.h | 37 ++++ + .../agl/host/wayland_extensions_agl_impl.cc | 93 +++++++++ + .../agl/host/wayland_extensions_agl_impl.h | 54 ++++++ + .../extensions/agl/protocol/agl-shell.xml | 179 ++++++++++++++++++ + .../wayland/host/wayland_connection.cc | 12 +- + .../wayland/host/wayland_connection.h | 4 + + .../wayland/host/wayland_extensions.h | 56 ++++++ + 15 files changed, 720 insertions(+), 2 deletions(-) + create mode 100644 ui/ozone/platform/wayland/extensions/agl/BUILD.gn + create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc + create mode 100644 ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h + create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc + create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h + create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h + create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc + create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h + create mode 100644 ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml + create mode 100644 ui/ozone/platform/wayland/host/wayland_extensions.h + +diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc +index 514bb3cdb580d..d94e2c5e78306 100644 +--- a/ui/base/ui_base_switches.cc ++++ b/ui/base/ui_base_switches.cc +@@ -112,4 +112,6 @@ const char kUIDisablePartialSwap[] = "ui-disable-partial-swap"; + // Enables the ozone x11 clipboard for linux-chromeos. + const char kUseSystemClipboard[] = "use-system-clipboard"; + ++const char kAglShellAppId[] = "agl-shell-appid"; ++ + } // namespace switches +diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h +index ec664b866c5d2..cf483e0339072 100644 +--- a/ui/base/ui_base_switches.h ++++ b/ui/base/ui_base_switches.h +@@ -53,6 +53,9 @@ COMPONENT_EXPORT(UI_BASE) extern const char kTopChromeTouchUiEnabled[]; + COMPONENT_EXPORT(UI_BASE) extern const char kUIDisablePartialSwap[]; + COMPONENT_EXPORT(UI_BASE) extern const char kUseSystemClipboard[]; + ++// Agl related ++COMPONENT_EXPORT(UI_BASE) extern const char kAglShellAppId[]; ++ + // Test related. + COMPONENT_EXPORT(UI_BASE) extern const char kDisallowNonExactResourceReuse[]; + COMPONENT_EXPORT(UI_BASE) extern const char kMangleLocalizedStrings[]; +diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn +index ae763d441d55c..8a436de0fafe3 100644 +--- a/ui/ozone/platform/wayland/BUILD.gn ++++ b/ui/ozone/platform/wayland/BUILD.gn +@@ -397,6 +397,13 @@ source_set("wayland") { + ] + + configs += [ "//third_party/khronos:khronos_headers" ] ++ ++ sources += [ ++ "host/wayland_extensions.h", ++ "host/wayland_extensions_stub.cc", ++ ] ++ ++ deps += [ "extensions/agl" ] + } + + source_set("test_support") { +diff --git a/ui/ozone/platform/wayland/extensions/agl/BUILD.gn b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn +new file mode 100644 +index 0000000000000..ce289bc5dbbca +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn +@@ -0,0 +1,40 @@ ++# Copyright 2021 LG Electronics, Inc. ++# ++# Licensed under the Apache License, Version 2.0 (the "License"); ++# you may not use this file except in compliance with the License. ++# You may obtain a copy of the License at ++# ++# http://www.apache.org/licenses/LICENSE-2.0 ++# ++# Unless required by applicable law or agreed to in writing, software ++# distributed under the License is distributed on an "AS IS" BASIS, ++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++# See the License for the specific language governing permissions and ++# limitations under the License. ++# ++# SPDX-License-Identifier: Apache-2.0 ++ ++import("//third_party/wayland/wayland_protocol.gni") ++ ++visibility = [ "//ui/ozone/*" ] ++ ++wayland_protocol("agl_shell_protocol") { ++ sources = [ "protocol/agl-shell.xml" ] ++} ++ ++source_set("agl") { ++ sources = [ ++ "common/wayland_object_agl.cc", ++ "common/wayland_object_agl.h", ++ "host/agl_shell_wrapper.cc", ++ "host/agl_shell_wrapper.h", ++ "host/wayland_extensions_agl.h", ++ "host/wayland_extensions_agl_impl.cc", ++ "host/wayland_extensions_agl_impl.h", ++ ] ++ ++ deps = [ ++ ":agl_shell_protocol", ++ "//ui/ozone/platform/wayland/mojom", ++ ] ++} +diff --git a/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc +new file mode 100644 +index 0000000000000..9f3300766df2c +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.cc +@@ -0,0 +1,26 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h" ++ ++#include <agl-shell-client-protocol.h> ++ ++namespace wl { ++ ++const wl_interface* ObjectTraits<agl_shell>::interface = &agl_shell_interface; ++void (*ObjectTraits<agl_shell>::deleter)(agl_shell*) = &agl_shell_destroy; ++ ++} // namespace wl +\ No newline at end of file +diff --git a/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h +new file mode 100644 +index 0000000000000..e91ac0da8d2fc +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h +@@ -0,0 +1,34 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_ ++#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_ ++ ++#include "ui/ozone/platform/wayland/common/wayland_object.h" ++ ++struct agl_shell; ++ ++namespace wl { ++ ++template <> ++struct ObjectTraits<agl_shell> { ++ static const wl_interface* interface; ++ static void (*deleter)(agl_shell*); ++}; ++ ++} // namespace wl ++ ++#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_COMMON_WAYLAND_OBJECT_AGL_H_ +\ No newline at end of file +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc +new file mode 100644 +index 0000000000000..c74fa5d9cd221 +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc +@@ -0,0 +1,113 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h" ++ ++#include "agl_shell_wrapper.h" ++#include "base/logging.h" ++#include "ui/base/ui_base_switches.h" ++#include "ui/ozone/platform/wayland/host/wayland_connection.h" ++#include "ui/ozone/platform/wayland/host/wayland_output_manager.h" ++#include "ui/ozone/platform/wayland/host/wayland_window.h" ++ ++namespace ui { ++ ++static const struct agl_shell_listener shell_listener = { ++ &AglShellWrapper::AglShellBoundOk, ++ &AglShellWrapper::AglShellBoundFail, ++#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION ++ &AglShellWrapper::AglAppState, ++#endif ++}; ++ ++AglShellWrapper::AglShellWrapper(agl_shell* agl_shell, ++ WaylandConnection* wayland_connection) ++ : agl_shell_(agl_shell), connection_(wayland_connection) { ++ if (wl::get_version_of_object(agl_shell) >= AGL_SHELL_BOUND_OK_SINCE_VERSION) ++ agl_shell_add_listener(agl_shell, &shell_listener, this); ++} ++ ++AglShellWrapper::~AglShellWrapper() = default; ++ ++void AglShellWrapper::SetAglActivateApp(const std::string& app_id) { ++ wl_output* output = ++ connection_->wayland_output_manager()->GetPrimaryOutput()->get_output(); ++ agl_shell_activate_app(agl_shell_.get(), app_id.c_str(), output); ++} ++ ++void AglShellWrapper::SetAglPanel(WaylandWindow* window, uint32_t edge) { ++ wl_surface* surface = window->root_surface()->surface(); ++ wl_output* output = ++ connection_->wayland_output_manager()->GetPrimaryOutput()->get_output(); ++ ++ agl_shell_set_panel(agl_shell_.get(), surface, output, edge); ++} ++ ++void AglShellWrapper::SetAglBackground(WaylandWindow* window) { ++ wl_surface* surface = window->root_surface()->surface(); ++ wl_output* output = ++ connection_->wayland_output_manager()->GetPrimaryOutput()->get_output(); ++ ++ agl_shell_set_background(agl_shell_.get(), surface, output); ++} ++ ++void AglShellWrapper::SetAglReady() { ++ agl_shell_ready(agl_shell_.get()); ++} ++ ++// static ++void AglShellWrapper::AglShellBoundOk(void* data, struct agl_shell*) { ++ AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data); ++ wrapper->wait_for_bound_ = false; ++ wrapper->bound_ok_ = true; ++ LOG(INFO) << "Bound to agl_shell (bound_ok)"; ++} ++ ++// static ++void AglShellWrapper::AglShellBoundFail(void* data, struct agl_shell*) { ++ AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data); ++ wrapper->wait_for_bound_ = false; ++ wrapper->bound_ok_ = false; ++ LOG(INFO) << "Failed to bind to agl_shell (bound_fail)"; ++} ++ ++#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION ++// static ++void AglShellWrapper::AglAppState(void* data, ++ struct agl_shell*, ++ const char* app_id, ++ uint32_t state) { ++ AglShellWrapper* wrapper = static_cast<AglShellWrapper*>(data); ++ ++ LOG(INFO) << "State for app " << app_id << " changed to " << state; ++ ++ if (state == AGL_SHELL_APP_STATE_STARTED) { ++ wrapper->SetAglActivateApp(app_id); ++ LOG(INFO) << "Activating app " << app_id; ++ } ++} ++#endif ++ ++bool AglShellWrapper::WaitUntilBoundOk() { ++ int ret = 0; ++ while (ret != -1 && wait_for_bound_) { ++ ret = wl_display_dispatch(connection_->display()); ++ } ++ ++ return bound_ok_; ++} ++ ++} // namespace ui +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h +new file mode 100644 +index 0000000000000..2ab765883057e +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h +@@ -0,0 +1,62 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_ ++#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_ ++ ++#include <string> ++ ++#include <agl-shell-client-protocol.h> ++ ++#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h" ++ ++namespace ui { ++ ++class WaylandConnection; ++class WaylandWindow; ++ ++class AglShellWrapper { ++ public: ++ AglShellWrapper(agl_shell* agl_shell, WaylandConnection* wayland_connection); ++ AglShellWrapper(const AglShellWrapper&) = delete; ++ AglShellWrapper& operator=(const AglShellWrapper&) = delete; ++ ~AglShellWrapper(); ++ ++ void SetAglActivateApp(const std::string& app_id); ++ void SetAglPanel(WaylandWindow* window, uint32_t edge); ++ void SetAglBackground(WaylandWindow* window); ++ void SetAglReady(); ++ bool WaitUntilBoundOk(); ++ ++ static void AglShellBoundOk(void* data, struct agl_shell*); ++ static void AglShellBoundFail(void* data, struct agl_shell*); ++#ifdef AGL_SHELL_APP_STATE_SINCE_VERSION ++ static void AglAppState(void* data, ++ struct agl_shell*, ++ const char* app_id, ++ uint32_t state); ++#endif ++ ++ private: ++ wl::Object<agl_shell> agl_shell_; ++ WaylandConnection* connection_; ++ bool wait_for_bound_ = true; ++ bool bound_ok_ = false; ++}; ++ ++} // namespace ui ++ ++#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_AGL_SHELL_WRAPPER_H_ +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h +new file mode 100644 +index 0000000000000..df42fc00c84da +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h +@@ -0,0 +1,37 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_ ++#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_ ++ ++namespace ui { ++ ++class AglShellWrapper; ++ ++// AGL extensions implementation for webOS/Lite ++class WaylandExtensionsAgl { ++ public: ++ WaylandExtensionsAgl() = default; ++ WaylandExtensionsAgl(const WaylandExtensionsAgl&) = delete; ++ WaylandExtensionsAgl& operator=(const WaylandExtensionsAgl&) = delete; ++ virtual ~WaylandExtensionsAgl() = default; ++ ++ virtual AglShellWrapper* GetAglShell() = 0; ++}; ++ ++} // namespace ui ++ ++#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_ +\ No newline at end of file +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc +new file mode 100644 +index 0000000000000..26a5f0550c302 +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc +@@ -0,0 +1,93 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h" ++ ++#include <cstring> ++ ++#include "base/command_line.h" ++#include "base/logging.h" ++#include "ui/base/ui_base_switches.h" ++#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h" ++#include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h" ++#include "ui/ozone/platform/wayland/host/wayland_connection.h" ++ ++namespace ui { ++ ++namespace { ++ ++constexpr uint32_t kMinAglShellExtensionVersion = 1; ++constexpr uint32_t kMaxAglShellExtensionVersion = 3; ++ ++} // namespace ++ ++WaylandExtensionsAglImpl::WaylandExtensionsAglImpl( ++ WaylandConnection* connection) ++ : connection_(connection) {} ++ ++WaylandExtensionsAglImpl::~WaylandExtensionsAglImpl() = default; ++ ++bool WaylandExtensionsAglImpl::Bind(wl_registry* registry, ++ uint32_t name, ++ const char* interface, ++ uint32_t version) { ++ bool should_use_agl_shell = base::CommandLine::ForCurrentProcess()->HasSwitch( ++ switches::kAglShellAppId); ++ bool can_bind = wl::CanBind(interface, version, kMinAglShellExtensionVersion, ++ kMaxAglShellExtensionVersion); ++ bool is_agl_shell_interface = (strcmp(interface, "agl_shell") == 0); ++ ++ if (!is_agl_shell_interface) { ++ return false; ++ } ++ ++ LOG(INFO) << "should_use_agl_shell: " << should_use_agl_shell << ++ " can_bind: " << can_bind; ++ ++ if (should_use_agl_shell && !agl_shell_ && ++ is_agl_shell_interface && can_bind) { ++ wl::Object<agl_shell> aglshell = wl::Bind<agl_shell>( ++ registry, name, std::min(version, kMaxAglShellExtensionVersion)); ++ if (!aglshell) { ++ LOG(ERROR) << "Failed to bind to agl_shell global"; ++ return false; ++ } ++ agl_shell_ = ++ std::make_unique<AglShellWrapper>(aglshell.release(), connection_); ++ ++ LOG(INFO) << "Waiting until bound..."; ++ return agl_shell_->WaitUntilBoundOk(); ++ } else { ++ LOG(INFO) << "Cant bind."; ++ } ++ ++ return false; ++} ++ ++bool WaylandExtensionsAglImpl::HasShellObject() const { ++ return !!agl_shell_; ++} ++ ++AglShellWrapper* WaylandExtensionsAglImpl::GetAglShell() { ++ return agl_shell_.get(); ++} ++ ++std::unique_ptr<WaylandExtensions> CreateWaylandExtensions( ++ WaylandConnection* connection) { ++ return std::make_unique<WaylandExtensionsAglImpl>(connection); ++} ++ ++} // namespace ui +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h +new file mode 100644 +index 0000000000000..f6cbabe99ed0b +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h +@@ -0,0 +1,54 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_ ++#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_ ++ ++#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h" ++#include "ui/ozone/platform/wayland/host/wayland_extensions.h" ++ ++namespace ui { ++ ++class AglShellWrapper; ++ ++// AGL extension implementation for webOS/Lite ++class WaylandExtensionsAglImpl : public WaylandExtensions, ++ public WaylandExtensionsAgl { ++ public: ++ explicit WaylandExtensionsAglImpl(WaylandConnection* connection); ++ WaylandExtensionsAglImpl(const WaylandExtensionsAglImpl&) = delete; ++ WaylandExtensionsAglImpl& operator=(const WaylandExtensionsAglImpl&) = delete; ++ ~WaylandExtensionsAglImpl() override; ++ ++ // WaylandExtensions overrides ++ bool Bind(wl_registry* registry, ++ uint32_t name, ++ const char* interface, ++ uint32_t version) override; ++ ++ bool HasShellObject() const override; ++ ++ // WaylandExtensionsAgl overrides ++ AglShellWrapper* GetAglShell() override; ++ ++ private: ++ std::unique_ptr<AglShellWrapper> agl_shell_; ++ WaylandConnection* connection_; ++}; ++ ++} // namespace ui ++ ++#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_ +diff --git a/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml +new file mode 100644 +index 0000000000000..ad5553d61f189 +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml +@@ -0,0 +1,179 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<protocol name="agl_shell"> ++ <copyright> ++ Copyright © 2019, 2022 Collabora, Ltd. ++ ++ 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 (including the next ++ paragraph) 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. ++ </copyright> ++ <interface name="agl_shell" version="3"> ++ <description summary="user interface for Automotive Grade Linux platform"> ++ Starting with version 2 of the protocol, the client is required to wait ++ for the 'bound_ok' or 'bound_fail' events in order to proceed further. ++ ++ In case the client gets a 'bound_fail' event then it should consider that ++ there's another client already bound to the agl_shell protocol. ++ A client that receives a 'bound_ok' event should consider that there's ++ no other client already bound to the interface and can proceed further. ++ ++ If the client uses an older version of the protocol it will receive ++ automatically an error and the compositor will terminate the connection, ++ if there's another client already bound the interface. ++ ++ If the client receives the 'bound_fail' event and attempts to use the ++ interface further it will receive an error and the compositor will ++ terminate the connection. After the 'bound_fail' event was received the ++ client should call the destructor, which has been added with version 2 ++ of the protocol. The client is free to try at a later point in time to ++ see if it will receive the 'bound_ok' event, but there's no explicit way ++ of finding out when that event will be delivered. ++ It is assumed that it can infer that information through other ++ means/other channels. ++ </description> ++ ++ <enum name="error"> ++ <entry name="invalid_argument" value="0"/> ++ <entry name="background_exists" value="1"/> ++ <entry name="panel_exists" value="2"/> ++ </enum> ++ ++ <enum name="edge"> ++ <entry name="top" value="0"/> ++ <entry name="bottom" value="1"/> ++ <entry name="left" value="2"/> ++ <entry name="right" value="3"/> ++ </enum> ++ ++ <enum name="app_state" since="3"> ++ <entry name="started" value="0"/> ++ <entry name="terminated" value="1"/> ++ <entry name="activated" value="2"/> ++ <entry name="deactivated" value="3"/> ++ </enum> ++ ++ <request name="ready"> ++ <description summary="client is ready to be shown"> ++ Tell the server that this client is ready to be shown. The server ++ will delay presentation during start-up until all shell clients are ++ ready to be shown, and will display a black screen instead. ++ This gives the client an opportunity to set up and configure several ++ surfaces into a coherent interface. ++ ++ The client that binds to this interface must send this request, otherwise ++ they may stall the compositor unnecessarily. ++ ++ If this request is called after the compositor has already finished ++ start-up, no operation is performed. ++ </description> ++ </request> ++ ++ <request name="set_background"> ++ <description summary="set surface as output's background"> ++ Set the surface to act as the background of an output. After this ++ request, the server will immediately send a configure event with ++ the dimensions the client should use to cover the entire output. ++ ++ The surface must have a "desktop" surface role, as supported by ++ libweston-desktop. ++ ++ Only a single surface may be the background for any output. If a ++ background surface already exists, a protocol error is raised. ++ </description> ++ <arg name="surface" type="object" interface="wl_surface"/> ++ <arg name="output" type="object" interface="wl_output"/> ++ </request> ++ ++ <request name="set_panel"> ++ <description summary="set surface as panel"> ++ Set the surface to act as a panel of an output. The 'edge' argument ++ says what edge of the output the surface will be anchored to. ++ After this request, the server will send a configure event with the ++ corresponding width/height that the client should use, and 0 for the ++ other dimension. E.g. if the edge is 'top', the width will be the ++ output's width, and the height will be 0. ++ ++ The surface must have a "desktop" surface role, as supported by ++ libweston-desktop. ++ ++ The compositor will take the panel's window geometry into account when ++ positioning other windows, so the panels are not covered. ++ ++ XXX: What happens if e.g. both top and left are used at the same time? ++ Who gets to have the corner? ++ ++ Only a single surface may be the panel for an output's edge. If a ++ surface already exists on an edge, a protocol error is raised. ++ </description> ++ <arg name="surface" type="object" interface="wl_surface"/> ++ <arg name="output" type="object" interface="wl_output"/> ++ <arg name="edge" type="uint" enum="edge"/> ++ </request> ++ ++ <request name="activate_app"> ++ <description summary="make client current window"> ++ Ask the compositor to make a toplevel to become the current/focused ++ window for window management purposes. ++ ++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a ++ description of app_id. ++ ++ If multiple toplevels have the same app_id, the result is unspecified. ++ ++ XXX: Do we need feedback to say it didn't work? (e.g. client does ++ not exist) ++ </description> ++ <arg name="app_id" type="string"/> ++ <arg name="output" type="object" interface="wl_output"/> ++ </request> ++ ++ <event name="bound_ok" since="2"> ++ <description summary="event sent if binding was ok"> ++ Informs the client that it was able to bind the agl_shell ++ interface succesfully. Clients are required to wait for this ++ event before continuing further. ++ </description> ++ </event> ++ ++ <event name="bound_fail" since="2"> ++ <description summary="event sent if binding was nok"> ++ Informs the client that binding to the agl_shell interface was ++ unsuccesfull. Clients are required to wait for this event for ++ continuing further. ++ </description> ++ </event> ++ ++ <request name="destroy" type="destructor" since="2"> ++ <description summary="destroys the factory object"> ++ </description> ++ </request> ++ ++ <event name="app_state" since="3"> ++ <description summary="event sent when an application suffered state modification"> ++ Informs the client that an application has changed its state to another, ++ specified by the app_state enum. Client can use this event to track ++ current application state. For instance to know when the application has ++ started, or when terminated/stopped. ++ </description> ++ <arg name="app_id" type="string"/> ++ <arg name="state" type="uint" enum="app_state"/> ++ </event> ++ ++ ++ </interface> ++</protocol> +diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc +index ad3bbd6e37157..7a47d4a636998 100644 +--- a/ui/ozone/platform/wayland/host/wayland_connection.cc ++++ b/ui/ozone/platform/wayland/host/wayland_connection.cc +@@ -68,6 +68,8 @@ + #include "ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.h" + #include "ui/platform_window/common/platform_window_defaults.h" + ++#include "ui/ozone/platform/wayland/host/wayland_extensions.h" ++ + namespace ui { + + namespace { +@@ -212,6 +214,10 @@ bool WaylandConnection::Initialize(bool use_threaded_polling) { + use_threaded_polling = false; + } + ++ if (!extensions_) { ++ extensions_ = CreateWaylandExtensions(this); ++ } ++ + // Now that the connection with the display server has been properly + // estabilished, initialize the event source and input objects. + DCHECK(!event_source_); +@@ -243,7 +249,7 @@ bool WaylandConnection::Initialize(bool use_threaded_polling) { + LOG(ERROR) << "No wl_shm object"; + return false; + } +- if (!shell_) { ++ if (!shell_ && !(extensions_ && extensions_->HasShellObject())) { + LOG(ERROR) << "No Wayland shell found"; + return false; + } +@@ -538,7 +544,9 @@ void WaylandConnection::HandleGlobal(wl_registry* registry, + const char* interface, + uint32_t version) { + auto factory_it = global_object_factories_.find(interface); +- if (factory_it != global_object_factories_.end()) { ++ if (extensions_->Bind(registry, name, interface, version)) { ++ DVLOG(1) << "Successfully bound to " << interface; ++ } else if (factory_it != global_object_factories_.end()) { + (*factory_it->second)(this, registry, name, interface, version); + } else if (!compositor_ && strcmp(interface, "wl_compositor") == 0) { + compositor_ = wl::Bind<wl_compositor>( +diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h +index 6659bc54bd475..ba293e5bcd088 100644 +--- a/ui/ozone/platform/wayland/host/wayland_connection.h ++++ b/ui/ozone/platform/wayland/host/wayland_connection.h +@@ -50,6 +50,7 @@ class WaylandBufferManagerHost; + class WaylandCursor; + class WaylandCursorBufferListener; + class WaylandEventSource; ++class WaylandExtensions; + class WaylandOutputManager; + class WaylandSeat; + class WaylandZAuraShell; +@@ -201,6 +202,8 @@ class WaylandConnection { + + WaylandZAuraShell* zaura_shell() const { return zaura_shell_.get(); } + ++ WaylandExtensions* extensions() { return extensions_.get(); } ++ + WaylandZcrColorManager* zcr_color_manager() const { + return zcr_color_manager_.get(); + } +@@ -486,6 +489,7 @@ class WaylandConnection { + std::unique_ptr<OverlayPrioritizer> overlay_prioritizer_; + std::unique_ptr<SurfaceAugmenter> surface_augmenter_; + std::unique_ptr<SinglePixelBuffer> single_pixel_buffer_; ++ std::unique_ptr<WaylandExtensions> extensions_; + + // Clipboard-related objects. |clipboard_| must be declared after all + // DeviceManager instances it depends on, otherwise tests may crash with +diff --git a/ui/ozone/platform/wayland/host/wayland_extensions.h b/ui/ozone/platform/wayland/host/wayland_extensions.h +new file mode 100644 +index 0000000000000..3bd2fd7a211ae +--- /dev/null ++++ b/ui/ozone/platform/wayland/host/wayland_extensions.h +@@ -0,0 +1,56 @@ ++// Copyright 2019 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_ ++#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_ ++ ++#include <memory> ++ ++#include "ui/ozone/platform/wayland/common/wayland_object.h" ++ ++namespace ui { ++ ++class ShellToplevelWrapper; ++class ShellPopupWrapper; ++class WaylandConnection; ++ ++// Wayland extensions abstract interface to support extending of the Wayland ++// protocol. Inherit it to provide your own Wayland extensions implementation. ++class WaylandExtensions { ++ public: ++ WaylandExtensions() = default; ++ WaylandExtensions(const WaylandExtensions&) = delete; ++ WaylandExtensions& operator=(const WaylandExtensions&) = delete; ++ virtual ~WaylandExtensions() = default; ++ ++ // Binds to the extensions interface(s). Can encapsulate binding of several ++ // interfaces, defined by |interface|. ++ virtual bool Bind(wl_registry* registry, ++ uint32_t name, ++ const char* interface, ++ uint32_t version) = 0; ++ ++ // Checks whether the extensions have bound shell object(s). ++ virtual bool HasShellObject() const = 0; ++}; ++ ++// Creates Wayland extensions. ++std::unique_ptr<WaylandExtensions> CreateWaylandExtensions( ++ WaylandConnection* connection); ++ ++} // namespace ui ++ ++#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EXTENSIONS_H_ +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0002-agl-Add-waylandwindow-window-tree-host-essential-par.patch b/recipes-wam/cef/files/chromium/0002-agl-Add-waylandwindow-window-tree-host-essential-par.patch new file mode 100644 index 00000000..488b398b --- /dev/null +++ b/recipes-wam/cef/files/chromium/0002-agl-Add-waylandwindow-window-tree-host-essential-par.patch @@ -0,0 +1,1376 @@ +From d50bcc010ca2856979f58b2ffbd0015514c4231f Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Wed, 17 May 2023 21:25:53 +0200 +Subject: [PATCH 02/33] [agl] Add waylandwindow/window tree host essential + parts + +This is a backport of the work we did on top of chromium webosose to be +able to communicate with the agl compositor. + +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + ui/aura/BUILD.gn | 7 ++ + ui/aura/agl/window_tree_host_agl.h | 42 +++++++++ + ui/aura/agl/window_tree_host_platform_agl.cc | 50 +++++++++++ + ui/aura/agl/window_tree_host_platform_agl.h | 51 +++++++++++ + ui/aura/window_tree_host.h | 5 +- + ui/aura/window_tree_host_platform.cc | 4 +- + ui/aura/window_tree_host_platform.h | 4 +- + ui/ozone/platform/wayland/BUILD.gn | 1 - + .../platform/wayland/extensions/agl/BUILD.gn | 2 + + .../agl/host/wayland_extensions_agl.h | 10 ++- + .../agl/host/wayland_extensions_agl_impl.cc | 11 ++- + .../agl/host/wayland_extensions_agl_impl.h | 9 ++ + .../extensions/agl/host/wayland_window_agl.cc | 86 +++++++++++++++++++ + .../extensions/agl/host/wayland_window_agl.h | 49 +++++++++++ + .../wayland/gpu/gl_surface_wayland.cc | 9 +- + .../host/gtk_primary_selection_device.cc | 2 +- + .../gtk_primary_selection_device_manager.cc | 4 +- + .../wayland/host/proxy/wayland_proxy_impl.cc | 2 +- + .../wayland/host/wayland_connection.cc | 19 +++- + .../wayland/host/wayland_connection.h | 9 +- + .../platform/wayland/host/wayland_cursor.cc | 4 +- + .../wayland/host/wayland_data_device.cc | 10 +-- + .../wayland/host/wayland_data_device_base.cc | 2 +- + .../host/wayland_data_drag_controller.cc | 2 +- + .../wayland/host/wayland_data_source.cc | 6 +- + ui/ozone/platform/wayland/host/wayland_drm.cc | 6 +- + .../wayland/host/wayland_extensions.h | 6 ++ + .../platform/wayland/host/wayland_keyboard.cc | 4 +- + .../platform/wayland/host/wayland_popup.cc | 8 +- + .../platform/wayland/host/wayland_seat.cc | 2 +- + ui/ozone/platform/wayland/host/wayland_shm.cc | 2 +- + .../platform/wayland/host/wayland_surface.cc | 2 +- + .../wayland/host/wayland_toplevel_window.cc | 18 ++-- + .../platform/wayland/host/wayland_window.cc | 6 +- + .../platform/wayland/host/wayland_window.h | 2 + + .../host/wayland_window_drag_controller.cc | 2 +- + .../wayland/host/wayland_window_factory.cc | 14 +++ + .../wayland/host/wayland_zwp_linux_dmabuf.cc | 4 +- + .../wayland/host/xdg_foreign_wrapper.cc | 4 +- + .../wayland/host/xdg_popup_wrapper_impl.cc | 2 +- + .../wayland/host/xdg_surface_wrapper_impl.cc | 2 +- + .../wayland/host/xdg_toplevel_wrapper_impl.cc | 2 +- + .../host/zwp_primary_selection_device.cc | 2 +- + .../zwp_primary_selection_device_manager.cc | 4 +- + ui/platform_window/agl/platform_window_agl.h | 36 ++++++++ + ui/platform_window/platform_window.h | 4 +- + 46 files changed, 469 insertions(+), 63 deletions(-) + create mode 100644 ui/aura/agl/window_tree_host_agl.h + create mode 100644 ui/aura/agl/window_tree_host_platform_agl.cc + create mode 100644 ui/aura/agl/window_tree_host_platform_agl.h + create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.cc + create mode 100644 ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h + create mode 100644 ui/platform_window/agl/platform_window_agl.h + +diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn +index 50ca856b9da18..8fa04492f69f7 100644 +--- a/ui/aura/BUILD.gn ++++ b/ui/aura/BUILD.gn +@@ -99,6 +99,13 @@ component("aura") { + "window_tree_host_platform.cc", + ] + ++ public += [ ++ "agl/window_tree_host_agl.h", ++ "agl/window_tree_host_platform_agl.h" ++ ] ++ ++ sources += [ "agl/window_tree_host_platform_agl.cc" ] ++ + friend = [ ":*" ] + + defines = [ "AURA_IMPLEMENTATION" ] +diff --git a/ui/aura/agl/window_tree_host_agl.h b/ui/aura/agl/window_tree_host_agl.h +new file mode 100644 +index 0000000000000..858a078d939d0 +--- /dev/null ++++ b/ui/aura/agl/window_tree_host_agl.h +@@ -0,0 +1,42 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#ifndef UI_AURA_AGL_WINDOW_TREE_HOST_AGL_H_ ++#define UI_AURA_AGL_WINDOW_TREE_HOST_AGL_H_ ++ ++#include <string> ++ ++#include "ui/aura/aura_export.h" ++ ++namespace aura { ++ ++class AURA_EXPORT WindowTreeHostAgl { ++ public: ++ WindowTreeHostAgl() = default; ++ WindowTreeHostAgl(const WindowTreeHostAgl&) = delete; ++ WindowTreeHostAgl& operator=(const WindowTreeHostAgl&) = delete; ++ ~WindowTreeHostAgl() = default; ++ ++ virtual void SetAglActivateApp(const std::string& app) {} ++ virtual void SetAglAppId(const std::string& title) {} ++ virtual void SetAglReady() {} ++ virtual void SetAglBackground() {} ++ virtual void SetAglPanel(uint32_t edge) {} ++}; ++ ++} // namespace aura ++ ++#endif // UI_AURA_AGL_WINDOW_TREE_HOST_AGL_H_ +diff --git a/ui/aura/agl/window_tree_host_platform_agl.cc b/ui/aura/agl/window_tree_host_platform_agl.cc +new file mode 100644 +index 0000000000000..e34595fe0ed9c +--- /dev/null ++++ b/ui/aura/agl/window_tree_host_platform_agl.cc +@@ -0,0 +1,50 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#include "ui/aura/agl/window_tree_host_platform_agl.h" ++ ++#include "ui/aura/window_tree_host_platform.h" ++#include "ui/platform_window/platform_window.h" ++ ++namespace aura { ++ ++WindowTreeHostPlatformAgl::WindowTreeHostPlatformAgl( ++ std::unique_ptr<Window> window, ++ aura::WindowTreeHostPlatform* window_tree_host_platform) ++ : aura::WindowTreeHost(std::move(window)), ++ window_tree_host_platform_(window_tree_host_platform) {} ++ ++void WindowTreeHostPlatformAgl::SetAglActivateApp(const std::string& app) { ++ window_tree_host_platform_->platform_window()->SetAglActivateApp(app); ++} ++ ++void WindowTreeHostPlatformAgl::SetAglAppId(const std::string& title) { ++ window_tree_host_platform_->platform_window()->SetAglAppId(title); ++} ++ ++void WindowTreeHostPlatformAgl::SetAglReady() { ++ window_tree_host_platform_->platform_window()->SetAglReady(); ++} ++ ++void WindowTreeHostPlatformAgl::SetAglBackground() { ++ window_tree_host_platform_->platform_window()->SetAglBackground(); ++} ++ ++void WindowTreeHostPlatformAgl::SetAglPanel(uint32_t edge) { ++ window_tree_host_platform_->platform_window()->SetAglPanel(edge); ++} ++ ++} // namespace aura +diff --git a/ui/aura/agl/window_tree_host_platform_agl.h b/ui/aura/agl/window_tree_host_platform_agl.h +new file mode 100644 +index 0000000000000..181eefae346f7 +--- /dev/null ++++ b/ui/aura/agl/window_tree_host_platform_agl.h +@@ -0,0 +1,51 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#ifndef UI_AURA_AGL_WINDOW_TREE_HOST_PLATFORM_AGL_H_ ++#define UI_AURA_AGL_WINDOW_TREE_HOST_PLATFORM_AGL_H_ ++ ++#include <memory> ++ ++#include "ui/aura/aura_export.h" ++#include "ui/aura/window_tree_host.h" ++ ++namespace aura { ++ ++class Window; ++class WindowTreeHostPlatform; ++ ++class AURA_EXPORT WindowTreeHostPlatformAgl : public aura::WindowTreeHost { ++ public: ++ explicit WindowTreeHostPlatformAgl( ++ std::unique_ptr<Window> window, ++ aura::WindowTreeHostPlatform* window_tree_host_platform); ++ WindowTreeHostPlatformAgl(const WindowTreeHostPlatformAgl&) = delete; ++ WindowTreeHostPlatformAgl& operator=(const WindowTreeHostPlatformAgl&) = delete; ++ ~WindowTreeHostPlatformAgl() override = default; ++ ++ void SetAglActivateApp(const std::string& app) override; ++ void SetAglAppId(const std::string& title) override; ++ void SetAglReady() override; ++ void SetAglBackground() override; ++ void SetAglPanel(uint32_t edge) override; ++ ++ private: ++ aura::WindowTreeHostPlatform* window_tree_host_platform_; ++}; ++ ++} // namespace aura ++ ++#endif // UI_AURA_AGL_WINDOW_TREE_HOST_PLATFORM_AGL_H_ +diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h +index b4b6e7022ea34..afb37a3a3ed13 100644 +--- a/ui/aura/window_tree_host.h ++++ b/ui/aura/window_tree_host.h +@@ -30,6 +30,8 @@ + #include "ui/gfx/native_widget_types.h" + #include "ui/gfx/overlay_transform.h" + ++#include "ui/aura/agl/window_tree_host_agl.h" ++ + namespace gfx { + class Point; + class Rect; +@@ -66,7 +68,8 @@ class WindowTreeHostObserver; + class AURA_EXPORT WindowTreeHost : public ui::ImeKeyEventDispatcher, + public ui::EventSource, + public display::DisplayObserver, +- public ui::CompositorObserver { ++ public ui::CompositorObserver, ++ public WindowTreeHostAgl { + public: + // VideoCaptureLock ensures state necessary for capturing video remains in + // effect. For example, this may force keeping the compositor visible when +diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc +index fd4a560f6cdd1..33b9e892c0212 100644 +--- a/ui/aura/window_tree_host_platform.cc ++++ b/ui/aura/window_tree_host_platform.cc +@@ -52,7 +52,7 @@ std::unique_ptr<WindowTreeHost> WindowTreeHost::Create( + WindowTreeHostPlatform::WindowTreeHostPlatform( + ui::PlatformWindowInitProperties properties, + std::unique_ptr<Window> window) +- : WindowTreeHost(std::move(window)) { ++ : WindowTreeHostPlatformAgl(std::move(window), this) { + size_in_pixels_ = properties.bounds.size(); + CreateCompositor(false, false, properties.enable_compositing_based_throttling, + properties.compositor_memory_limit_mb); +@@ -60,7 +60,7 @@ WindowTreeHostPlatform::WindowTreeHostPlatform( + } + + WindowTreeHostPlatform::WindowTreeHostPlatform(std::unique_ptr<Window> window) +- : WindowTreeHost(std::move(window)), ++ : WindowTreeHostPlatformAgl(std::move(window), this), + widget_(gfx::kNullAcceleratedWidget), + current_cursor_(ui::mojom::CursorType::kNull) {} + +diff --git a/ui/aura/window_tree_host_platform.h b/ui/aura/window_tree_host_platform.h +index 92ae0f0229e70..9c3f742c30ad3 100644 +--- a/ui/aura/window_tree_host_platform.h ++++ b/ui/aura/window_tree_host_platform.h +@@ -15,6 +15,8 @@ + #include "ui/gfx/native_widget_types.h" + #include "ui/platform_window/platform_window_delegate.h" + ++#include "ui/aura/agl/window_tree_host_platform_agl.h" ++ + namespace ui { + enum class DomCode; + class PlatformWindow; +@@ -26,7 +28,7 @@ namespace aura { + + // The unified WindowTreeHost implementation for platforms + // that implement PlatformWindow. +-class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost, ++class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHostPlatformAgl, + public ui::PlatformWindowDelegate { + public: + explicit WindowTreeHostPlatform(ui::PlatformWindowInitProperties properties, +diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn +index 8a436de0fafe3..754cb123043a9 100644 +--- a/ui/ozone/platform/wayland/BUILD.gn ++++ b/ui/ozone/platform/wayland/BUILD.gn +@@ -400,7 +400,6 @@ source_set("wayland") { + + sources += [ + "host/wayland_extensions.h", +- "host/wayland_extensions_stub.cc", + ] + + deps += [ "extensions/agl" ] +diff --git a/ui/ozone/platform/wayland/extensions/agl/BUILD.gn b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn +index ce289bc5dbbca..01c590e53df58 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/BUILD.gn ++++ b/ui/ozone/platform/wayland/extensions/agl/BUILD.gn +@@ -31,6 +31,8 @@ source_set("agl") { + "host/wayland_extensions_agl.h", + "host/wayland_extensions_agl_impl.cc", + "host/wayland_extensions_agl_impl.h", ++ "host/wayland_window_agl.cc", ++ "host/wayland_window_agl.h", + ] + + deps = [ +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h +index df42fc00c84da..295154dfb437d 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h +@@ -20,6 +20,9 @@ + namespace ui { + + class AglShellWrapper; ++class PlatformWindowDelegate; ++class WaylandConnection; ++class WaylandWindow; + + // AGL extensions implementation for webOS/Lite + class WaylandExtensionsAgl { +@@ -29,9 +32,14 @@ class WaylandExtensionsAgl { + WaylandExtensionsAgl& operator=(const WaylandExtensionsAgl&) = delete; + virtual ~WaylandExtensionsAgl() = default; + ++ virtual std::unique_ptr<WaylandWindow> CreateWaylandWindow( ++ PlatformWindowDelegate* delegate, ++ WaylandConnection* connection) = 0; ++ ++ + virtual AglShellWrapper* GetAglShell() = 0; + }; + + } // namespace ui + +-#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_ +\ No newline at end of file ++#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_H_ +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc +index 26a5f0550c302..87376cbb8a9d3 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc +@@ -22,6 +22,7 @@ + #include "base/logging.h" + #include "ui/base/ui_base_switches.h" + #include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h" ++#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h" + #include "ui/ozone/platform/wayland/extensions/agl/common/wayland_object_agl.h" + #include "ui/ozone/platform/wayland/host/wayland_connection.h" + +@@ -68,8 +69,8 @@ bool WaylandExtensionsAglImpl::Bind(wl_registry* registry, + agl_shell_ = + std::make_unique<AglShellWrapper>(aglshell.release(), connection_); + +- LOG(INFO) << "Waiting until bound..."; +- return agl_shell_->WaitUntilBoundOk(); ++ //LOG(INFO) << "Waiting until bound..."; ++ //return agl_shell_->WaitUntilBoundOk(); + } else { + LOG(INFO) << "Cant bind."; + } +@@ -85,6 +86,12 @@ AglShellWrapper* WaylandExtensionsAglImpl::GetAglShell() { + return agl_shell_.get(); + } + ++std::unique_ptr<WaylandWindow> WaylandExtensionsAglImpl::CreateWaylandWindow( ++ PlatformWindowDelegate* delegate, ++ WaylandConnection* connection) { ++ return std::make_unique<WaylandWindowAgl>(delegate, connection, this); ++} ++ + std::unique_ptr<WaylandExtensions> CreateWaylandExtensions( + WaylandConnection* connection) { + return std::make_unique<WaylandExtensionsAglImpl>(connection); +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h +index f6cbabe99ed0b..3218589f1a09a 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.h +@@ -17,12 +17,17 @@ + #ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_ + #define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_EXTENSIONS_AGL_IMPL_H_ + ++#include <memory> ++ + #include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h" + #include "ui/ozone/platform/wayland/host/wayland_extensions.h" + + namespace ui { + + class AglShellWrapper; ++class PlatformWindowDelegate; ++class WaylandConnection; ++class WaylandWindow; + + // AGL extension implementation for webOS/Lite + class WaylandExtensionsAglImpl : public WaylandExtensions, +@@ -44,6 +49,10 @@ class WaylandExtensionsAglImpl : public WaylandExtensions, + // WaylandExtensionsAgl overrides + AglShellWrapper* GetAglShell() override; + ++ std::unique_ptr<WaylandWindow> CreateWaylandWindow( ++ PlatformWindowDelegate* delegate, ++ WaylandConnection* connection) override; ++ + private: + std::unique_ptr<AglShellWrapper> agl_shell_; + WaylandConnection* connection_; +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.cc b/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.cc +new file mode 100644 +index 0000000000000..97b21ae537658 +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.cc +@@ -0,0 +1,86 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h" ++ ++#include "base/logging.h" ++#include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h" ++#include "ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl.h" ++#include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h" ++#include "ui/ozone/platform/wayland/host/shell_toplevel_wrapper.h" ++#include "ui/ozone/platform/wayland/host/wayland_connection.h" ++ ++namespace ui { ++ ++WaylandWindowAgl::WaylandWindowAgl(PlatformWindowDelegate* delegate, ++ WaylandConnection* connection, ++ WaylandExtensionsAgl* agl_extensions) ++ : WaylandToplevelWindow(delegate, connection), ++ agl_extensions_(agl_extensions) {} ++ ++WaylandWindowAgl::~WaylandWindowAgl() = default; ++ ++void WaylandWindowAgl::SetAglActivateApp(const std::string& app) { ++ if (!agl_extensions_->GetAglShell()) { ++ LOG(ERROR) << "Agl shell wrapper is not created"; ++ return; ++ } ++ ++ agl_extensions_->GetAglShell()->SetAglActivateApp(app); ++ connection()->ScheduleFlush(); ++} ++ ++void WaylandWindowAgl::SetAglAppId(const std::string& title) { ++ if (!shell_toplevel()) { ++ LOG(ERROR) << "Shell toplevel is not created"; ++ return; ++ } ++ ++ shell_toplevel()->SetAppId(title); ++ connection()->ScheduleFlush(); ++} ++ ++void WaylandWindowAgl::SetAglReady() { ++ if (!agl_extensions_->GetAglShell()) { ++ LOG(ERROR) << "Agl shell wrapper is not created"; ++ return; ++ } ++ ++ agl_extensions_->GetAglShell()->SetAglReady(); ++ connection()->ScheduleFlush(); ++} ++ ++void WaylandWindowAgl::SetAglBackground() { ++ if (!agl_extensions_->GetAglShell()) { ++ LOG(ERROR) << "Agl shell wrapper is not created"; ++ return; ++ } ++ ++ agl_extensions_->GetAglShell()->SetAglBackground(this); ++ connection()->ScheduleFlush(); ++} ++ ++void WaylandWindowAgl::SetAglPanel(uint32_t edge) { ++ if (!agl_extensions_->GetAglShell()) { ++ LOG(ERROR) << "Agl shell wrapper is not created"; ++ return; ++ } ++ ++ agl_extensions_->GetAglShell()->SetAglPanel(this, edge); ++ connection()->ScheduleFlush(); ++} ++ ++} // namespace ui +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h +new file mode 100644 +index 0000000000000..b2a922604c001 +--- /dev/null ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h +@@ -0,0 +1,49 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++// ++ ++#ifndef UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_WINDOW_AGL_H_ ++#define UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_WINDOW_AGL_H_ ++ ++#include "ui/ozone/platform/wayland/host/wayland_toplevel_window.h" ++ ++namespace ui { ++ ++class WaylandExtensionsAgl; ++ ++class WaylandWindowAgl : public WaylandToplevelWindow { ++ public: ++ explicit WaylandWindowAgl(PlatformWindowDelegate* delegate, ++ WaylandConnection* connection, ++ WaylandExtensionsAgl* agl_extensions); ++ WaylandWindowAgl(const WaylandWindowAgl&) = delete; ++ WaylandWindowAgl& operator=(const WaylandWindowAgl&) = delete; ++ ~WaylandWindowAgl() override; ++ ++ // Overrides PlatformWindowAgl ++ void SetAglActivateApp(const std::string& app) override; ++ void SetAglAppId(const std::string& title) override; ++ void SetAglReady() override; ++ void SetAglBackground() override; ++ void SetAglPanel(uint32_t edge) override; ++ ++ private: ++ WaylandExtensionsAgl* agl_extensions_; ++}; ++ ++} // namespace ui ++ ++#endif // UI_OZONE_PLATFORM_WAYLAND_EXTENSIONS_AGL_HOST_WAYLAND_WINDOW_AGL_H_ +diff --git a/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc b/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc +index 1cda8aa671ddb..220f759ff30a1 100644 +--- a/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc ++++ b/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc +@@ -90,7 +90,14 @@ gfx::SwapResult GLSurfaceWayland::SwapBuffers(PresentationCallback callback, + return scoped_swap_buffers.result(); + } + window_->root_surface()->set_surface_buffer_scale(scale_factor_); +- return gl::NativeViewGLSurfaceEGL::SwapBuffers(std::move(callback), data); ++ ++ gfx::SwapResult result = gl::NativeViewGLSurfaceEGL::SwapBuffers(std::move(callback), data); ++ ++ if (window_) { ++ window_->OnSurfaceContentChanged(); ++ } ++ ++ return result; + } + + gfx::SwapResult GLSurfaceWayland::PostSubBuffer(int x, +diff --git a/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc b/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc +index c62dd62be4fbf..2959593cfeb5b 100644 +--- a/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc ++++ b/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc +@@ -32,7 +32,7 @@ void GtkPrimarySelectionDevice::SetSelectionSource( + auto* data_source = source ? source->data_source() : nullptr; + gtk_primary_selection_device_set_selection(data_device_.get(), data_source, + serial); +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + + // static +diff --git a/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc b/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc +index 2c39409808128..1e07ae6009776 100644 +--- a/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc ++++ b/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc +@@ -66,7 +66,7 @@ GtkPrimarySelectionDevice* GtkPrimarySelectionDeviceManager::GetDevice() { + connection_, + gtk_primary_selection_device_manager_get_device( + device_manager_.get(), connection_->seat()->wl_object())); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + DCHECK(device_); + return device_.get(); +@@ -77,7 +77,7 @@ GtkPrimarySelectionDeviceManager::CreateSource( + GtkPrimarySelectionSource::Delegate* delegate) { + auto* data_source = + gtk_primary_selection_device_manager_create_source(device_manager_.get()); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + return std::make_unique<GtkPrimarySelectionSource>(data_source, connection_, + delegate); + } +diff --git a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc +index f2407d1c306ec..7a7868ded8a52 100644 +--- a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc ++++ b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc +@@ -69,7 +69,7 @@ void WaylandProxyImpl::DestroyShmForWlBuffer(wl_buffer* buffer) { + } + + void WaylandProxyImpl::FlushForTesting() { +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + ui::PlatformWindowType WaylandProxyImpl::GetWindowType( +diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc +index 7a47d4a636998..8d9e8eea6fd79 100644 +--- a/ui/ozone/platform/wayland/host/wayland_connection.cc ++++ b/ui/ozone/platform/wayland/host/wayland_connection.cc +@@ -264,6 +264,20 @@ bool WaylandConnection::Initialize(bool use_threaded_polling) { + return true; + } + ++void WaylandConnection::ScheduleFlush() { ++ // When we are in tests, the message loop is set later when the ++ // initialization of the OzonePlatform complete. Thus, just ++ // flush directly. This doesn't happen in normal run. ++ if (!base::CurrentUIThread::IsSet()) { ++ Flush(); ++ } else if (!scheduled_flush_) { ++ base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( ++ FROM_HERE, ++ base::BindOnce(&WaylandConnection::Flush, base::Unretained(this))); ++ scheduled_flush_ = true; ++ } ++} ++ + void WaylandConnection::RoundTripQueue() { + if (roundtrip_closure_for_testing_) { + roundtrip_closure_for_testing_.Run(); +@@ -333,6 +347,7 @@ void WaylandConnection::RegisterGlobalObjectFactory( + + void WaylandConnection::Flush() { + wl_display_flush(display_.get()); ++ scheduled_flush_ = false; + } + + void WaylandConnection::UpdateInputDevices() { +@@ -526,7 +541,7 @@ void WaylandConnection::OnPing(void* data, + uint32_t serial) { + auto* connection = static_cast<WaylandConnection*>(data); + xdg_wm_base_pong(shell, serial); +- connection->Flush(); ++ connection->ScheduleFlush(); + } + + // static +@@ -707,7 +722,7 @@ void WaylandConnection::HandleGlobal(wl_registry* registry, + } + + available_globals_.emplace_back(interface, version); +- Flush(); ++ ScheduleFlush(); + } + + } // namespace ui +diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h +index ba293e5bcd088..641f36f13db35 100644 +--- a/ui/ozone/platform/wayland/host/wayland_connection.h ++++ b/ui/ozone/platform/wayland/host/wayland_connection.h +@@ -100,8 +100,8 @@ class WaylandConnection { + + bool Initialize(bool use_threaded_polling = false); + +- // Immediately flushes the Wayland display. +- void Flush(); ++ // Schedules a flush of the Wayland connection. ++ void ScheduleFlush(); + + // Calls wl_display_roundtrip_queue. Might be required during initialization + // of some objects that should block until they are initialized. +@@ -388,6 +388,9 @@ class WaylandConnection { + friend class ZwpIdleInhibitManager; + friend class ZwpPrimarySelectionDeviceManager; + ++ // Immediately flushes the Wayland display. ++ void Flush(); ++ + void RegisterGlobalObjectFactory(const char* interface_name, + wl::GlobalObjectFactory factory); + +@@ -535,6 +538,8 @@ class WaylandConnection { + // This is set if delegated composition should not be used. + bool overlay_delegation_disabled_ = false; + ++ bool scheduled_flush_ = false; ++ + wl::SerialTracker serial_tracker_; + + // Global Wayland interfaces available in the current session, with their +diff --git a/ui/ozone/platform/wayland/host/wayland_cursor.cc b/ui/ozone/platform/wayland/host/wayland_cursor.cc +index 1b7d303291cff..a384212c84134 100644 +--- a/ui/ozone/platform/wayland/host/wayland_cursor.cc ++++ b/ui/ozone/platform/wayland/host/wayland_cursor.cc +@@ -107,7 +107,7 @@ void WaylandCursor::HideCursor() { + wl_surface_attach(pointer_surface_.get(), nullptr, 0, 0); + wl_surface_commit(pointer_surface_.get()); + +- connection_->Flush(); ++ connection_->ScheduleFlush(); + + if (listener_) + listener_->OnCursorBufferAttached(nullptr); +@@ -166,7 +166,7 @@ void WaylandCursor::AttachAndCommit(wl_buffer* buffer, + wl_pointer_set_cursor(pointer_->wl_object(), pointer_enter_serial->value, + pointer_surface_.get(), hotspot_x_dip, hotspot_y_dip); + +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + } // namespace ui +diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.cc b/ui/ozone/platform/wayland/host/wayland_data_device.cc +index a7adfd313188b..fe16d8577fd35 100644 +--- a/ui/ozone/platform/wayland/host/wayland_data_device.cc ++++ b/ui/ozone/platform/wayland/host/wayland_data_device.cc +@@ -51,7 +51,7 @@ void WaylandDataDevice::StartDrag(const WaylandDataSource& data_source, + origin_window.root_surface()->surface(), + icon_surface, serial); + drag_delegate_->DrawIcon(); +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + + void WaylandDataDevice::ResetDragDelegate() { +@@ -92,7 +92,7 @@ void WaylandDataDevice::SetSelectionSource(WaylandDataSource* source, + uint32_t serial) { + auto* data_source = source ? source->data_source() : nullptr; + wl_data_device_set_selection(data_device_.get(), data_source, serial); +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + + void WaylandDataDevice::ReadDragDataFromFD(base::ScopedFD fd, +@@ -146,7 +146,7 @@ void WaylandDataDevice::OnEnter(void* data, + gfx::PointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), window); + self->drag_delegate_->OnDragEnter(window, point, serial); + +- self->connection()->Flush(); ++ self->connection()->ScheduleFlush(); + } + + void WaylandDataDevice::OnMotion(void* data, +@@ -167,7 +167,7 @@ void WaylandDataDevice::OnDrop(void* data, wl_data_device* data_device) { + auto* self = static_cast<WaylandDataDevice*>(data); + if (self->drag_delegate_) { + self->drag_delegate_->OnDragDrop(); +- self->connection()->Flush(); ++ self->connection()->ScheduleFlush(); + } + + // There are buggy Exo versions, which send 'drop' event (even for +@@ -184,7 +184,7 @@ void WaylandDataDevice::OnLeave(void* data, wl_data_device* data_device) { + auto* self = static_cast<WaylandDataDevice*>(data); + if (self->drag_delegate_) { + self->drag_delegate_->OnDragLeave(); +- self->connection()->Flush(); ++ self->connection()->ScheduleFlush(); + } + self->ResetDragDelegateIfNotDragSource(); + } +diff --git a/ui/ozone/platform/wayland/host/wayland_data_device_base.cc b/ui/ozone/platform/wayland/host/wayland_data_device_base.cc +index 203e907f92bfa..a0c72971ac567 100644 +--- a/ui/ozone/platform/wayland/host/wayland_data_device_base.cc ++++ b/ui/ozone/platform/wayland/host/wayland_data_device_base.cc +@@ -64,7 +64,7 @@ void WaylandDataDeviceBase::RegisterDeferredReadCallback() { + static constexpr wl_callback_listener kSyncCallbackListener = { + .done = &OnSyncDone}; + wl_callback_add_listener(sync_callback_.get(), &kSyncCallbackListener, this); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + void WaylandDataDeviceBase::RegisterDeferredReadClosure( +diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc +index 705bdec41a1b7..dfa5789e8d149 100644 +--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc ++++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc +@@ -256,7 +256,7 @@ void WaylandDataDragController::OnDragSurfaceFrame(void* data, + DCHECK(self); + self->DrawIconInternal(); + self->icon_frame_callback_.reset(); +- self->connection_->Flush(); ++ self->connection_->ScheduleFlush(); + } + + SkBitmap WaylandDataDragController::GetIconBitmap() { +diff --git a/ui/ozone/platform/wayland/host/wayland_data_source.cc b/ui/ozone/platform/wayland/host/wayland_data_source.cc +index c0e95c8a22e48..c294ffb8836aa 100644 +--- a/ui/ozone/platform/wayland/host/wayland_data_source.cc ++++ b/ui/ozone/platform/wayland/host/wayland_data_source.cc +@@ -130,7 +130,7 @@ void DataSource<wl_data_source>::Offer( + const std::vector<std::string>& mime_types) { + for (auto& mime_type : mime_types) + wl_data_source_offer(data_source_.get(), mime_type.c_str()); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + template <typename T> +@@ -165,7 +165,7 @@ void DataSource<gtk_primary_selection_source>::Offer( + const std::vector<std::string>& mime_types) { + for (const auto& mime_type : mime_types) + gtk_primary_selection_source_offer(data_source_.get(), mime_type.c_str()); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + template <> +@@ -185,7 +185,7 @@ void DataSource<zwp_primary_selection_source_v1>::Offer( + for (const auto& mime_type : mime_types) + zwp_primary_selection_source_v1_offer(data_source_.get(), + mime_type.c_str()); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + template class DataSource<gtk_primary_selection_source>; +diff --git a/ui/ozone/platform/wayland/host/wayland_drm.cc b/ui/ozone/platform/wayland/host/wayland_drm.cc +index 68570a9aacb2c..2b3b16e8859cb 100644 +--- a/ui/ozone/platform/wayland/host/wayland_drm.cc ++++ b/ui/ozone/platform/wayland/host/wayland_drm.cc +@@ -58,7 +58,7 @@ WaylandDrm::WaylandDrm(wl_drm* drm, WaylandConnection* connection) + .capabilities = &OnCapabilities, + }; + wl_drm_add_listener(wl_drm_.get(), &kDrmListener, this); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + + // A roundtrip after binding guarantees that the client has received all + // supported formats and capabilities of the device. +@@ -92,7 +92,7 @@ void WaylandDrm::CreateBuffer(const base::ScopedFD& fd, + wl::Object<wl_buffer> buffer(wl_drm_create_prime_buffer( + wl_drm_.get(), fd.get(), size.width(), size.height(), format, offset[0], + stride[0], offset[1], stride[1], offset[2], stride[2])); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + + std::move(callback).Run(std::move(buffer)); + } +@@ -146,7 +146,7 @@ void WaylandDrm::Authenticate(const char* drm_device_path) { + } + + wl_drm_authenticate(wl_drm_.get(), magic); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + + // Do the roundtrip to make sure the server processes this request and + // authenticates us. +diff --git a/ui/ozone/platform/wayland/host/wayland_extensions.h b/ui/ozone/platform/wayland/host/wayland_extensions.h +index 3bd2fd7a211ae..f6ed47507d217 100644 +--- a/ui/ozone/platform/wayland/host/wayland_extensions.h ++++ b/ui/ozone/platform/wayland/host/wayland_extensions.h +@@ -25,7 +25,9 @@ namespace ui { + + class ShellToplevelWrapper; + class ShellPopupWrapper; ++class PlatformWindowDelegate; + class WaylandConnection; ++class WaylandWindow; + + // Wayland extensions abstract interface to support extending of the Wayland + // protocol. Inherit it to provide your own Wayland extensions implementation. +@@ -45,6 +47,10 @@ class WaylandExtensions { + + // Checks whether the extensions have bound shell object(s). + virtual bool HasShellObject() const = 0; ++ ++ virtual std::unique_ptr<WaylandWindow> CreateWaylandWindow( ++ PlatformWindowDelegate* delegate, ++ WaylandConnection* connection) = 0; + }; + + // Creates Wayland extensions. +diff --git a/ui/ozone/platform/wayland/host/wayland_keyboard.cc b/ui/ozone/platform/wayland/host/wayland_keyboard.cc +index 2b7fc05d426e1..f24d6993b26ac 100644 +--- a/ui/ozone/platform/wayland/host/wayland_keyboard.cc ++++ b/ui/ozone/platform/wayland/host/wayland_keyboard.cc +@@ -114,7 +114,7 @@ class WaylandKeyboard::ZCRExtendedKeyboard { + + void AckKey(uint32_t serial, bool handled) { + zcr_extended_keyboard_v1_ack_key(obj_.get(), serial, handled); +- keyboard_->connection_->Flush(); ++ keyboard_->connection_->ScheduleFlush(); + } + + // Returns true if connected object will send zcr_extended_keyboard::peek_key. +@@ -373,7 +373,7 @@ void WaylandKeyboard::FlushInput(base::OnceClosure closure) { + .done = &OnSyncDone, + }; + wl_callback_add_listener(sync_callback_.get(), &kSyncCallbackListener, this); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + void WaylandKeyboard::DispatchKey(unsigned int key, +diff --git a/ui/ozone/platform/wayland/host/wayland_popup.cc b/ui/ozone/platform/wayland/host/wayland_popup.cc +index f1e886f8675fb..28903c031e6ce 100644 +--- a/ui/ozone/platform/wayland/host/wayland_popup.cc ++++ b/ui/ozone/platform/wayland/host/wayland_popup.cc +@@ -132,7 +132,7 @@ void WaylandPopup::Show(bool inactive) { + return; + } + +- connection()->Flush(); ++ connection()->ScheduleFlush(); + WaylandWindow::Show(inactive); + } + +@@ -158,7 +158,7 @@ void WaylandPopup::Hide() { + decorated_via_aura_popup_ = false; + } + +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + + bool WaylandPopup::IsVisible() const { +@@ -256,14 +256,14 @@ void WaylandPopup::ShowTooltip(const std::u16string& text, + if (zaura_surface && + zaura_surface->ShowTooltip(text, position, zaura_shell_trigger, + show_delay, hide_delay)) { +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + } + + void WaylandPopup::HideTooltip() { + auto* zaura_surface = GetZAuraSurface(); + if (zaura_surface && zaura_surface->HideTooltip()) { +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + } + +diff --git a/ui/ozone/platform/wayland/host/wayland_seat.cc b/ui/ozone/platform/wayland/host/wayland_seat.cc +index 3b05da49eb6b8..5f70725a9a9dd 100644 +--- a/ui/ozone/platform/wayland/host/wayland_seat.cc ++++ b/ui/ozone/platform/wayland/host/wayland_seat.cc +@@ -128,7 +128,7 @@ void WaylandSeat::HandleCapabilities(void* data, + + connection_->UpdateInputDevices(); + connection_->UpdateCursor(); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + } // namespace ui +diff --git a/ui/ozone/platform/wayland/host/wayland_shm.cc b/ui/ozone/platform/wayland/host/wayland_shm.cc +index b264ad88962bb..95c19d9962085 100644 +--- a/ui/ozone/platform/wayland/host/wayland_shm.cc ++++ b/ui/ozone/platform/wayland/host/wayland_shm.cc +@@ -62,7 +62,7 @@ wl::Object<wl_buffer> WaylandShm::CreateBuffer(const base::ScopedFD& fd, + with_alpha_channel ? WL_SHM_FORMAT_ARGB8888 : WL_SHM_FORMAT_XRGB8888; + wl::Object<wl_buffer> shm_buffer(wl_shm_pool_create_buffer( + pool.get(), 0, size.width(), size.height(), size.width() * 4, format)); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + return shm_buffer; + } + +diff --git a/ui/ozone/platform/wayland/host/wayland_surface.cc b/ui/ozone/platform/wayland/host/wayland_surface.cc +index 47dc846390898..2a04d28b05484 100644 +--- a/ui/ozone/platform/wayland/host/wayland_surface.cc ++++ b/ui/ozone/platform/wayland/host/wayland_surface.cc +@@ -305,7 +305,7 @@ void WaylandSurface::UpdateBufferDamageRegion(const gfx::Rect& damage_px) { + void WaylandSurface::Commit(bool flush) { + wl_surface_commit(surface_.get()); + if (flush) +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + void WaylandSurface::set_surface_buffer_scale(float scale) { +diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc +index 898113178a783..1b489b327fa29 100644 +--- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc ++++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc +@@ -127,7 +127,7 @@ void WaylandToplevelWindow::DispatchHostWindowDragMovement( + else + shell_toplevel_->SurfaceResize(connection(), hittest); + +- connection()->Flush(); ++ connection()->ScheduleFlush(); + #if !BUILDFLAG(IS_CHROMEOS_LACROS) + // TODO(crbug.com/1454893): Revisit to resolve the correct impl. + connection()->event_source()->ResetPointerFlags(); +@@ -176,7 +176,7 @@ void WaylandToplevelWindow::Hide() { + gtk_surface1_.reset(); + + shell_toplevel_.reset(); +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + + bool WaylandToplevelWindow::IsVisible() const { +@@ -193,7 +193,7 @@ void WaylandToplevelWindow::SetTitle(const std::u16string& title) { + + if (shell_toplevel_) { + shell_toplevel_->SetTitle(title); +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + } + +@@ -288,13 +288,13 @@ void WaylandToplevelWindow::Activate() { + // but nothing more happens (until the user moves the mouse over a Lacros + // window in which case events will start and the activation will come + // through). +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + + void WaylandToplevelWindow::Deactivate() { + if (shell_toplevel_ && shell_toplevel_->SupportsActivation()) { + shell_toplevel_->Deactivate(); +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + } + +@@ -722,14 +722,14 @@ void WaylandToplevelWindow::ShowTooltip( + if (zaura_surface && + zaura_surface->ShowTooltip(text, position, zaura_shell_trigger, + show_delay, hide_delay)) { +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + } + + void WaylandToplevelWindow::HideTooltip() { + auto* zaura_surface = GetZAuraSurface(); + if (zaura_surface && zaura_surface->HideTooltip()) { +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + } + +@@ -1001,7 +1001,7 @@ void WaylandToplevelWindow::TriggerStateChanges() { + } + + delegate()->OnWindowStateChanged(previous_state_, state_); +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + + void WaylandToplevelWindow::SetWindowState(PlatformWindowState state) { +@@ -1035,7 +1035,7 @@ void WaylandToplevelWindow::SetSizeConstraints() { + shell_toplevel_->SetCanMaximize(delegate()->CanMaximize()); + shell_toplevel_->SetCanFullscreen(delegate()->CanFullscreen()); + +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + + void WaylandToplevelWindow::SetOrResetRestoredBounds() { +diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc +index ad4366edfe4db..9a18c567bcbcc 100644 +--- a/ui/ozone/platform/wayland/host/wayland_window.cc ++++ b/ui/ozone/platform/wayland/host/wayland_window.cc +@@ -686,6 +686,10 @@ std::string WaylandWindow::WindowStates::ToString() const { + return states; + } + ++void WaylandWindow::OnSurfaceContentChanged() { ++ connection_->ScheduleFlush(); ++} ++ + void WaylandWindow::HandleToplevelConfigure(int32_t widht, + int32_t height, + const WindowStates& window_states) { +@@ -832,7 +836,7 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { + root_surface_->EnableTrustedDamageIfPossible(); + root_surface_->ApplyPendingState(); + +- connection_->Flush(); ++ connection_->ScheduleFlush(); + + return true; + } +diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h +index d68d4d818f28f..2c5afbb3de99c 100644 +--- a/ui/ozone/platform/wayland/host/wayland_window.h ++++ b/ui/ozone/platform/wayland/host/wayland_window.h +@@ -230,6 +230,8 @@ class WaylandWindow : public PlatformWindow, + // currently bound to. + virtual void HandleSurfaceConfigure(uint32_t serial); + ++ void OnSurfaceContentChanged(); ++ + struct WindowStates { + bool is_maximized = false; + bool is_fullscreen = false; +diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc +index e38565635a583..ff201c038efb7 100644 +--- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc ++++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc +@@ -91,7 +91,7 @@ class WaylandWindowDragController::ExtendedDragSource { + auto* surface = window ? window->root_surface()->surface() : nullptr; + zcr_extended_drag_source_v1_drag(source_.get(), surface, offset.x(), + offset.y()); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + private: +diff --git a/ui/ozone/platform/wayland/host/wayland_window_factory.cc b/ui/ozone/platform/wayland/host/wayland_window_factory.cc +index 6f66c6654819c..e2bc045e4b3fb 100644 +--- a/ui/ozone/platform/wayland/host/wayland_window_factory.cc ++++ b/ui/ozone/platform/wayland/host/wayland_window_factory.cc +@@ -12,6 +12,8 @@ + #include "ui/ozone/platform/wayland/host/wayland_window.h" + #include "ui/platform_window/platform_window_init_properties.h" + ++#include "ui/ozone/platform/wayland/host/wayland_extensions.h" ++ + namespace ui { + + // static +@@ -29,6 +31,12 @@ std::unique_ptr<WaylandWindow> WaylandWindow::Create( + // toplevel window instead. + if (auto* parent = connection->window_manager()->GetWindow( + properties.parent_widget)) { ++ if (connection->extensions()) { ++ window = connection->extensions()->CreateWaylandWindow(delegate, ++ connection); ++ if (window) ++ break; ++ } + window = std::make_unique<WaylandPopup>(delegate, connection, parent); + } else { + DLOG(WARNING) << "Failed to determine parent for menu/popup window."; +@@ -40,6 +48,12 @@ std::unique_ptr<WaylandWindow> WaylandWindow::Create( + case PlatformWindowType::kDrag: + // TODO(crbug.com/1399419): Figure out what kind of surface we need to + // create for kBubble and kDrag windows. ++ if (connection->extensions()) { ++ window = ++ connection->extensions()->CreateWaylandWindow(delegate, connection); ++ if (window) ++ break; ++ } + window = std::make_unique<WaylandToplevelWindow>(delegate, connection); + break; + default: +diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc b/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc +index 33935db68eadd..15f600ed7a126 100644 +--- a/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc ++++ b/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc +@@ -104,7 +104,7 @@ void WaylandZwpLinuxDmabuf::CreateBuffer(const base::ScopedFD& fd, + // created buffer and notify the client about it via the |callback|. + pending_params_.emplace(std::move(params), std::move(callback)); + } +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + bool WaylandZwpLinuxDmabuf::CanCreateBufferImmed() const { +@@ -147,7 +147,7 @@ void WaylandZwpLinuxDmabuf::NotifyRequestCreateBufferDone( + DCHECK(it != pending_params_.end()); + std::move(it->second).Run(wl::Object<wl_buffer>(new_buffer)); + pending_params_.erase(it); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + // static +diff --git a/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc b/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc +index 293c09a7e35f2..d36db127ec057 100644 +--- a/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc ++++ b/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc +@@ -158,7 +158,7 @@ void XdgForeignWrapperImpl<zxdg_exporter_v1, zxdg_exported_v1>:: + &kXdgExportedListener, this); + + exported_surfaces_.emplace_back(std::move(exported_surface)); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + template <> +@@ -174,7 +174,7 @@ void XdgForeignWrapperImpl<zxdg_exporter_v2, zxdg_exported_v2>:: + &kXdgExportedListener, this); + + exported_surfaces_.emplace_back(std::move(exported_surface)); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + // static +diff --git a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc +index 64c8f2663ae60..b0d8f27aebbf9 100644 +--- a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc ++++ b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc +@@ -239,7 +239,7 @@ bool XDGPopupWrapperImpl::SetBounds(const gfx::Rect& new_bounds) { + xdg_popup_reposition(xdg_popup_.get(), positioner.get(), + ++next_reposition_token_); + +- connection_->Flush(); ++ connection_->ScheduleFlush(); + return true; + } + +diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc +index c4dd8c8e78ce4..67702ecc8fa4f 100644 +--- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc ++++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc +@@ -39,7 +39,7 @@ bool XDGSurfaceWrapperImpl::Initialize() { + }; + xdg_surface_add_listener(xdg_surface_.get(), &kXdgSurfaceListener, this); + +- connection_->Flush(); ++ connection_->ScheduleFlush(); + return true; + } + +diff --git a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc +index 0673c59185348..b9462c60a2eee 100644 +--- a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc ++++ b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc +@@ -720,7 +720,7 @@ void XDGToplevelWrapperImpl::ShowSnapPreview( + + void XDGToplevelWrapperImpl::AckRotateFocus(uint32_t serial, uint32_t handled) { + zaura_toplevel_ack_rotate_focus(aura_toplevel_.get(), serial, handled); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + + XDGToplevelWrapperImpl* XDGToplevelWrapperImpl::AsXDGToplevelWrapper() { +diff --git a/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc b/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc +index 9057d1bea0116..97c1624e200ac 100644 +--- a/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc ++++ b/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc +@@ -32,7 +32,7 @@ void ZwpPrimarySelectionDevice::SetSelectionSource( + auto* data_source = source ? source->data_source() : nullptr; + zwp_primary_selection_device_v1_set_selection(data_device_.get(), data_source, + serial); +- connection()->Flush(); ++ connection()->ScheduleFlush(); + } + + // static +diff --git a/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc b/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc +index 9d5d79635b66d..2ca82ce6031ba 100644 +--- a/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc ++++ b/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc +@@ -66,7 +66,7 @@ ZwpPrimarySelectionDevice* ZwpPrimarySelectionDeviceManager::GetDevice() { + connection_, + zwp_primary_selection_device_manager_v1_get_device( + device_manager_.get(), connection_->seat()->wl_object())); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + } + DCHECK(device_); + return device_.get(); +@@ -77,7 +77,7 @@ ZwpPrimarySelectionDeviceManager::CreateSource( + ZwpPrimarySelectionSource::Delegate* delegate) { + auto* data_source = zwp_primary_selection_device_manager_v1_create_source( + device_manager_.get()); +- connection_->Flush(); ++ connection_->ScheduleFlush(); + return std::make_unique<ZwpPrimarySelectionSource>(data_source, connection_, + delegate); + } +diff --git a/ui/platform_window/agl/platform_window_agl.h b/ui/platform_window/agl/platform_window_agl.h +new file mode 100644 +index 0000000000000..4bc915d663e72 +--- /dev/null ++++ b/ui/platform_window/agl/platform_window_agl.h +@@ -0,0 +1,36 @@ ++// Copyright 2021 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#ifndef UI_PLATFORM_WINDOW_AGL_PLATFORM_WINDOW_AGL_H_ ++#define UI_PLATFORM_WINDOW_AGL_PLATFORM_WINDOW_AGL_H_ ++ ++#include <string> ++ ++namespace ui { ++ ++// AGL additions for platform window. ++class PlatformWindowAgl { ++ public: ++ virtual void SetAglActivateApp(const std::string& app) {} ++ virtual void SetAglAppId(const std::string& title) {} ++ virtual void SetAglReady() {} ++ virtual void SetAglBackground() {} ++ virtual void SetAglPanel(uint32_t edge) {} ++}; ++ ++} // namespace ui ++ ++#endif // UI_PLATFORM_WINDOW_AGL_PLATFORM_WINDOW_AGL_H_ +diff --git a/ui/platform_window/platform_window.h b/ui/platform_window/platform_window.h +index 845da9467d6a4..a9b28388ec649 100644 +--- a/ui/platform_window/platform_window.h ++++ b/ui/platform_window/platform_window.h +@@ -9,6 +9,7 @@ + #include <string> + #include <vector> + ++#include "agl/platform_window_agl.h" + #include "base/component_export.h" + #include "ui/base/class_property.h" + #include "ui/base/ui_base_types.h" +@@ -32,7 +33,8 @@ class PlatformCursor; + + // Generic PlatformWindow interface. + class COMPONENT_EXPORT(PLATFORM_WINDOW) PlatformWindow +- : public PropertyHandler { ++ : public PropertyHandler, ++ public PlatformWindowAgl { + public: + PlatformWindow(); + ~PlatformWindow() override; +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0003-agl-Only-bind-to-agl_shell-if-it-s-the-browser-proce.patch b/recipes-wam/cef/files/chromium/0003-agl-Only-bind-to-agl_shell-if-it-s-the-browser-proce.patch new file mode 100644 index 00000000..4de7779f --- /dev/null +++ b/recipes-wam/cef/files/chromium/0003-agl-Only-bind-to-agl_shell-if-it-s-the-browser-proce.patch @@ -0,0 +1,41 @@ +From ab07780e04f15b511967cd609b70fb97abcea96f Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Sat, 27 May 2023 15:55:17 +0200 +Subject: [PATCH 03/33] [agl] Only bind to agl_shell if it's the browser + process + +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + .../extensions/agl/host/wayland_extensions_agl_impl.cc | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc +index 87376cbb8a9d3..075b3010ea8a1 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc +@@ -20,6 +20,7 @@ + + #include "base/command_line.h" + #include "base/logging.h" ++#include "content/public/common/content_switches.h" + #include "ui/base/ui_base_switches.h" + #include "ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h" + #include "ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h" +@@ -45,8 +46,12 @@ bool WaylandExtensionsAglImpl::Bind(wl_registry* registry, + uint32_t name, + const char* interface, + uint32_t version) { +- bool should_use_agl_shell = base::CommandLine::ForCurrentProcess()->HasSwitch( +- switches::kAglShellAppId); ++ bool has_agl_shell_switch = base::CommandLine::ForCurrentProcess()->HasSwitch( ++ switches::kAglShellAppId); ++ bool is_browser_process = !base::CommandLine::ForCurrentProcess()->HasSwitch( ++ switches::kProcessType); ++ bool should_use_agl_shell = has_agl_shell_switch && is_browser_process; ++ + bool can_bind = wl::CanBind(interface, version, kMinAglShellExtensionVersion, + kMaxAglShellExtensionVersion); + bool is_agl_shell_interface = (strcmp(interface, "agl_shell") == 0); +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0004-agl-Add-a-method-to-check-if-the-agl-window-is-confi.patch b/recipes-wam/cef/files/chromium/0004-agl-Add-a-method-to-check-if-the-agl-window-is-confi.patch new file mode 100644 index 00000000..398023ca --- /dev/null +++ b/recipes-wam/cef/files/chromium/0004-agl-Add-a-method-to-check-if-the-agl-window-is-confi.patch @@ -0,0 +1,69 @@ +From 76cb42f0773ecff97710d7d5ea20cd16b8781d51 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Fri, 30 Jun 2023 10:25:10 +0200 +Subject: [PATCH 04/33] [agl] Add a method to check if the agl window is + configured + +This will be used on cef side to know the time when the window can be +displayed. + +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + ui/aura/agl/window_tree_host_agl.h | 1 + + ui/aura/agl/window_tree_host_platform_agl.cc | 4 ++++ + ui/aura/agl/window_tree_host_platform_agl.h | 1 + + ui/platform_window/agl/platform_window_agl.h | 1 + + 4 files changed, 7 insertions(+) + +diff --git a/ui/aura/agl/window_tree_host_agl.h b/ui/aura/agl/window_tree_host_agl.h +index 858a078d939d0..b9aa451c8332e 100644 +--- a/ui/aura/agl/window_tree_host_agl.h ++++ b/ui/aura/agl/window_tree_host_agl.h +@@ -35,6 +35,7 @@ class AURA_EXPORT WindowTreeHostAgl { + virtual void SetAglReady() {} + virtual void SetAglBackground() {} + virtual void SetAglPanel(uint32_t edge) {} ++ virtual bool IsSurfaceConfigured() const { return false; } + }; + + } // namespace aura +diff --git a/ui/aura/agl/window_tree_host_platform_agl.cc b/ui/aura/agl/window_tree_host_platform_agl.cc +index e34595fe0ed9c..67190e1da6973 100644 +--- a/ui/aura/agl/window_tree_host_platform_agl.cc ++++ b/ui/aura/agl/window_tree_host_platform_agl.cc +@@ -47,4 +47,8 @@ void WindowTreeHostPlatformAgl::SetAglPanel(uint32_t edge) { + window_tree_host_platform_->platform_window()->SetAglPanel(edge); + } + ++bool WindowTreeHostPlatformAgl::IsSurfaceConfigured() const { ++ return window_tree_host_platform_->platform_window()->IsSurfaceConfigured(); ++} ++ + } // namespace aura +diff --git a/ui/aura/agl/window_tree_host_platform_agl.h b/ui/aura/agl/window_tree_host_platform_agl.h +index 181eefae346f7..e5a29fa1bfca3 100644 +--- a/ui/aura/agl/window_tree_host_platform_agl.h ++++ b/ui/aura/agl/window_tree_host_platform_agl.h +@@ -41,6 +41,7 @@ class AURA_EXPORT WindowTreeHostPlatformAgl : public aura::WindowTreeHost { + void SetAglReady() override; + void SetAglBackground() override; + void SetAglPanel(uint32_t edge) override; ++ bool IsSurfaceConfigured() const override; + + private: + aura::WindowTreeHostPlatform* window_tree_host_platform_; +diff --git a/ui/platform_window/agl/platform_window_agl.h b/ui/platform_window/agl/platform_window_agl.h +index 4bc915d663e72..cab1f42272772 100644 +--- a/ui/platform_window/agl/platform_window_agl.h ++++ b/ui/platform_window/agl/platform_window_agl.h +@@ -29,6 +29,7 @@ class PlatformWindowAgl { + virtual void SetAglReady() {} + virtual void SetAglBackground() {} + virtual void SetAglPanel(uint32_t edge) {} ++ virtual bool IsSurfaceConfigured() { return false; } + }; + + } // namespace ui +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0005-agl-Start-using-agl-shell-version-4.patch b/recipes-wam/cef/files/chromium/0005-agl-Start-using-agl-shell-version-4.patch new file mode 100644 index 00000000..8b5a3812 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0005-agl-Start-using-agl-shell-version-4.patch @@ -0,0 +1,348 @@ +From 98de96755da14f4cabf2447ce88a01cd3cdca770 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Sun, 2 Jul 2023 11:11:07 +0200 +Subject: [PATCH 05/33] [agl] Start using agl-shell version 4 + +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + ui/aura/agl/window_tree_host_agl.h | 1 + + ui/aura/agl/window_tree_host_platform_agl.cc | 4 + + ui/aura/agl/window_tree_host_platform_agl.h | 1 + + .../extensions/agl/host/agl_shell_wrapper.cc | 9 + + .../extensions/agl/host/agl_shell_wrapper.h | 1 + + .../agl/host/wayland_extensions_agl_impl.cc | 2 +- + .../extensions/agl/host/wayland_window_agl.cc | 10 + + .../extensions/agl/host/wayland_window_agl.h | 1 + + .../extensions/agl/protocol/agl-shell.xml | 185 +++++++++++++++++- + ui/platform_window/agl/platform_window_agl.h | 1 + + 10 files changed, 213 insertions(+), 2 deletions(-) + +diff --git a/ui/aura/agl/window_tree_host_agl.h b/ui/aura/agl/window_tree_host_agl.h +index b9aa451c8332e..c5213f75e623e 100644 +--- a/ui/aura/agl/window_tree_host_agl.h ++++ b/ui/aura/agl/window_tree_host_agl.h +@@ -36,6 +36,7 @@ class AURA_EXPORT WindowTreeHostAgl { + virtual void SetAglBackground() {} + virtual void SetAglPanel(uint32_t edge) {} + virtual bool IsSurfaceConfigured() const { return false; } ++ virtual void SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {} + }; + + } // namespace aura +diff --git a/ui/aura/agl/window_tree_host_platform_agl.cc b/ui/aura/agl/window_tree_host_platform_agl.cc +index 67190e1da6973..b9bae3f3b9bdc 100644 +--- a/ui/aura/agl/window_tree_host_platform_agl.cc ++++ b/ui/aura/agl/window_tree_host_platform_agl.cc +@@ -51,4 +51,8 @@ bool WindowTreeHostPlatformAgl::IsSurfaceConfigured() const { + return window_tree_host_platform_->platform_window()->IsSurfaceConfigured(); + } + ++void WindowTreeHostPlatformAgl::SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { ++ window_tree_host_platform_->platform_window()->SetupActivationArea(x, y, width, height); ++} ++ + } // namespace aura +diff --git a/ui/aura/agl/window_tree_host_platform_agl.h b/ui/aura/agl/window_tree_host_platform_agl.h +index e5a29fa1bfca3..30e160736e327 100644 +--- a/ui/aura/agl/window_tree_host_platform_agl.h ++++ b/ui/aura/agl/window_tree_host_platform_agl.h +@@ -42,6 +42,7 @@ class AURA_EXPORT WindowTreeHostPlatformAgl : public aura::WindowTreeHost { + void SetAglBackground() override; + void SetAglPanel(uint32_t edge) override; + bool IsSurfaceConfigured() const override; ++ void SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override; + + private: + aura::WindowTreeHostPlatform* window_tree_host_platform_; +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc +index c74fa5d9cd221..0d5d79c4738df 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc ++++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.cc +@@ -110,4 +110,13 @@ bool AglShellWrapper::WaitUntilBoundOk() { + return bound_ok_; + } + ++void AglShellWrapper::SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { ++#ifdef AGL_SHELL_SET_ACTIVATE_REGION_SINCE_VERSION ++ wl_output* output = ++ connection_->wayland_output_manager()->GetPrimaryOutput()->get_output(); ++ agl_shell_set_activate_region(agl_shell_.get(), output, x, y, ++ width, height); ++#endif ++} ++ + } // namespace ui +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h +index 2ab765883057e..1c2074e1b4306 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h ++++ b/ui/ozone/platform/wayland/extensions/agl/host/agl_shell_wrapper.h +@@ -39,6 +39,7 @@ class AglShellWrapper { + void SetAglPanel(WaylandWindow* window, uint32_t edge); + void SetAglBackground(WaylandWindow* window); + void SetAglReady(); ++ void SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height); + bool WaitUntilBoundOk(); + + static void AglShellBoundOk(void* data, struct agl_shell*); +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc +index 075b3010ea8a1..8f9d938cdd1f6 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_extensions_agl_impl.cc +@@ -32,7 +32,7 @@ namespace ui { + namespace { + + constexpr uint32_t kMinAglShellExtensionVersion = 1; +-constexpr uint32_t kMaxAglShellExtensionVersion = 3; ++constexpr uint32_t kMaxAglShellExtensionVersion = 4; + + } // namespace + +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.cc b/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.cc +index 97b21ae537658..f92406d455de1 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.cc ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.cc +@@ -83,4 +83,14 @@ void WaylandWindowAgl::SetAglPanel(uint32_t edge) { + connection()->ScheduleFlush(); + } + ++void WaylandWindowAgl::SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { ++ if (!agl_extensions_->GetAglShell()) { ++ LOG(ERROR) << "Agl shell wrapper is not created"; ++ return; ++ } ++ ++ agl_extensions_->GetAglShell()->SetupActivationArea(x, y, width, height); ++ connection()->ScheduleFlush(); ++} ++ + } // namespace ui +diff --git a/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h b/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h +index b2a922604c001..d21d2d9387215 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h ++++ b/ui/ozone/platform/wayland/extensions/agl/host/wayland_window_agl.h +@@ -39,6 +39,7 @@ class WaylandWindowAgl : public WaylandToplevelWindow { + void SetAglReady() override; + void SetAglBackground() override; + void SetAglPanel(uint32_t edge) override; ++ void SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override; + + private: + WaylandExtensionsAgl* agl_extensions_; +diff --git a/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml +index ad5553d61f189..e010a80808c69 100644 +--- a/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml ++++ b/ui/ozone/platform/wayland/extensions/agl/protocol/agl-shell.xml +@@ -22,7 +22,7 @@ + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + </copyright> +- <interface name="agl_shell" version="3"> ++ <interface name="agl_shell" version="8"> + <description summary="user interface for Automotive Grade Linux platform"> + Starting with version 2 of the protocol, the client is required to wait + for the 'bound_ok' or 'bound_fail' events in order to proceed further. +@@ -174,6 +174,189 @@ + <arg name="state" type="uint" enum="app_state"/> + </event> + ++ <request name="set_activate_region" since="4"> ++ <description summary="sets a specific region to activate"> ++ A hint for the compositor to use a custom area, rather than ++ inferring the activation area. If any panels are used ++ the compositor computes the activation area by subtracting the ++ panels geometry area. If no panels are used then the entire output ++ is being used. This request changes that as to hint the compositor ++ to use the supplied rectangle and ignore any potential panels ++ that might been set-up previously. + ++ In order for this request to take effect it will need to happen ++ before the 'ready' request in order for the compositor to make use of it. ++ Note that any 'set_panel' request be will not be honored, if this request ++ has been called. ++ ++ The x and y coordinates use the top-left corner as the origin. The ++ rectangle area shouldn't exceed the output area, while an area smaller ++ than the output, would basically result in showing up the background ++ surface. ++ </description> ++ <arg name="output" type="object" interface="wl_output"/> ++ <arg name="x" type="int" summary="x position of rectangle"/> ++ <arg name="y" type="int" summary="y position of rectangle"/> ++ <arg name="width" type="int" summary="width of rectangle"/> ++ <arg name="height" type="int" summary="height of rectangle"/> ++ </request> ++ ++ <request name="deactivate_app" since="5"> ++ <description summary="de-activate/hide window identified by app_id"> ++ Ask the compositor to hide the toplevel window for window ++ management purposes. Depending on the window role, this request ++ will either display the previously active window (or the background ++ in case there's no previously active surface) or temporarily (or ++ until a 'activate_app' is called upon) hide the surface. ++ ++ All the surfaces are identifiable by using the app_id, and no actions ++ are taken in case the app_id is not/was not present. ++ ++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a ++ description of app_id. ++ </description> ++ <arg name="app_id" type="string"/> ++ </request> ++ ++ <request name="set_app_float" since="6"> ++ <description summary="set the window identified by app_id as float"> ++ Makes the application identified by app_id as floating. If the ++ application's window is already mapped, in a maximized, normal state, ++ it would transition to the float state. ++ ++ For applications that want to modify their own state, this request ++ must be done before the initial surface commit in order to take effect. ++ ++ If the application is already in floating state, this request wouldn't ++ do anything. ++ ++ There's no persistence of this request, once the application terminated ++ you'll to issue this request again for that particular app_id. ++ ++ The x, and y values would be initial position of the window where the ++ window surface will be placed. ++ ++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a ++ description of app_id. ++ </description> ++ <arg name="app_id" type="string"/> ++ <arg name="x" type="int" summary="x position"/> ++ <arg name="y" type="int" summary="y position"/> ++ </request> ++ ++ <request name="set_app_normal" since="6"> ++ <description summary="set the window identified by app_id as normally started"> ++ Returns the application identified by app_id as it was in the normal state. ++ This is useful to come back from other states to the maximized state, the ++ normal state applications are started. ++ </description> ++ <arg name="app_id" type="string"/> ++ </request> ++ ++ <request name="set_app_fullscreen" since="7"> ++ <description summary=""> ++ Makes the application identified by app_id as fullscreen. If the ++ application's window is already mapped, in a maximized, normal state, ++ it would transition to the fullscreen state. ++ ++ For applications that want to modify their own state, this request ++ must be done before the initial surface commit in order to take effect. ++ ++ If the application is already in fullscreen state, this request wouldn't ++ do anything. ++ ++ There's no persistence of this request, once the application terminated ++ you'll to issue this request again for that particular app_id. ++ ++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a ++ description of app_id. ++ </description> ++ <arg name="app_id" type="string"/> ++ </request> ++ ++ <request name="set_app_output" since="8"> ++ <description summary="Assign an application to a particular output"> ++ This would allow the compositor to place an application on a particular ++ output, if that output is indeed available. This can happen before ++ application is started which would make the application start on that ++ particular output. If the application is already started it would ++ move the application to that output. ++ ++ There's no persistence of this request, once the application terminated ++ you'll need to issue this request again for that particular app_id. ++ ++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a ++ description of app_id. ++ </description> ++ <arg name="app_id" type="string"/> ++ <arg name="output" type="object" interface="wl_output"/> ++ </request> ++ ++ <event name="app_on_output" since="8"> ++ <description summary="Event sent as a reponse to set_app_output"> ++ Clients can use this event to be notified when an application ++ wants to be displayed on a certain output. This event is sent in ++ response to the set_app_output request. ++ ++ See xdg_toplevel.set_app_id from the xdg-shell protocol for a ++ description of app_id. ++ </description> ++ <arg name="app_id" type="string"/> ++ <arg name="output_name" type="string"/> ++ </event> ++ </interface> ++ ++ <interface name="agl_shell_ext" version="1"> ++ <description summary="extended user interface for Automotive Grade Linux platform"> ++ This interface allows another client bind to the agl_shell interface, ++ while there's another shell client already present. ++ ++ The client should first bind to this interface and then inform the ++ compositor with the 'doas_shell_client' request and it wants to bind to ++ the agl_shell interface. The client is still expected, if using a new ++ version of the agl_shell interface, to wait for the 'bound_ok' and ++ 'bound_fail' events before issueing any other requests/events. ++ ++ Note that this interface has its limitations, and the compositor would ++ still refuse the act for 'set_panel' or 'set_background' requests ++ of the agl_shell interface if there's already a client that used them. ++ ++ Any other requests or events should be delievered and handled as it would ++ a client bound to the agl_shell interface. ++ </description> ++ ++ <enum name="doas_shell_client_status"> ++ <entry name="success" value="0"/> ++ <entry name="failed" value="1"/> ++ </enum> ++ ++ <request name="destroy" type="destructor"> ++ <description summary="destroys the factory object"> ++ Call the destructor once you're ready with agl_shell_ext interface. ++ This would reset the state and would make any requests made ++ on the agl_shell interface be terminated. The client would need ++ to bind again the agl_shell_ext and issue a 'doas_shell_client' ++ request. ++ </description> ++ </request> ++ ++ <request name="doas_shell_client"> ++ <description summary="Informs the compositor it wants to bind to the ++ agl_shell interface"> ++ Prior to binding to agl_shell interface, this request would inform ++ the compositor that it wants to gain access the agl_shell interface. ++ The client is expected to wait for 'doas_shell_client_done' event and ++ check for a successful status before going further with binding to ++ the agl_shell interface. ++ </description> ++ </request> ++ ++ <event name="doas_done"> ++ <description summary="event sent as a reply to doas_shell_client"> ++ The client should check the status event to verify that the ++ compositor was able to handle the request. ++ </description> ++ <arg name="status" type="uint" enum="doas_shell_client_status"/> ++ </event> + </interface> + </protocol> +diff --git a/ui/platform_window/agl/platform_window_agl.h b/ui/platform_window/agl/platform_window_agl.h +index cab1f42272772..b1a6150fff950 100644 +--- a/ui/platform_window/agl/platform_window_agl.h ++++ b/ui/platform_window/agl/platform_window_agl.h +@@ -30,6 +30,7 @@ class PlatformWindowAgl { + virtual void SetAglBackground() {} + virtual void SetAglPanel(uint32_t edge) {} + virtual bool IsSurfaceConfigured() { return false; } ++ virtual void SetupActivationArea(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {} + }; + + } // namespace ui +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0006-agl-Don-t-use-DRI-for-renesas.patch b/recipes-wam/cef/files/chromium/0006-agl-Don-t-use-DRI-for-renesas.patch new file mode 100644 index 00000000..1914661e --- /dev/null +++ b/recipes-wam/cef/files/chromium/0006-agl-Don-t-use-DRI-for-renesas.patch @@ -0,0 +1,72 @@ +From e7b779035f0d7ff1ba5bf59ea2f314f364493928 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Thu, 4 May 2023 10:42:06 +0200 +Subject: [PATCH 06/33] [agl] Don't use DRI for renesas + +This adds the use_dri flag that defauls to true and +can be disabled if we are building CEF using ozone + wayland + +Upstream-Status: Inappropriate, specific to the renesas boards supported +by AGL. +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + content/gpu/BUILD.gn | 4 ++-- + media/gpu/sandbox/BUILD.gn | 5 +++-- + media/media_options.gni | 3 +++ + 3 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/content/gpu/BUILD.gn b/content/gpu/BUILD.gn +index 93559f6092c7a..cef8415be7ab1 100644 +--- a/content/gpu/BUILD.gn ++++ b/content/gpu/BUILD.gn +@@ -139,8 +139,8 @@ target(link_target_type, "gpu_sources") { + } + + # Use DRI on desktop Linux builds. +- if (current_cpu != "s390x" && current_cpu != "ppc64" && is_linux && +- !is_castos) { ++ if (use_dri && current_cpu != "s390x" && current_cpu != "ppc64" && ++ is_linux && !is_castos) { + configs += [ "//build/config/linux/dri" ] + } + } +diff --git a/media/gpu/sandbox/BUILD.gn b/media/gpu/sandbox/BUILD.gn +index cfcb7fa80ef89..6ba37d06b29c8 100644 +--- a/media/gpu/sandbox/BUILD.gn ++++ b/media/gpu/sandbox/BUILD.gn +@@ -4,6 +4,7 @@ + + import("//build/config/chromeos/ui_mode.gni") + import("//media/gpu/args.gni") ++import("//media/media_options.gni") + + source_set("sandbox") { + sources = [] +@@ -30,8 +31,8 @@ source_set("sandbox") { + if (use_v4l2_codec) { + deps += [ "//media/gpu/v4l2" ] + } +- if (current_cpu != "s390x" && current_cpu != "ppc64" && is_linux && +- !is_castos) { ++ if (use_dri && (current_cpu != "s390x" && current_cpu != "ppc64" && is_linux && ++ !is_castos)) { + # For DRI_DRIVER_DIR. + configs += [ "//build/config/linux/dri" ] + } +diff --git a/media/media_options.gni b/media/media_options.gni +index 61d5046d0cb0e..4898c9034d448 100644 +--- a/media/media_options.gni ++++ b/media/media_options.gni +@@ -117,6 +117,9 @@ declare_args() { + # Enable inclusion of VVC/H.266 parser/demuxer, and also enable VVC/H.266 decoding + # with hardware acceleration provided by platform. Disabled by default for all builds. + enable_platform_vvc = false ++ ++ # used to disable dri on renesas boards ++ use_dri = true + } + + # Use another declare_args() to allow dependence on args defined above. +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0007-meta-browser-Remove-the-GN-settings-done-for-clang-t.patch b/recipes-wam/cef/files/chromium/0007-meta-browser-Remove-the-GN-settings-done-for-clang-t.patch new file mode 100644 index 00000000..75d37ab1 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0007-meta-browser-Remove-the-GN-settings-done-for-clang-t.patch @@ -0,0 +1,117 @@ +From 89705cfc3a4e677dd97db36c3dc9b0aa97515760 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Thu, 27 Apr 2023 16:16:28 +0200 +Subject: [PATCH 07/33] [meta-browser] Remove the GN settings done for clang + that conflict with OE + +clang cross compiler that is build with meta-clang has lot of these +settings built-in and specifying them here confuses the compiler + +--target option and -no-canonical-prefixes options result in clang + +finding the headers in target sysroot + +Upstream-Status: Inappropriate [OE-Specific] + +Signed-off-by: Khem Raj <raj.khem@gmail.com> +Rebased-by: Maksim Sisov <msisov@igalia.com> +Rebased-by: Randy MacLeod <randy.macleod@windriver.com> +Rebased-by: Roger Zanoni <rzanoni@igalia.com> +--- + build/config/compiler/BUILD.gn | 38 ---------------------------------- + 1 file changed, 38 deletions(-) + +diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn +index 06812fb9c2188..db763b998c4fb 100644 +--- a/build/config/compiler/BUILD.gn ++++ b/build/config/compiler/BUILD.gn +@@ -1112,11 +1112,6 @@ config("compiler_cpu_abi") { + ] + } + } else if (current_cpu == "arm") { +- if (is_clang && !is_android && !is_nacl && +- !(is_chromeos_lacros && is_chromeos_device)) { +- cflags += [ "--target=arm-linux-gnueabihf" ] +- ldflags += [ "--target=arm-linux-gnueabihf" ] +- } + if (!is_nacl) { + cflags += [ + "-march=$arm_arch", +@@ -1126,12 +1121,6 @@ config("compiler_cpu_abi") { + if (arm_tune != "") { + cflags += [ "-mtune=$arm_tune" ] + } +- } else if (current_cpu == "arm64") { +- if (is_clang && !is_android && !is_nacl && !is_fuchsia && +- !(is_chromeos_lacros && is_chromeos_device)) { +- cflags += [ "--target=aarch64-linux-gnu" ] +- ldflags += [ "--target=aarch64-linux-gnu" ] +- } + } else if (current_cpu == "mipsel" && !is_nacl) { + ldflags += [ "-Wl,--hash-style=sysv" ] + if (custom_toolchain == "") { +@@ -1139,9 +1128,6 @@ config("compiler_cpu_abi") { + if (is_android) { + cflags += [ "--target=mipsel-linux-android" ] + ldflags += [ "--target=mipsel-linux-android" ] +- } else { +- cflags += [ "--target=mipsel-linux-gnu" ] +- ldflags += [ "--target=mipsel-linux-gnu" ] + } + } else { + cflags += [ "-EL" ] +@@ -1221,8 +1207,6 @@ config("compiler_cpu_abi") { + ldflags += [ "-Wl,--hash-style=sysv" ] + if (custom_toolchain == "") { + if (is_clang) { +- cflags += [ "--target=mips-linux-gnu" ] +- ldflags += [ "--target=mips-linux-gnu" ] + } else { + cflags += [ "-EB" ] + ldflags += [ "-EB" ] +@@ -1270,9 +1254,6 @@ config("compiler_cpu_abi") { + if (is_android) { + cflags += [ "--target=mips64el-linux-android" ] + ldflags += [ "--target=mips64el-linux-android" ] +- } else { +- cflags += [ "--target=mips64el-linux-gnuabi64" ] +- ldflags += [ "--target=mips64el-linux-gnuabi64" ] + } + } else { + cflags += [ +@@ -1330,8 +1311,6 @@ config("compiler_cpu_abi") { + ldflags += [ "-Wl,--hash-style=sysv" ] + if (custom_toolchain == "") { + if (is_clang) { +- cflags += [ "--target=mips64-linux-gnuabi64" ] +- ldflags += [ "--target=mips64-linux-gnuabi64" ] + } else { + cflags += [ + "-EB", +@@ -1494,23 +1473,6 @@ config("compiler_deterministic") { + } + } + } +- +- # Tells the compiler not to use absolute paths when passing the default +- # paths to the tools it invokes. We don't want this because we don't +- # really need it and it can mess up the goma cache entries. +- if (is_clang && (!is_nacl || is_nacl_saigo)) { +- cflags += [ "-no-canonical-prefixes" ] +- +- # Same for links: Let the compiler driver invoke the linker +- # with a relative path and pass relative paths to built-in +- # libraries. Not needed on Windows because we call the linker +- # directly there, not through the compiler driver. +- # We don't link on goma, so this change is just for cleaner +- # internal linker invocations, for people who work on the build. +- if (!is_win) { +- ldflags += [ "-no-canonical-prefixes" ] +- } +- } + } + + config("clang_revision") { +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0008-meta-browser-Pass-no-static-libstdc-to-gen.py.patch b/recipes-wam/cef/files/chromium/0008-meta-browser-Pass-no-static-libstdc-to-gen.py.patch new file mode 100644 index 00000000..a31d4242 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0008-meta-browser-Pass-no-static-libstdc-to-gen.py.patch @@ -0,0 +1,31 @@ +From f4d754e203e4968f4c9f68f00321fa0f1c942139 Mon Sep 17 00:00:00 2001 +From: Maksim Sisov <msisov@igalia.com> +Date: Thu, 19 Dec 2019 15:47:53 +0200 +Subject: [PATCH 08/33] [meta-browser] Pass no-static-libstdc++ to gen.py + +Upstream-Status: Inappropriate + +GN requires libstdc++.a to be installed on host systems by default, +which is often not very common, for no particular reason. + +Signed-off-by: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com> +Signed-off-by: Maksim Sisov <msisov@igalia.com> +--- + tools/gn/bootstrap/bootstrap.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py +index caf736b28946d..c5d7c428ed68a 100755 +--- a/tools/gn/bootstrap/bootstrap.py ++++ b/tools/gn/bootstrap/bootstrap.py +@@ -113,6 +113,7 @@ def main(argv): + cmd = [ + sys.executable, + os.path.join(GN_ROOT, 'build', 'gen.py'), ++ '--no-static-libstdc++', + '--no-last-commit-position', + '--out-path=' + gn_build_dir, + ] +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0009-meta-browser-IWYU-Add-includes-for-size_t-and-int64_.patch b/recipes-wam/cef/files/chromium/0009-meta-browser-IWYU-Add-includes-for-size_t-and-int64_.patch new file mode 100644 index 00000000..8e46c2c5 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0009-meta-browser-IWYU-Add-includes-for-size_t-and-int64_.patch @@ -0,0 +1,42 @@ +From 585854fa48a040fe31caa42e675f78c783be0098 Mon Sep 17 00:00:00 2001 +From: Ivan Murashov <ivan.murashov@lge.com> +Date: Wed, 6 Sep 2023 19:40:47 +0000 +Subject: [PATCH 09/33] [meta-browser] IWYU: Add includes for size_t and + int64_t usage into sensor_reading.h + +Otherwise build fails when building with use_custom_libcxx=false. +The errors example: +services/device/public/cpp/generic_sensor/sensor_reading.h:17:40: +error: use of undeclared identifier 'int64_t' +services/device/public/cpp/generic_sensor/sensor_reading.h:35:5: +error: unknown type name 'int64_t' +services/device/public/cpp/generic_sensor/sensor_reading.h:58:20: +error: unknown type name 'size_t'; did you mean 'std::size_t'? + +Bug: 957519 +Change-Id: Iec9bb821eb6284cf38d93c1cec90846e2f615fab +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4838935 +Reviewed-by: Reilly Grant <reillyg@chromium.org> +Commit-Queue: Ivan Murashov <ivan.murashov@lge.com> +Cr-Commit-Position: refs/heads/main@{#1193203} +--- + services/device/public/cpp/generic_sensor/sensor_reading.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/services/device/public/cpp/generic_sensor/sensor_reading.h b/services/device/public/cpp/generic_sensor/sensor_reading.h +index 7df8278649a23..c653bec632cc6 100644 +--- a/services/device/public/cpp/generic_sensor/sensor_reading.h ++++ b/services/device/public/cpp/generic_sensor/sensor_reading.h +@@ -5,6 +5,9 @@ + #ifndef SERVICES_DEVICE_PUBLIC_CPP_GENERIC_SENSOR_SENSOR_READING_H_ + #define SERVICES_DEVICE_PUBLIC_CPP_GENERIC_SENSOR_SENSOR_READING_H_ + ++#include <stddef.h> ++#include <stdint.h> ++ + #include <type_traits> + + namespace device { +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0010-meta-browser-BUILD-do-not-specify-march-on-arm.patch b/recipes-wam/cef/files/chromium/0010-meta-browser-BUILD-do-not-specify-march-on-arm.patch new file mode 100644 index 00000000..5936248e --- /dev/null +++ b/recipes-wam/cef/files/chromium/0010-meta-browser-BUILD-do-not-specify-march-on-arm.patch @@ -0,0 +1,43 @@ +From 5d216a0f4d6312531bc03ce8c878dc251b67c589 Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Tue, 22 Jan 2019 00:17:41 -0800 +Subject: [PATCH 10/33] [meta-browser] BUILD: do not specify march on arm + +Do not try to set the guessed values for march/mtune/float-abi +OE config machinary has computed these values already and fed it +via compiler cmdline to chromium build + +I think upstream should check for the values on compiler cmdline +before overriding these + +Upstream-Status: Inappropriate [OE-Specific] + +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- + build/config/compiler/BUILD.gn | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn +index db763b998c4fb..6d87a2b03fa04 100644 +--- a/build/config/compiler/BUILD.gn ++++ b/build/config/compiler/BUILD.gn +@@ -1111,16 +1111,6 @@ config("compiler_cpu_abi") { + "-msse3", + ] + } +- } else if (current_cpu == "arm") { +- if (!is_nacl) { +- cflags += [ +- "-march=$arm_arch", +- "-mfloat-abi=$arm_float_abi", +- ] +- } +- if (arm_tune != "") { +- cflags += [ "-mtune=$arm_tune" ] +- } + } else if (current_cpu == "mipsel" && !is_nacl) { + ldflags += [ "-Wl,--hash-style=sysv" ] + if (custom_toolchain == "") { +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0011-meta-browser-Avoid-parenthesized-initialization-of-a.patch b/recipes-wam/cef/files/chromium/0011-meta-browser-Avoid-parenthesized-initialization-of-a.patch new file mode 100644 index 00000000..dbdda920 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0011-meta-browser-Avoid-parenthesized-initialization-of-a.patch @@ -0,0 +1,164 @@ +From 03e9492ef563af17682683b6db5761d1c2ece8cc Mon Sep 17 00:00:00 2001 +From: Max Ihlenfeldt <max@igalia.com> +Date: Thu, 3 Aug 2023 13:31:15 +0000 +Subject: [PATCH 11/33] [meta-browser] Avoid parenthesized initialization of + aggregates + +clang < 16 doesn't support C++20's "Parenthesized initialization of +aggregates" [1]. To fix build errors with older clang versions, we need +to either explicitly define a constructor that does the initialization, +or initialize the aggregate using curly braces. + +[1] https://clang.llvm.org/cxx_status.html + +Upstream-Status: Inappropriate [specific to older versions of clang] +Signed-off-by: Max Ihlenfeldt <max@igalia.com> +--- + .../browser/content_settings/one_time_permission_provider.h | 1 + + chrome/browser/ui/omnibox/chrome_omnibox_client.cc | 4 ++-- + chrome/test/chromedriver/chrome/client_hints.h | 1 + + .../display_embedder/skia_output_surface_impl_on_gpu.cc | 2 +- + net/dns/host_resolver_cache.cc | 2 +- + .../blink/renderer/modules/canvas/canvas2d/canvas_style.cc | 4 ++-- + .../blink/renderer/platform/fonts/palette_interpolation.cc | 2 +- + ui/base/wayland/color_manager_util.h | 5 +++++ + 8 files changed, 14 insertions(+), 7 deletions(-) + +diff --git a/chrome/browser/content_settings/one_time_permission_provider.h b/chrome/browser/content_settings/one_time_permission_provider.h +index 839bec7daff97..2a000003507cf 100644 +--- a/chrome/browser/content_settings/one_time_permission_provider.h ++++ b/chrome/browser/content_settings/one_time_permission_provider.h +@@ -92,6 +92,7 @@ class OneTimePermissionProvider + ContentSettingsType type; + ContentSettingsPattern primary_pattern; + ContentSettingsPattern secondary_pattern; ++ ContentSettingEntry(ContentSettingsType t, ContentSettingsPattern p, ContentSettingsPattern s) : type(t), primary_pattern(p), secondary_pattern(s) {} + }; + + void DeleteEntriesAndNotify( +diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc +index 7ee2e0645e6c8..e036eeea4a5f9 100644 +--- a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc ++++ b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc +@@ -474,10 +474,10 @@ void ChromeOmniboxClient::OnAutocompleteAccept( + alternative_nav_match); + + // Store the details necessary to open the omnibox match via browser commands. +- location_bar_->set_navigation_params(LocationBar::NavigationParams( ++ location_bar_->set_navigation_params(LocationBar::NavigationParams { + destination_url, disposition, transition, match_selection_timestamp, + destination_url_entered_without_scheme, +- destination_url_entered_with_http_scheme)); ++ destination_url_entered_with_http_scheme}); + + if (browser_) { + auto navigation = chrome::OpenCurrentURL(browser_); +diff --git a/chrome/test/chromedriver/chrome/client_hints.h b/chrome/test/chromedriver/chrome/client_hints.h +index 8c13bd3321c5e..42dc1acf75ec5 100644 +--- a/chrome/test/chromedriver/chrome/client_hints.h ++++ b/chrome/test/chromedriver/chrome/client_hints.h +@@ -19,6 +19,7 @@ struct BrandVersion { + // * "major version" for "brands", + // * "full version" for "fullVersionList". + std::string version; ++ BrandVersion(std::string b, std::string v) : brand(b), version(v) {} + }; + + // User-Agent Client Hints +diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +index 9e04843c454e3..e4981a96bbb06 100644 +--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc ++++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +@@ -1521,7 +1521,7 @@ void SkiaOutputSurfaceImplOnGpu::CopyOutputNV12( + + // Issue readbacks from the surfaces: + for (size_t i = 0; i < CopyOutputResult::kNV12MaxPlanes; ++i) { +- SkISize size(plane_surfaces[i]->width(), plane_surfaces[i]->height()); ++ SkISize size {plane_surfaces[i]->width(), plane_surfaces[i]->height()}; + SkImageInfo dst_info = SkImageInfo::Make( + size, (i == 0) ? kAlpha_8_SkColorType : kR8G8_unorm_SkColorType, + kUnpremul_SkAlphaType); +diff --git a/net/dns/host_resolver_cache.cc b/net/dns/host_resolver_cache.cc +index e54ed00c913ba..7d1165e7fcacf 100644 +--- a/net/dns/host_resolver_cache.cc ++++ b/net/dns/host_resolver_cache.cc +@@ -161,7 +161,7 @@ void HostResolverCache::Set( + + std::string domain_name = result->domain_name(); + entries_.emplace( +- Key(std::move(domain_name), network_anonymization_key), ++ Key {std::move(domain_name), network_anonymization_key}, + Entry(std::move(result), source, secure, staleness_generation_)); + + if (entries_.size() > max_entries_) { +diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc +index 883d769ca4b24..3dcd0d73468fc 100644 +--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc ++++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc +@@ -83,12 +83,12 @@ void CanvasStyle::ApplyToFlags(cc::PaintFlags& flags, + case kGradient: + GetCanvasGradient()->GetGradient()->ApplyToFlags(flags, SkMatrix::I(), + ImageDrawOptions()); +- flags.setColor(SkColor4f(0.0f, 0.0f, 0.0f, global_alpha)); ++ flags.setColor(SkColor4f {0.0f, 0.0f, 0.0f, global_alpha}); + break; + case kImagePattern: + GetCanvasPattern()->GetPattern()->ApplyToFlags( + flags, AffineTransformToSkMatrix(GetCanvasPattern()->GetTransform())); +- flags.setColor(SkColor4f(0.0f, 0.0f, 0.0f, global_alpha)); ++ flags.setColor(SkColor4f {0.0f, 0.0f, 0.0f, global_alpha}); + break; + default: + NOTREACHED(); +diff --git a/third_party/blink/renderer/platform/fonts/palette_interpolation.cc b/third_party/blink/renderer/platform/fonts/palette_interpolation.cc +index 1ce08e956a7aa..d6521525a52f6 100644 +--- a/third_party/blink/renderer/platform/fonts/palette_interpolation.cc ++++ b/third_party/blink/renderer/platform/fonts/palette_interpolation.cc +@@ -31,7 +31,7 @@ Vector<FontPalette::FontPaletteOverride> PaletteInterpolation::MixColorRecords( + color_interpolation_space, hue_interpolation_method, start_color, + end_color, percentage, alpha_multiplier); + +- FontPalette::FontPaletteOverride result_color_record(i, result_color); ++ FontPalette::FontPaletteOverride result_color_record {static_cast<int>(i), result_color}; + result_color_records.push_back(result_color_record); + } + return result_color_records; +diff --git a/ui/base/wayland/color_manager_util.h b/ui/base/wayland/color_manager_util.h +index fa1dd422c0e60..c54ace574e52e 100644 +--- a/ui/base/wayland/color_manager_util.h ++++ b/ui/base/wayland/color_manager_util.h +@@ -23,26 +23,31 @@ constexpr uint32_t kDefaultSinceVersion = 1; + struct TransferFnVersion { + skcms_TransferFunction transfer_fn; + uint32_t version; ++ TransferFnVersion(skcms_TransferFunction t, uint32_t v) : transfer_fn(t), version(v) {} + }; + + struct TransferVersion { + gfx::ColorSpace::TransferID transfer; + uint32_t version; ++ TransferVersion(gfx::ColorSpace::TransferID t, uint32_t v) : transfer(t), version(v) {} + }; + + struct PrimaryVersion { + gfx::ColorSpace::PrimaryID primary; + uint32_t version; ++ PrimaryVersion(gfx::ColorSpace::PrimaryID p, uint32_t v) : primary(p), version(v) {} + }; + + struct MatrixVersion { + gfx::ColorSpace::MatrixID matrix; + uint32_t version; ++ MatrixVersion(gfx::ColorSpace::MatrixID m, uint32_t v) : matrix(m), version(v) {} + }; + + struct RangeVersion { + gfx::ColorSpace::RangeID range; + uint32_t version; ++ RangeVersion(gfx::ColorSpace::RangeID r, uint32_t v) : range(r), version(v) {} + }; + + // A map from the zcr_color_manager_v1 chromaticity_names enum values +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0012-meta-browser-Fix-constexpr-variable-cannot-have-non-.patch b/recipes-wam/cef/files/chromium/0012-meta-browser-Fix-constexpr-variable-cannot-have-non-.patch new file mode 100644 index 00000000..3a91c1dd --- /dev/null +++ b/recipes-wam/cef/files/chromium/0012-meta-browser-Fix-constexpr-variable-cannot-have-non-.patch @@ -0,0 +1,78 @@ +From dcc972ec3451eaf88c2289a6f4852b24e901f26d Mon Sep 17 00:00:00 2001 +From: Max Ihlenfeldt <max@igalia.com> +Date: Thu, 31 Aug 2023 10:27:47 +0000 +Subject: [PATCH 12/33] [meta-browser] Fix "constexpr variable cannot have + non-literal type" errors + +Something about Chromium's `base::flat_map` / +`base::internal::flat_tree` isn't considered a literal type by older +clang versions, meaning they can't be used in constexpr expressions. We +need to change them to be const instead. + +Upstream-Status: Inappropriate [specific to older versions of clang] +Signed-off-by: Max Ihlenfeldt <max@igalia.com> +--- + ui/base/wayland/color_manager_util.h | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/ui/base/wayland/color_manager_util.h b/ui/base/wayland/color_manager_util.h +index c54ace574e52e..e25abe8e5d722 100644 +--- a/ui/base/wayland/color_manager_util.h ++++ b/ui/base/wayland/color_manager_util.h +@@ -53,7 +53,7 @@ struct RangeVersion { + // A map from the zcr_color_manager_v1 chromaticity_names enum values + // representing well-known chromaticities, to their equivalent PrimaryIDs. + // See components/exo/wayland/protocol/chrome-color-management.xml +-constexpr auto kChromaticityMap = base::MakeFixedFlatMap< ++const auto kChromaticityMap = base::MakeFixedFlatMap< + zcr_color_manager_v1_chromaticity_names, + PrimaryVersion>( + {{ZCR_COLOR_MANAGER_V1_CHROMATICITY_NAMES_BT601_525_LINE, +@@ -108,7 +108,7 @@ constexpr auto kChromaticityMap = base::MakeFixedFlatMap< + // A map from the zcr_color_manager_v1 eotf_names enum values + // representing well-known EOTFs, to their equivalent TransferIDs. + // See components/exo/wayland/protocol/chrome-color-management.xml +-constexpr auto kEotfMap = base::MakeFixedFlatMap< ++const auto kEotfMap = base::MakeFixedFlatMap< + zcr_color_manager_v1_eotf_names, + TransferVersion>({ + {ZCR_COLOR_MANAGER_V1_EOTF_NAMES_LINEAR, +@@ -176,7 +176,7 @@ constexpr auto kEotfMap = base::MakeFixedFlatMap< + // A map from the SDR zcr_color_manager_v1 eotf_names enum values + // representing well-known EOTFs, to their equivalent transfer functions. + // See components/exo/wayland/protocol/chrome-color-management.xml +-constexpr auto kTransferMap = ++const auto kTransferMap = + base::MakeFixedFlatMap<zcr_color_manager_v1_eotf_names, TransferFnVersion>({ + {ZCR_COLOR_MANAGER_V1_EOTF_NAMES_LINEAR, + TransferFnVersion(SkNamedTransferFn::kLinear, kDefaultSinceVersion)}, +@@ -196,7 +196,7 @@ constexpr auto kTransferMap = + // A map from the HDR zcr_color_manager_v1 eotf_names enum values + // representing well-known EOTFs, to their equivalent transfer functions. + // See components/exo/wayland/protocol/chrome-color-management.xml +-constexpr auto kHDRTransferMap = ++const auto kHDRTransferMap = + base::MakeFixedFlatMap<zcr_color_manager_v1_eotf_names, TransferFnVersion>( + {{ZCR_COLOR_MANAGER_V1_EOTF_NAMES_LINEAR, + TransferFnVersion(SkNamedTransferFn::kLinear, kDefaultSinceVersion)}, +@@ -214,7 +214,7 @@ constexpr auto kHDRTransferMap = + + // A map from zcr_color_manager_v1 matrix_names enum values to + // gfx::ColorSpace::MatrixIDs. +-constexpr auto kMatrixMap = ++const auto kMatrixMap = + base::MakeFixedFlatMap<zcr_color_manager_v1_matrix_names, MatrixVersion>( + {{ZCR_COLOR_MANAGER_V1_MATRIX_NAMES_RGB, + MatrixVersion(gfx::ColorSpace::MatrixID::RGB, kDefaultSinceVersion)}, +@@ -251,7 +251,7 @@ constexpr auto kMatrixMap = + + // A map from zcr_color_manager_v1 range_names enum values to + // gfx::ColorSpace::RangeIDs. +-constexpr auto kRangeMap = ++const auto kRangeMap = + base::MakeFixedFlatMap<zcr_color_manager_v1_range_names, RangeVersion>( + {{ZCR_COLOR_MANAGER_V1_RANGE_NAMES_LIMITED, + RangeVersion(gfx::ColorSpace::RangeID::LIMITED, +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0013-meta-browser-Add-missing-typename-s.patch b/recipes-wam/cef/files/chromium/0013-meta-browser-Add-missing-typename-s.patch new file mode 100644 index 00000000..8740b81a --- /dev/null +++ b/recipes-wam/cef/files/chromium/0013-meta-browser-Add-missing-typename-s.patch @@ -0,0 +1,105 @@ +From 210019ce23ea273a13c77fedb3e674a47c67214a Mon Sep 17 00:00:00 2001 +From: Max Ihlenfeldt <max@igalia.com> +Date: Mon, 12 Jun 2023 16:52:44 +0000 +Subject: [PATCH 13/33] [meta-browser] Add missing "typename"s + +This adds some `typename`s in locations where they are needed in older +versions of clang (probably < 16). + +Upstream-Status: Inappropriate [specific to older versions of clang] +Signed-off-by: Max Ihlenfeldt <max@igalia.com> +--- + .../download/bubble/download_bubble_update_service.cc | 6 +++--- + components/optimization_guide/core/tflite_model_executor.h | 2 +- + .../browser/web_ui_browser_interface_broker_registry.h | 6 +++--- + .../core/html/parser/html_document_parser_fastpath.cc | 2 +- + .../renderer/core/paint/object_paint_properties_sparse.h | 4 ++-- + 5 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/chrome/browser/download/bubble/download_bubble_update_service.cc b/chrome/browser/download/bubble/download_bubble_update_service.cc +index 93ec91e38b9b3..acd25f25d1579 100644 +--- a/chrome/browser/download/bubble/download_bubble_update_service.cc ++++ b/chrome/browser/download/bubble/download_bubble_update_service.cc +@@ -91,7 +91,7 @@ ItemSortKey GetSortKey(const Item& item) { + // Helper to get an iterator to the last element in the cache. The cache + // must not be empty. + template <typename Item> +-SortedItems<Item>::const_iterator GetLastIter(const SortedItems<Item>& cache) { ++typename SortedItems<Item>::const_iterator GetLastIter(const SortedItems<Item>& cache) { + CHECK(!cache.empty()); + auto it = cache.end(); + return std::prev(it); +@@ -967,9 +967,9 @@ bool DownloadBubbleUpdateService::CacheManager::RemoveItemFromCacheImpl( + } + + template <typename Id, typename Item> +-SortedItems<Item>::iterator ++typename SortedItems<Item>::iterator + DownloadBubbleUpdateService::CacheManager::RemoveItemFromCacheByIter( +- SortedItems<Item>::iterator iter, ++ typename SortedItems<Item>::iterator iter, + SortedItems<Item>& cache, + IterMap<Id, Item>& iter_map) { + CHECK(iter != cache.end()); +diff --git a/components/optimization_guide/core/tflite_model_executor.h b/components/optimization_guide/core/tflite_model_executor.h +index bbb5208aae904..027ae8e101634 100644 +--- a/components/optimization_guide/core/tflite_model_executor.h ++++ b/components/optimization_guide/core/tflite_model_executor.h +@@ -240,7 +240,7 @@ class TFLiteModelExecutor : public ModelExecutor<OutputType, InputType> { + void SendForBatchExecution( + BatchExecutionCallback callback_on_complete, + base::TimeTicks start_time, +- ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs) ++ typename ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs) + override { + DCHECK(execution_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +diff --git a/content/public/browser/web_ui_browser_interface_broker_registry.h b/content/public/browser/web_ui_browser_interface_broker_registry.h +index 0a419be66b325..7253c9680f722 100644 +--- a/content/public/browser/web_ui_browser_interface_broker_registry.h ++++ b/content/public/browser/web_ui_browser_interface_broker_registry.h +@@ -127,10 +127,10 @@ class CONTENT_EXPORT WebUIBrowserInterfaceBrokerRegistry { + // + // TODO(crbug.com/1407936): Point to WebUIJsBridge documentation. + template <typename ControllerType> +- JsBridgeTraits<ControllerType>::BinderInitializer& ForWebUIWithJsBridge() { ++ typename JsBridgeTraits<ControllerType>::BinderInitializer& ForWebUIWithJsBridge() { + using Traits = JsBridgeTraits<ControllerType>; +- using Interface = Traits::Interface; +- using JsBridgeBinderInitializer = Traits::BinderInitializer; ++ using Interface = typename Traits::Interface; ++ using JsBridgeBinderInitializer = typename Traits::BinderInitializer; + + // WebUIController::GetType() requires an instantiated WebUIController + // (because it's a virtual method and can't be static). Here we only have +diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser_fastpath.cc b/third_party/blink/renderer/core/html/parser/html_document_parser_fastpath.cc +index 4b5b6701a591b..59e1262a06e37 100644 +--- a/third_party/blink/renderer/core/html/parser/html_document_parser_fastpath.cc ++++ b/third_party/blink/renderer/core/html/parser/html_document_parser_fastpath.cc +@@ -169,7 +169,7 @@ class HTMLFastPathParser { + using Span = base::span<const Char>; + using USpan = base::span<const UChar>; + // 32 matches that used by HTMLToken::Attribute. +- typedef std::conditional<std::is_same_v<Char, UChar>, ++ typedef typename std::conditional<std::is_same_v<Char, UChar>, + UCharLiteralBuffer<32>, + LCharLiteralBuffer<32>>::type LiteralBufferType; + typedef UCharLiteralBuffer<32> UCharLiteralBufferType; +diff --git a/third_party/blink/renderer/core/paint/object_paint_properties_sparse.h b/third_party/blink/renderer/core/paint/object_paint_properties_sparse.h +index 9adc6dfac54db..be94e55af7cf6 100644 +--- a/third_party/blink/renderer/core/paint/object_paint_properties_sparse.h ++++ b/third_party/blink/renderer/core/paint/object_paint_properties_sparse.h +@@ -272,8 +272,8 @@ class CORE_EXPORT ObjectPaintPropertiesSparse : public ObjectPaintProperties { + NodeList& nodes, + NodeId node_id, + const ParentType& parent, +- NodeType::State&& state, +- const NodeType::AnimationState& animation_state = ++ typename NodeType::State&& state, ++ const typename NodeType::AnimationState& animation_state = + NodeType::AnimationState()) { + // First, check if we need to add a new node. + if (!nodes.HasField(node_id)) { +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0014-meta-browser-Avoid-std-ranges-find_if.patch b/recipes-wam/cef/files/chromium/0014-meta-browser-Avoid-std-ranges-find_if.patch new file mode 100644 index 00000000..2bd12fae --- /dev/null +++ b/recipes-wam/cef/files/chromium/0014-meta-browser-Avoid-std-ranges-find_if.patch @@ -0,0 +1,70 @@ +From a577e7a76e6002e50b5ab27514b7f49d4070499c Mon Sep 17 00:00:00 2001 +From: Max Ihlenfeldt <max@igalia.com> +Date: Wed, 30 Aug 2023 16:06:19 +0000 +Subject: [PATCH 14/33] [meta-browser] Avoid std::ranges::find_if() + +std::ranges::find_if() was introduced in C++20, and older versions of +clang don't support it. We can instead use Chromium's `base::ranges` +library, which is supported. + +Upstream-Status: Inappropriate [specific to older versions of clang] +Signed-off-by: Max Ihlenfeldt <max@igalia.com> +--- + .../password_manager/core/browser/ui/passwords_grouper.cc | 3 ++- + components/webauthn/core/browser/passkey_sync_bridge.cc | 5 +++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/components/password_manager/core/browser/ui/passwords_grouper.cc b/components/password_manager/core/browser/ui/passwords_grouper.cc +index 1b016e0eb9561..d259c6accf246 100644 +--- a/components/password_manager/core/browser/ui/passwords_grouper.cc ++++ b/components/password_manager/core/browser/ui/passwords_grouper.cc +@@ -8,6 +8,7 @@ + #include "base/containers/flat_set.h" + #include "base/strings/escape.h" + #include "base/strings/string_util.h" ++#include "base/ranges/algorithm.h" + #include "components/password_manager/core/browser/affiliation/affiliation_service.h" + #include "components/password_manager/core/browser/affiliation/affiliation_utils.h" + #include "components/password_manager/core/browser/passkey_credential.h" +@@ -277,7 +278,7 @@ absl::optional<PasskeyCredential> PasswordsGrouper::GetPasskeyFor( + const std::vector<PasskeyCredential>& passkeys = + map_group_id_to_credentials_[group_id_iterator->second].passkeys; + const auto passkey_it = +- std::ranges::find_if(passkeys, [&credential](const auto& passkey) { ++ base::ranges::find_if(passkeys, [&credential](const auto& passkey) { + return credential.passkey_credential_id == passkey.credential_id(); + }); + if (passkey_it == passkeys.end()) { +diff --git a/components/webauthn/core/browser/passkey_sync_bridge.cc b/components/webauthn/core/browser/passkey_sync_bridge.cc +index 93129fed756aa..794c696fcff04 100644 +--- a/components/webauthn/core/browser/passkey_sync_bridge.cc ++++ b/components/webauthn/core/browser/passkey_sync_bridge.cc +@@ -16,6 +16,7 @@ + #include "base/containers/span.h" + #include "base/feature_list.h" + #include "base/functional/callback_helpers.h" ++#include "base/ranges/algorithm.h" + #include "base/strings/string_number_conversions.h" + #include "base/trace_event/trace_event.h" + #include "components/sync/base/features.h" +@@ -258,7 +259,7 @@ PasskeySyncBridge::GetPasskeysForRelyingPartyId( + bool PasskeySyncBridge::DeletePasskey(const std::string& credential_id) { + // Find the credential with the given |credential_id|. + const auto passkey_it = +- std::ranges::find_if(data_, [&credential_id](const auto& passkey) { ++ base::ranges::find_if(data_, [&credential_id](const auto& passkey) { + return passkey.second.credential_id() == credential_id; + }); + if (passkey_it == data_.end()) { +@@ -309,7 +310,7 @@ bool PasskeySyncBridge::UpdatePasskey(const std::string& credential_id, + PasskeyChange change) { + // Find the credential with the given |credential_id|. + const auto passkey_it = +- std::ranges::find_if(data_, [&credential_id](const auto& passkey) { ++ base::ranges::find_if(data_, [&credential_id](const auto& passkey) { + return passkey.second.credential_id() == credential_id; + }); + if (passkey_it == data_.end()) { +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0015-meta-browser-Avoid-capturing-structured-bindings.patch b/recipes-wam/cef/files/chromium/0015-meta-browser-Avoid-capturing-structured-bindings.patch new file mode 100644 index 00000000..7b612b84 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0015-meta-browser-Avoid-capturing-structured-bindings.patch @@ -0,0 +1,56 @@ +From a1c05a94dc5b999bf22f1beedf3e3a9468775775 Mon Sep 17 00:00:00 2001 +From: Max Ihlenfeldt <max@igalia.com> +Date: Tue, 13 Jun 2023 15:48:12 +0000 +Subject: [PATCH 15/33] [meta-browser] Avoid capturing structured bindings + +Similar to https://crrev.com/c/4526976, this patch removes some uses of +structured bindings that lead to compile errors when using older +versions of clang (observed with clang 15). + +Upstream-Status: Inappropriate [specific to older versions of clang] +Signed-off-by: Max Ihlenfeldt <max@igalia.com> +--- + .../service_worker/service_worker_context_wrapper.cc | 3 ++- + media/base/cdm_promise_adapter.cc | 8 ++++---- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc +index 3267cdb340819..de88ef7e565cb 100644 +--- a/content/browser/service_worker/service_worker_context_wrapper.cc ++++ b/content/browser/service_worker/service_worker_context_wrapper.cc +@@ -1412,9 +1412,10 @@ void ServiceWorkerContextWrapper::MaybeProcessPendingWarmUpRequest() { + auto [document_url, key, callback] = std::move(*request); + + DCHECK(document_url.is_valid()); ++ auto document_url_spec = document_url.spec(); + TRACE_EVENT1("ServiceWorker", + "ServiceWorkerContextWrapper::MaybeProcessPendingWarmUpRequest", +- "document_url", document_url.spec()); ++ "document_url", document_url_spec); + + context_core_->registry()->FindRegistrationForClientUrl( + ServiceWorkerRegistry::Purpose::kNotForNavigation, +diff --git a/media/base/cdm_promise_adapter.cc b/media/base/cdm_promise_adapter.cc +index f013809a62e25..144809b9696c3 100644 +--- a/media/base/cdm_promise_adapter.cc ++++ b/media/base/cdm_promise_adapter.cc +@@ -94,12 +94,12 @@ void CdmPromiseAdapter::RejectPromise(uint32_t promise_id, + void CdmPromiseAdapter::Clear(ClearReason reason) { + // Reject all outstanding promises. + DCHECK(thread_checker_.CalledOnValidThread()); +- for (auto& [promise_id, promise] : promises_) { ++ for (auto& promise : promises_) { + TRACE_EVENT_NESTABLE_ASYNC_END1( +- "media", "CdmPromise", TRACE_ID_WITH_SCOPE("CdmPromise", promise_id), ++ "media", "CdmPromise", TRACE_ID_WITH_SCOPE("CdmPromise", promise.first), + "status", "cleared"); +- promise->reject(CdmPromise::Exception::INVALID_STATE_ERROR, +- ToSystemCode(reason), "Operation aborted."); ++ promise.second->reject(CdmPromise::Exception::INVALID_STATE_ERROR, ++ ToSystemCode(reason), "Operation aborted."); + } + promises_.clear(); + } +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0016-meta-browser-Delete-compiler-options-not-available-i.patch b/recipes-wam/cef/files/chromium/0016-meta-browser-Delete-compiler-options-not-available-i.patch new file mode 100644 index 00000000..0956f5f3 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0016-meta-browser-Delete-compiler-options-not-available-i.patch @@ -0,0 +1,32 @@ +From 267609878c7f7472990ee5b480a9ab1c54dad8b2 Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Wed, 4 Dec 2019 19:06:54 -0800 +Subject: [PATCH 16/33] [meta-browser] Delete compiler options not available in + release versions of clang _yet_ + +Upstream-Status: Inappropriate [ clang/master already supports them ] +Signed-off-by: Khem Raj <raj.khem@gmail.com> +Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com> +--- + build/config/compiler/BUILD.gn | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn +index 6d87a2b03fa04..5762f0b4e6b0a 100644 +--- a/build/config/compiler/BUILD.gn ++++ b/build/config/compiler/BUILD.gn +@@ -1725,6 +1725,11 @@ config("default_warnings") { + cflags += [ + "-Wenum-compare-conditional", + ++ # Disable unknown warnings, since system clang may not have ++ # backported newer warning yet unlike internal clang that ++ # chromium uses. ++ "-Wno-unknown-warning-option", ++ + # Ignore warnings about MSVC optimization pragmas. + # TODO(thakis): Only for no_chromium_code? http://crbug.com/912662 + "-Wno-ignored-pragma-optimize", +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0017-meta-browser-Don-t-pass-disable-auto-upgrade-debug-i.patch b/recipes-wam/cef/files/chromium/0017-meta-browser-Don-t-pass-disable-auto-upgrade-debug-i.patch new file mode 100644 index 00000000..48f722e8 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0017-meta-browser-Don-t-pass-disable-auto-upgrade-debug-i.patch @@ -0,0 +1,39 @@ +From a8243956b0fd410bf16143b3e781144ad8964244 Mon Sep 17 00:00:00 2001 +From: Max Ihlenfeldt <max@igalia.com> +Date: Tue, 13 Jun 2023 14:36:23 +0000 +Subject: [PATCH 17/33] [meta-browser] Don't pass + disable-auto-upgrade-debug-info to linker + +The version of aarch64-oe-linux-ld.lld we use on dunfell, kirkstone, and +mickledore doesn't support this flag. Thus, we mustn't pass it if we +want to avoid an "Unknown command line argument" linker error that stops +the build. + +Upstream-Status: Inappropriate +Signed-off-by: Max Ihlenfeldt <max@igalia.com> +--- + build/config/compiler/BUILD.gn | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn +index 5762f0b4e6b0a..c73b7ca6325d8 100644 +--- a/build/config/compiler/BUILD.gn ++++ b/build/config/compiler/BUILD.gn +@@ -767,14 +767,6 @@ config("compiler") { + } + + ldflags += [ "-Wl,-mllvm,-import-instr-limit=$import_instr_limit" ] +- +- if (!is_chromeos) { +- # TODO(https://crbug.com/972449): turn on for ChromeOS when that +- # toolchain has this flag. +- # We only use one version of LLVM within a build so there's no need to +- # upgrade debug info, which can be expensive since it runs the verifier. +- ldflags += [ "-Wl,-mllvm,-disable-auto-upgrade-debug-info" ] +- } + } + + # TODO(https://crbug.com/1211155): investigate why this isn't effective on +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0018-meta-browser-Fix-undefined-symbol-PaintOpWriter-Seri.patch b/recipes-wam/cef/files/chromium/0018-meta-browser-Fix-undefined-symbol-PaintOpWriter-Seri.patch new file mode 100644 index 00000000..2c953d3b --- /dev/null +++ b/recipes-wam/cef/files/chromium/0018-meta-browser-Fix-undefined-symbol-PaintOpWriter-Seri.patch @@ -0,0 +1,49 @@ +From 1b8ee706e8bb16a9b6c59c832d33b56915d1f410 Mon Sep 17 00:00:00 2001 +From: Max Ihlenfeldt <max@igalia.com> +Date: Tue, 5 Sep 2023 09:51:38 +0000 +Subject: [PATCH 18/33] [meta-browser] Fix "undefined symbol: + PaintOpWriter::SerializedSize<unsigned long>()" + +For some reason, clang 14 (currently used on dunfell and kirkstone) +seems to fail to correctly generate a needed instantiation of +`cc::PaintOpWriter::SerializedSize<T>()`, and thus the final linking +step fails with an "undefined symbol" error. + +We can fix this by explicitly providing a specialization, which does the +same thing as the generic implementation. + +Upstream-Status: Inappropriate [specific to older versions of clang] +Signed-off-by: Max Ihlenfeldt <max@igalia.com> +--- + cc/paint/paint_op_writer.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/cc/paint/paint_op_writer.h b/cc/paint/paint_op_writer.h +index 70153c0aa64ac..f47eb934c1eb1 100644 +--- a/cc/paint/paint_op_writer.h ++++ b/cc/paint/paint_op_writer.h +@@ -122,6 +122,9 @@ class CC_PAINT_EXPORT PaintOpWriter { + static size_t SerializedSize(const PaintRecord& record); + static size_t SerializedSize(const SkHighContrastConfig& config); + ++ template<> ++ constexpr size_t SerializedSize<size_t>(); ++ + // Serialization of raw/smart pointers is not supported by default. + template <typename T> + static inline size_t SerializedSize(const T* p); +@@ -385,6 +388,11 @@ constexpr size_t PaintOpWriter::SerializedSize<SkGainmapInfo>() { + SerializedSizeSimple<uint32_t>(); // fBaseImageType + } + ++template<> ++constexpr size_t PaintOpWriter::SerializedSize<size_t>() { ++ return SerializedSizeSimple<size_t>(); ++} ++ + template <typename T> + constexpr size_t PaintOpWriter::SerializedSize() { + static_assert(std::is_arithmetic_v<T> || std::is_enum_v<T>); +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0019-upstream-Initialize-ServerCvc-with-designated-initia.patch b/recipes-wam/cef/files/chromium/0019-upstream-Initialize-ServerCvc-with-designated-initia.patch new file mode 100644 index 00000000..aba25502 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0019-upstream-Initialize-ServerCvc-with-designated-initia.patch @@ -0,0 +1,45 @@ +From 41653aae0a0de782bcfb8396a01aa1d3c98d3149 Mon Sep 17 00:00:00 2001 +From: Chisoon Jeong <chisoon.jeong@lge.com> +Date: Tue, 12 Sep 2023 08:35:43 +0000 +Subject: [PATCH 19/33] [upstream] Initialize ServerCvc with designated + initializers. + +Replace ServerCvc initialization using aggregates from a parenthesized +list of values, which is not a c++20 feature allowed for Chromium at +the moment, with designated initializers. + +Change-Id: Ifdeb78d0ebc804016c655683ad1369dd543d4204 +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4855865 +Reviewed-by: Florian Leimgruber <fleimgruber@google.com> +Reviewed-by: Dominic Battre <battre@chromium.org> +Commit-Queue: Dominic Battre <battre@chromium.org> +Cr-Commit-Position: refs/heads/main@{#1195267} +--- + .../core/browser/webdata/autofill_sync_bridge_util.cc | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/components/autofill/core/browser/webdata/autofill_sync_bridge_util.cc b/components/autofill/core/browser/webdata/autofill_sync_bridge_util.cc +index 634443fb4fe22..f67b90114f762 100644 +--- a/components/autofill/core/browser/webdata/autofill_sync_bridge_util.cc ++++ b/components/autofill/core/browser/webdata/autofill_sync_bridge_util.cc +@@ -553,11 +553,13 @@ ServerCvc AutofillWalletCvcStructDataFromWalletCredentialSpecifics( + base::StringToInt64(wallet_credential_specifics.instrument_id(), + &instrument_id); + +- return ServerCvc( +- instrument_id, base::UTF8ToUTF16(wallet_credential_specifics.cvc()), +- base::Time::UnixEpoch() + ++ return ServerCvc{ ++ .instrument_id = instrument_id, ++ .cvc = base::UTF8ToUTF16(wallet_credential_specifics.cvc()), ++ .last_updated_timestamp = ++ base::Time::UnixEpoch() + + base::Milliseconds(wallet_credential_specifics +- .last_updated_time_unix_epoch_millis())); ++ .last_updated_time_unix_epoch_millis())}; + } + + VirtualCardUsageData VirtualCardUsageDataFromUsageSpecifics( +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0020-M118-fix-Don-t-look-for-depot_tools-in-chrommium-s-t.patch b/recipes-wam/cef/files/chromium/0020-M118-fix-Don-t-look-for-depot_tools-in-chrommium-s-t.patch new file mode 100644 index 00000000..a8c01ab0 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0020-M118-fix-Don-t-look-for-depot_tools-in-chrommium-s-t.patch @@ -0,0 +1,37 @@ +From 814421a53454a9d35cd9d0799f68eaae8b7cf440 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Fri, 7 Apr 2023 16:28:51 +0200 +Subject: [PATCH 20/33] [M118-fix] Don't look for depot_tools in chrommium's + third_party folder + +This caused an issue at the configure step before we starte using +tarballs, we need to check if it still needed. + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + build/find_depot_tools.py | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/build/find_depot_tools.py b/build/find_depot_tools.py +index f891a414837a5..592bba699c00d 100755 +--- a/build/find_depot_tools.py ++++ b/build/find_depot_tools.py +@@ -27,14 +27,6 @@ def IsRealDepotTools(path): + + def add_depot_tools_to_path(): + """Search for depot_tools and add it to sys.path.""" +- # First, check if we have a DEPS'd in "depot_tools". +- deps_depot_tools = os.path.join(SRC, 'third_party', 'depot_tools') +- if IsRealDepotTools(deps_depot_tools): +- # Put the pinned version at the start of the sys.path, in case there +- # are other non-pinned versions already on the sys.path. +- sys.path.insert(0, deps_depot_tools) +- return deps_depot_tools +- + # Then look if depot_tools is already in PYTHONPATH. + for i in sys.path: + if i.rstrip(os.sep).endswith('depot_tools') and IsRealDepotTools(i): +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0021-M118-fix-Add-multiple-missing-includes.patch b/recipes-wam/cef/files/chromium/0021-M118-fix-Add-multiple-missing-includes.patch new file mode 100644 index 00000000..df307082 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0021-M118-fix-Add-multiple-missing-includes.patch @@ -0,0 +1,69 @@ +From 99b897cb41f70222477ed55128b38ea78edc78ff Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Tue, 31 Oct 2023 10:29:32 -0300 +Subject: [PATCH 21/33] [M118-fix] Add multiple missing includes + +Fix build issues related to missing includes. + +Upstream-Status: Apparently the issue only happens on older versions of +clang, but it's worth checking if it's applicable. +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + chrome/browser/ui/views/dark_mode_manager_linux.h | 1 + + net/cert/pki/general_names.h | 1 + + net/filter/zstd_source_stream.cc | 1 + + ui/events/gesture_detection/motion_event_generic.h | 2 ++ + 4 files changed, 5 insertions(+) + +diff --git a/chrome/browser/ui/views/dark_mode_manager_linux.h b/chrome/browser/ui/views/dark_mode_manager_linux.h +index f9bcd034d141d..e98db21ef1767 100644 +--- a/chrome/browser/ui/views/dark_mode_manager_linux.h ++++ b/chrome/browser/ui/views/dark_mode_manager_linux.h +@@ -6,6 +6,7 @@ + #define CHROME_BROWSER_UI_VIEWS_DARK_MODE_MANAGER_LINUX_H_ + + #include <string> ++#include <vector> + + #include "base/gtest_prod_util.h" + #include "base/memory/scoped_refptr.h" +diff --git a/net/cert/pki/general_names.h b/net/cert/pki/general_names.h +index e35e410a2fba7..7704837970178 100644 +--- a/net/cert/pki/general_names.h ++++ b/net/cert/pki/general_names.h +@@ -6,6 +6,7 @@ + #define NET_CERT_PKI_GENERAL_NAMES_H_ + + #include <memory> ++#include <string_view> + #include <vector> + + #include "net/base/net_export.h" +diff --git a/net/filter/zstd_source_stream.cc b/net/filter/zstd_source_stream.cc +index bd337d14366bb..551729ac542b7 100644 +--- a/net/filter/zstd_source_stream.cc ++++ b/net/filter/zstd_source_stream.cc +@@ -5,6 +5,7 @@ + #include "net/filter/zstd_source_stream.h" + + #include <algorithm> ++#include <unordered_map> + #include <utility> + + #define ZSTD_STATIC_LINKING_ONLY +diff --git a/ui/events/gesture_detection/motion_event_generic.h b/ui/events/gesture_detection/motion_event_generic.h +index 5460f7f8adf46..e508335d47ae9 100644 +--- a/ui/events/gesture_detection/motion_event_generic.h ++++ b/ui/events/gesture_detection/motion_event_generic.h +@@ -5,6 +5,8 @@ + #ifndef UI_EVENTS_GESTURE_DETECTION_MOTION_EVENT_GENERIC_H_ + #define UI_EVENTS_GESTURE_DETECTION_MOTION_EVENT_GENERIC_H_ + ++#include <vector> ++ + #include <stddef.h> + #include <stdint.h> + +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0022-M118-fix-Fix-aggregate-initialization-in-trace_log.patch b/recipes-wam/cef/files/chromium/0022-M118-fix-Fix-aggregate-initialization-in-trace_log.patch new file mode 100644 index 00000000..39e5c605 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0022-M118-fix-Fix-aggregate-initialization-in-trace_log.patch @@ -0,0 +1,34 @@ +From a46e381a9007ab552d4551711611cd9d231a9f17 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Wed, 25 Oct 2023 15:59:23 -0300 +Subject: [PATCH 22/33] [M118-fix] Fix aggregate initialization in trace_log + +clang 14 doesn't parenthesized initialization of aggregates, so we are +explicitly defining the needed constructor. + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + base/trace_event/trace_log.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/base/trace_event/trace_log.h b/base/trace_event/trace_log.h +index 2778526e87b78..3b7e0f0306cf5 100644 +--- a/base/trace_event/trace_log.h ++++ b/base/trace_event/trace_log.h +@@ -420,6 +420,12 @@ class BASE_EXPORT TraceLog : + + #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) + struct TrackEventSession { ++ TrackEventSession(uint32_t internal_instance_index, ++ perfetto::DataSourceConfig config, ++ perfetto::BackendType backend_type = perfetto::kUnspecifiedBackend) ++ : internal_instance_index{internal_instance_index} ++ , config{config} ++ , backend_type{backend_type} {} + uint32_t internal_instance_index; + perfetto::DataSourceConfig config; + perfetto::BackendType backend_type = perfetto::kUnspecifiedBackend; +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0023-M118-fix-Add-missing-typename-keyword-in-multiple-st.patch b/recipes-wam/cef/files/chromium/0023-M118-fix-Add-missing-typename-keyword-in-multiple-st.patch new file mode 100644 index 00000000..ea0b2c59 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0023-M118-fix-Add-missing-typename-keyword-in-multiple-st.patch @@ -0,0 +1,140 @@ +From a1077aa6d029f729143727ab8d25f85121f871a3 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Thu, 26 Oct 2023 07:43:26 -0300 +Subject: [PATCH 23/33] [M118-fix] Add missing 'typename' keyword in multiple + statements + +Add the typename keywork where it's needed as this causes build issues +in clang 14. + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + .../optimization_guide/core/tflite_model_executor.h | 8 ++++---- + components/supervised_user/core/browser/proto_fetcher.cc | 6 +++--- + components/supervised_user/core/browser/proto_fetcher.h | 4 ++-- + ui/base/interaction/interactive_test_internal.h | 6 +++--- + 4 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/components/optimization_guide/core/tflite_model_executor.h b/components/optimization_guide/core/tflite_model_executor.h +index 027ae8e101634..a256a85322e54 100644 +--- a/components/optimization_guide/core/tflite_model_executor.h ++++ b/components/optimization_guide/core/tflite_model_executor.h +@@ -262,7 +262,7 @@ class TFLiteModelExecutor : public ModelExecutor<OutputType, InputType> { + // Starts the synchronous execution of the model. Returns model outputs. + // Model needs to be loaded. Synchronous calls do not load or unload model. + std::vector<absl::optional<OutputType>> SendForBatchExecutionSync( +- ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs) ++ typename ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs) + override { + DCHECK(execution_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +@@ -417,7 +417,7 @@ class TFLiteModelExecutor : public ModelExecutor<OutputType, InputType> { + // executes it on the model execution thread. + void LoadModelFileAndBatchExecute( + BatchExecutionCallback callback_on_complete, +- ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs) { ++ typename ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs) { + DCHECK(execution_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + +@@ -434,7 +434,7 @@ class TFLiteModelExecutor : public ModelExecutor<OutputType, InputType> { + + // Batch executes the loaded model for inputs. + void BatchExecuteLoadedModel( +- ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs, ++ typename ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs, + std::vector<absl::optional<OutputType>>* outputs) { + DCHECK(execution_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +@@ -494,7 +494,7 @@ class TFLiteModelExecutor : public ModelExecutor<OutputType, InputType> { + // Unloads the model if needed. + void BatchExecuteLoadedModelAndRunCallback( + BatchExecutionCallback callback_on_complete, +- ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs, ++ typename ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs, + ExecutionStatus execution_status) { + DCHECK(execution_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +diff --git a/components/supervised_user/core/browser/proto_fetcher.cc b/components/supervised_user/core/browser/proto_fetcher.cc +index 9c8e7b5cb88f4..92a614d75b579 100644 +--- a/components/supervised_user/core/browser/proto_fetcher.cc ++++ b/components/supervised_user/core/browser/proto_fetcher.cc +@@ -399,7 +399,7 @@ class RetryingFetcherImpl final : public DeferredFetcherImpl<Response> { + RetryingFetcherImpl(const RetryingFetcherImpl&) = delete; + RetryingFetcherImpl& operator=(const RetryingFetcherImpl&) = delete; + +- void Start(ProtoFetcher<Response>::Callback callback) override { ++ void Start(typename ProtoFetcher<Response>::Callback callback) override { + callback_ = std::move(callback); + Retry(); + } +@@ -435,7 +435,7 @@ class RetryingFetcherImpl final : public DeferredFetcherImpl<Response> { + } + + // Client callback. +- ProtoFetcher<Response>::Callback callback_; ++ typename ProtoFetcher<Response>::Callback callback_; + + // Retry controls. + base::OneShotTimer timer_; +@@ -578,7 +578,7 @@ ParallelFetchManager<Request, Response>::ParallelFetchManager( + template <typename Request, typename Response> + void ParallelFetchManager<Request, Response>::Fetch( + const Request& request, +- Fetcher::Callback callback) { ++ typename Fetcher::Callback callback) { + CHECK(callback) << "Use base::DoNothing() instead of empty callback."; + KeyType key = requests_in_flight_.Add(MakeFetcher(request)); + requests_in_flight_.Lookup(key)->Start( +diff --git a/components/supervised_user/core/browser/proto_fetcher.h b/components/supervised_user/core/browser/proto_fetcher.h +index 8266c99d78a7a..9c41978aea68e 100644 +--- a/components/supervised_user/core/browser/proto_fetcher.h ++++ b/components/supervised_user/core/browser/proto_fetcher.h +@@ -165,10 +165,10 @@ class ParallelFetchManager { + + // Starts the fetch. Underlying fetcher is stored internally, and will be + // cleaned up after finish or when this manager is destroyed. +- void Fetch(const Request& request, Fetcher::Callback callback); ++ void Fetch(const Request& request, typename Fetcher::Callback callback); + + private: +- using KeyType = base::IDMap<std::unique_ptr<Fetcher>>::KeyType; ++ using KeyType = typename base::IDMap<std::unique_ptr<Fetcher>>::KeyType; + + // Remove fetcher under key from requests_in_flight_. + void Remove(KeyType key); +diff --git a/ui/base/interaction/interactive_test_internal.h b/ui/base/interaction/interactive_test_internal.h +index 080152fa265cd..a3c9b22f79487 100644 +--- a/ui/base/interaction/interactive_test_internal.h ++++ b/ui/base/interaction/interactive_test_internal.h +@@ -108,7 +108,7 @@ class InteractiveTestPrivate { + + // Adds `state_observer` and associates it with an element with identifier + // `id` and context `context`. +- template <typename Observer, typename V = Observer::ValueType> ++ template <typename Observer, typename V = typename Observer::ValueType> + void AddStateObserver(ElementIdentifier id, + ElementContext context, + std::unique_ptr<Observer> state_observer); +@@ -457,7 +457,7 @@ struct ArgsExtractor<R(Args...)> { + }; + + template <typename F> +-using ReturnTypeOf = MaybeBindTypeHelper<F>::ReturnType; ++using ReturnTypeOf = typename MaybeBindTypeHelper<F>::ReturnType; + + template <size_t N, typename F> + using NthArgumentOf = std::tuple_element_t< +@@ -556,7 +556,7 @@ struct MatcherTypeHelper<const char16_t[]> { + }; + + template <typename T> +-using MatcherTypeFor = MatcherTypeHelper<std::remove_cvref_t<T>>::ActualType; ++using MatcherTypeFor = typename MatcherTypeHelper<std::remove_cvref_t<T>>::ActualType; + + template <typename T> + class IsMatcherHelper { +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0024-M118-fix-Fix-comparison-in-HostResolverCache.patch b/recipes-wam/cef/files/chromium/0024-M118-fix-Fix-comparison-in-HostResolverCache.patch new file mode 100644 index 00000000..ab487339 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0024-M118-fix-Fix-comparison-in-HostResolverCache.patch @@ -0,0 +1,34 @@ +From 590fdfc0339a2d82f30927b7c4e35b5e24d2dcc8 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 30 Oct 2023 08:14:34 -0300 +Subject: [PATCH 24/33] [M118-fix] Fix comparison in HostResolverCache + +Fixes the string_view/basic_strinc comparison: + +error: invalid operands to binary expression +('tuple<...basic_string_view<char> &, ...>' and 'tuple<const std::basic_string<char> &, ...') + return std::tie(lhs.domain_name, *lhs.network_anonymization_key) < + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + net/dns/host_resolver_cache.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/dns/host_resolver_cache.h b/net/dns/host_resolver_cache.h +index 934e0682c9864..2bb147de0ff19 100644 +--- a/net/dns/host_resolver_cache.h ++++ b/net/dns/host_resolver_cache.h +@@ -120,7 +120,7 @@ class NET_EXPORT HostResolverCache final { + struct Key { + ~Key(); + +- std::string domain_name; ++ base::StringPiece domain_name; + NetworkAnonymizationKey network_anonymization_key; + }; + +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0025-M118-fix-Avoid-using-std-ranges-any_of-find_if-none_.patch b/recipes-wam/cef/files/chromium/0025-M118-fix-Avoid-using-std-ranges-any_of-find_if-none_.patch new file mode 100644 index 00000000..fff1423e --- /dev/null +++ b/recipes-wam/cef/files/chromium/0025-M118-fix-Avoid-using-std-ranges-any_of-find_if-none_.patch @@ -0,0 +1,92 @@ +From ded11a971e690a00075c4f337fa09469b69b69a5 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 30 Oct 2023 15:03:04 -0300 +Subject: [PATCH 25/33] [M118-fix] Avoid using + std::ranges::any_of/find_if/none_of/all_of + +Those functions are available only in newer c++ standards(C++20). +Chromium defines those functions in base::ranges. + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + chrome/browser/ui/webauthn/sheet_models.cc | 2 +- + .../browser/webauthn/authenticator_request_dialog_model.cc | 2 +- + .../webauthn/chrome_authenticator_request_delegate.cc | 4 ++-- + device/fido/get_assertion_request_handler.cc | 5 +++-- + 4 files changed, 7 insertions(+), 6 deletions(-) + +diff --git a/chrome/browser/ui/webauthn/sheet_models.cc b/chrome/browser/ui/webauthn/sheet_models.cc +index e72087c22dc84..1d1999fdc49c3 100644 +--- a/chrome/browser/ui/webauthn/sheet_models.cc ++++ b/chrome/browser/ui/webauthn/sheet_models.cc +@@ -1499,7 +1499,7 @@ AuthenticatorMultiSourcePickerSheetModel:: + using ICloudKeychainMech = + AuthenticatorRequestDialogModel::Mechanism::ICloudKeychain; + bool has_local_passkeys = +- std::ranges::any_of(dialog_model->mechanisms(), [](const auto& mech) { ++ base::ranges::any_of(dialog_model->mechanisms(), [](const auto& mech) { + return absl::holds_alternative<CredentialMech>(mech.type) && + absl::get<CredentialMech>(mech.type).value().source != + device::AuthenticatorType::kPhone; +diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc +index 7695aa00f44a8..fa983ddf1a166 100644 +--- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc ++++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc +@@ -495,7 +495,7 @@ void AuthenticatorRequestDialogModel:: + // extra step. Jump to Windows instead. + if (base::FeatureList::IsEnabled(device::kWebAuthnNewPasskeyUI) && + transport_availability_.has_win_native_api_authenticator && +- std::ranges::all_of(mechanisms_, [](const auto& mech) { ++ base::ranges::all_of(mechanisms_, [](const auto& mech) { + return absl::holds_alternative<Mechanism::WindowsAPI>(mech.type) || + (absl::holds_alternative<Mechanism::Credential>(mech.type) && + absl::get<Mechanism::Credential>(mech.type).value().source == +diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc +index 15773fad86902..6ddd5cba1d6f3 100644 +--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc ++++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc +@@ -886,8 +886,8 @@ void ChromeAuthenticatorRequestDelegate::OnTransportAvailabilityEnumerated( + if (data.has_platform_authenticator_credential == + device::FidoRequestHandlerBase::RecognizedCredential:: + kHasRecognizedCredential && +- std::ranges::none_of(data.recognized_credentials, +- IsCredentialFromPlatformAuthenticator)) { ++ base::ranges::none_of(data.recognized_credentials, ++ IsCredentialFromPlatformAuthenticator)) { + data.has_platform_authenticator_credential = device:: + FidoRequestHandlerBase::RecognizedCredential::kNoRecognizedCredential; + } +diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc +index 507cc2b46ddb6..80b6da1799c33 100644 +--- a/device/fido/get_assertion_request_handler.cc ++++ b/device/fido/get_assertion_request_handler.cc +@@ -15,6 +15,7 @@ + #include "base/functional/bind.h" + #include "base/json/json_writer.h" + #include "base/metrics/histogram_functions.h" ++#include "base/ranges/algorithm.h" + #include "base/stl_util.h" + #include "base/strings/string_number_conversions.h" + #include "base/timer/elapsed_timer.h" +@@ -370,7 +371,7 @@ bool AllowListOnlyHybridOrInternal(const CtapGetAssertionRequest& request) { + + bool AllowListIncludedTransport(const CtapGetAssertionRequest& request, + FidoTransportProtocol transport) { +- return std::ranges::any_of( ++ return base::ranges::any_of( + request.allow_list, + [transport](const PublicKeyCredentialDescriptor& cred) { + return cred.transports.empty() || +@@ -441,7 +442,7 @@ void GetAssertionRequestHandler::PreselectAccount( + PublicKeyCredentialDescriptor credential) { + DCHECK(!preselected_credential_); + DCHECK(request_.allow_list.empty() || +- std::ranges::any_of( ++ base::ranges::any_of( + request_.allow_list, + [&credential](const PublicKeyCredentialDescriptor& desc) { + return desc.id == credential.id; +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0026-M118-fix-Add-deleted-constructors-operators.patch b/recipes-wam/cef/files/chromium/0026-M118-fix-Add-deleted-constructors-operators.patch new file mode 100644 index 00000000..06106360 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0026-M118-fix-Add-deleted-constructors-operators.patch @@ -0,0 +1,339 @@ +From 19a3339965f79f8ae8ab650850461cbd0a782bff Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 30 Oct 2023 15:28:20 -0300 +Subject: [PATCH 26/33] [M118-fix] Add deleted constructors/operators + +Apparently the rules for deleting the implicitly-defined move +constructor/operators is different in clang 14 and this causes build +issues where the constructors or operators are needed. + +So we explicitly declare all the needed constructors defined as deleted +by the compiler. + +Upstream-Status: Inappropriate, only affects older versions of clang +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + .../profile_management_navigation_throttle.cc | 22 +++++++++++++ + .../core/browser/profile_token_quality.cc | 12 +++---- + .../core/browser/profile_token_quality.h | 15 +++++++++ + .../public/common/download_save_item_data.h | 5 +++ + .../fenced_frame/fenced_frame_reporter.h | 25 +++++++++++++++ + .../header_direct_from_seller_signals.cc | 4 ++- + .../webid/idp_network_request_manager.h | 31 +++++++++++++++++++ + .../renderer/platform/fonts/font_palette.h | 1 + + .../gesture_detection/motion_event_generic.cc | 27 ++++++++++++++++ + .../gesture_detection/motion_event_generic.h | 6 ++-- + 10 files changed, 139 insertions(+), 9 deletions(-) + +diff --git a/chrome/browser/enterprise/profile_management/profile_management_navigation_throttle.cc b/chrome/browser/enterprise/profile_management/profile_management_navigation_throttle.cc +index aecaaf76762ee..3b02142d3e722 100644 +--- a/chrome/browser/enterprise/profile_management/profile_management_navigation_throttle.cc ++++ b/chrome/browser/enterprise/profile_management/profile_management_navigation_throttle.cc +@@ -5,6 +5,7 @@ + #include "chrome/browser/enterprise/profile_management/profile_management_navigation_throttle.h" + + #include <string> ++#include <utility> + + #include "base/command_line.h" + #include "base/containers/contains.h" +@@ -47,6 +48,27 @@ constexpr char kGoogleServiceLoginUrl[] = + // Utility struct used to store SAML attributes related to third-party profile + // management. + struct SAMLProfileAttributes { ++ SAMLProfileAttributes() {} ++ SAMLProfileAttributes(std::string n, std::string d, std::string t) ++ : name{n}, domain{d}, token{t} {} ++ SAMLProfileAttributes(const SAMLProfileAttributes& o) ++ : SAMLProfileAttributes(o.name, ++ o.domain, ++ o.token) {} ++ SAMLProfileAttributes(SAMLProfileAttributes&& o) ++ : name{std::move(o.name)} ++ , domain{std::move(o.domain)} ++ , token{std::move(o.token)} {} ++ SAMLProfileAttributes& operator=(const SAMLProfileAttributes& o) { ++ return *this = SAMLProfileAttributes(o); ++ } ++ SAMLProfileAttributes& operator=(SAMLProfileAttributes&& o) { ++ name = std::move(o.name); ++ domain = std::move(o.domain); ++ token = std::move(o.token); ++ return *this; ++ } ++ + std::string name; + std::string domain; + std::string token; +diff --git a/components/autofill/core/browser/profile_token_quality.cc b/components/autofill/core/browser/profile_token_quality.cc +index ff5f175372f39..e1c18eccb84b3 100644 +--- a/components/autofill/core/browser/profile_token_quality.cc ++++ b/components/autofill/core/browser/profile_token_quality.cc +@@ -241,10 +241,10 @@ bool ProfileTokenQuality::AddObservationsForFilledForm( + } + possible_observations.emplace_back( + stored_type, +- Observation{.type = base::to_underlying(GetObservationTypeFromField( ++ Observation(base::to_underlying(GetObservationTypeFromField( + field, form_data.fields[i].value, other_profiles, + pdm.app_locale())), +- .form_hash = hash}); ++ hash)); + } + return AddSubsetOfObservations(std::move(possible_observations)) > 0; + } +@@ -387,10 +387,10 @@ void ProfileTokenQuality::LoadSerializedObservationsForStoredType( + for (size_t i = 0; i + 1 < serialized_data.size(); i += 2) { + AddObservation( + type, +- Observation{ +- .type = std::min(serialized_data[i], +- base::to_underlying(ObservationType::kMaxValue)), +- .form_hash = FormSignatureHash(serialized_data[i + 1])}); ++ Observation( ++ std::min(serialized_data[i], ++ base::to_underlying(ObservationType::kMaxValue)), ++ FormSignatureHash(serialized_data[i + 1]))); + } + } + +diff --git a/components/autofill/core/browser/profile_token_quality.h b/components/autofill/core/browser/profile_token_quality.h +index 9dc16a1f98a13..2f726f04ab8d3 100644 +--- a/components/autofill/core/browser/profile_token_quality.h ++++ b/components/autofill/core/browser/profile_token_quality.h +@@ -211,6 +211,21 @@ class ProfileTokenQuality { + // For this reason, it is preferred to store the `ObservationType`s as their + // underlying type in the data model as well. + // Getters expose unknown values as `kUnknown`. ++ Observation(std::underlying_type_t<ObservationType> t, ++ FormSignatureHash h) : type{t}, form_hash{h} {} ++ Observation(const Observation &o) ++ : Observation(o.type, o.form_hash) {} ++ Observation(Observation &&o) : type{std::move(o.type)}, ++ form_hash{std::move(o.form_hash)} {} ++ Observation& operator=(const Observation& o) { ++ return *this = Observation(o); ++ } ++ Observation& operator=(Observation&& o) noexcept { ++ type = std::move(o.type); ++ form_hash = std::move(o.form_hash); ++ return *this; ++ } ++ + std::underlying_type_t<ObservationType> type; + FormSignatureHash form_hash = FormSignatureHash(0); + }; +diff --git a/components/download/public/common/download_save_item_data.h b/components/download/public/common/download_save_item_data.h +index 754aec2f64f6d..d49c3cd545b06 100644 +--- a/components/download/public/common/download_save_item_data.h ++++ b/components/download/public/common/download_save_item_data.h +@@ -20,6 +20,11 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadSaveItemData + : public base::SupportsUserData::Data { + public: + struct ItemInfo { ++ ItemInfo(base::FilePath f, GURL u, GURL r) ++ : file_path{f} ++ , url{u} ++ , referrer_url{r} {} ++ + // The final path where this file of the package will be saved. + base::FilePath file_path; + // The url this file was downloaded from. +diff --git a/content/browser/fenced_frame/fenced_frame_reporter.h b/content/browser/fenced_frame/fenced_frame_reporter.h +index 19ebadf3e14f7..8d2ee62847ced 100644 +--- a/content/browser/fenced_frame/fenced_frame_reporter.h ++++ b/content/browser/fenced_frame/fenced_frame_reporter.h +@@ -8,6 +8,7 @@ + #include <map> + #include <set> + #include <string> ++#include <utility> + #include <vector> + + #include "base/containers/flat_map.h" +@@ -40,6 +41,21 @@ class RenderFrameHostImpl; + // `type` is the key for the `ReportingUrlMap`, and `data` is sent with the + // request as a POST. + struct DestinationEnumEvent { ++ DestinationEnumEvent(std::string t, std::string d) ++ : type{std::move(t)} ++ , data{std::move(d)} {} ++ DestinationEnumEvent(const DestinationEnumEvent& o) ++ : DestinationEnumEvent(o.type, o.data) {} ++ DestinationEnumEvent(DestinationEnumEvent&& o) ++ : type{std::move(o.type)} ++ , data{std::move(o.data)} {} ++ DestinationEnumEvent& operator=(const DestinationEnumEvent& o) { ++ return *this = DestinationEnumEvent(o); ++ } ++ DestinationEnumEvent& operator=(DestinationEnumEvent&& o) { ++ std::swap(type, o.type); ++ std::swap(data, o.data); ++ } + std::string type; + std::string data; + }; +@@ -48,6 +64,15 @@ struct DestinationEnumEvent { + // `url` is the custom destination url, and the request is sent as a GET. + // Macros are substituted using the `ReportingMacros`. + struct DestinationURLEvent { ++ DestinationURLEvent(const GURL& u) : url{u} {} ++ DestinationURLEvent(const DestinationURLEvent& u) : url{u.url} {} ++ DestinationURLEvent(DestinationURLEvent&& u) : url{std::move(u.url)} {} ++ DestinationURLEvent& operator=(const DestinationURLEvent& o) { ++ return *this =DestinationURLEvent(o); ++ } ++ DestinationURLEvent& operator=(DestinationURLEvent&& o) { ++ std::swap(url, o.url); ++ } + GURL url; + }; + +diff --git a/content/browser/interest_group/header_direct_from_seller_signals.cc b/content/browser/interest_group/header_direct_from_seller_signals.cc +index fe59d11edf449..facbec80a203a 100644 +--- a/content/browser/interest_group/header_direct_from_seller_signals.cc ++++ b/content/browser/interest_group/header_direct_from_seller_signals.cc +@@ -16,6 +16,7 @@ + #include "base/strings/stringprintf.h" + #include "base/values.h" + #include "services/data_decoder/public/cpp/data_decoder.h" ++#include "third_party/abseil-cpp/absl/types/optional.h" + #include "url/gurl.h" + #include "url/origin.h" + #include "url/url_constants.h" +@@ -187,7 +188,8 @@ void OnJsonDecoded(std::unique_ptr<const std::set<std::string>> responses, + + } // namespace + +-HeaderDirectFromSellerSignals::HeaderDirectFromSellerSignals() = default; ++HeaderDirectFromSellerSignals::HeaderDirectFromSellerSignals() : seller_signals_{absl::nullopt} ++ , auction_signals_{absl::nullopt} {} + + HeaderDirectFromSellerSignals::~HeaderDirectFromSellerSignals() = default; + +diff --git a/content/browser/webid/idp_network_request_manager.h b/content/browser/webid/idp_network_request_manager.h +index 6a652e0a22b44..307e0f4a68f48 100644 +--- a/content/browser/webid/idp_network_request_manager.h ++++ b/content/browser/webid/idp_network_request_manager.h +@@ -75,6 +75,24 @@ class CONTENT_EXPORT IdpNetworkRequestManager { + kInvalidContentTypeError, + }; + struct FetchStatus { ++ FetchStatus(ParseStatus p, int r) ++ : parse_status{p} ++ , response_code{r} {} ++ FetchStatus(const FetchStatus& o) ++ : FetchStatus(o.parse_status, ++ o.response_code) {} ++ FetchStatus(FetchStatus&& o) ++ : parse_status{std::move(o.parse_status)} ++ , response_code{std::move(o.response_code)} {} ++ FetchStatus& operator=(const FetchStatus& o) { ++ return *this = FetchStatus(o); ++ } ++ FetchStatus& operator=(FetchStatus&& o) { ++ std::swap(parse_status, o.parse_status); ++ std::swap(response_code, o.response_code); ++ return *this; ++ } ++ + ParseStatus parse_status; + // The HTTP response code, if one was received, otherwise the net error. It + // is possible to distinguish which it is since HTTP response codes are +@@ -117,6 +135,19 @@ class CONTENT_EXPORT IdpNetworkRequestManager { + }; + + struct IdentityCredentialTokenError { ++ IdentityCredentialTokenError(int c, GURL u) : code{c}, url{u} {} ++ IdentityCredentialTokenError(const IdentityCredentialTokenError &o) ++ : IdentityCredentialTokenError(o.code, o.url) {} ++ IdentityCredentialTokenError(IdentityCredentialTokenError &&o) ++ : code{std::move(o.code)}, url{std::move(o.url)} {} ++ IdentityCredentialTokenError& operator=(const IdentityCredentialTokenError& o) { ++ return *this = IdentityCredentialTokenError(o); ++ } ++ IdentityCredentialTokenError& operator=(IdentityCredentialTokenError&& o) { ++ std::swap(code, o.code); ++ std::swap(url, o.url); ++ return *this; ++ } + int code; + GURL url; + }; +diff --git a/third_party/blink/renderer/platform/fonts/font_palette.h b/third_party/blink/renderer/platform/fonts/font_palette.h +index 01dac9c908e9e..9a1a167acf213 100644 +--- a/third_party/blink/renderer/platform/fonts/font_palette.h ++++ b/third_party/blink/renderer/platform/fonts/font_palette.h +@@ -60,6 +60,7 @@ class PLATFORM_EXPORT FontPalette : public RefCounted<FontPalette> { + }; + + struct NonNormalizedPercentages { ++ NonNormalizedPercentages(double s, double e) : start{s}, end{e} {} + double start; + double end; + bool operator==(const NonNormalizedPercentages& other) const { +diff --git a/ui/events/gesture_detection/motion_event_generic.cc b/ui/events/gesture_detection/motion_event_generic.cc +index 77c5edaa17ee4..a312c6d4de0cf 100644 +--- a/ui/events/gesture_detection/motion_event_generic.cc ++++ b/ui/events/gesture_detection/motion_event_generic.cc +@@ -348,6 +348,33 @@ MotionEventGeneric& MotionEventGeneric::operator=( + return *this; + } + ++MotionEventGeneric& MotionEventGeneric::operator=( ++ MotionEventGeneric&& other) { ++ action_ = std::move(other.action_); ++ event_time_ = std::move(other.event_time_); ++ unique_event_id_ = std::move(other.unique_event_id_); ++ action_index_ = std::move(other.action_index_); ++ button_state_ = std::move(other.button_state_); ++ flags_ = std::move(other.flags_); ++ pointers_ = std::move(other.pointers_); ++ const size_t history_size = std::move(other.GetHistorySize()); ++ for (size_t h = 0; h < history_size; ++h) ++ PushHistoricalEvent(other.historical_events_[h]->Clone()); ++} ++ ++MotionEventGeneric::MotionEventGeneric(MotionEventGeneric&& other) { ++ action_ = std::move(other.action_); ++ event_time_ = std::move(other.event_time_); ++ unique_event_id_ = std::move(other.unique_event_id_); ++ action_index_ = std::move(other.action_index_); ++ button_state_ = std::move(other.button_state_); ++ flags_ = std::move(other.flags_); ++ pointers_ = std::move(other.pointers_); ++ const size_t history_size = std::move(other.GetHistorySize()); ++ for (size_t h = 0; h < history_size; ++h) ++ PushHistoricalEvent(other.historical_events_[h]->Clone()); ++} ++ + void MotionEventGeneric::PopPointer() { + DCHECK_GT(pointers_.size(), 0U); + pointers_.pop_back(); +diff --git a/ui/events/gesture_detection/motion_event_generic.h b/ui/events/gesture_detection/motion_event_generic.h +index e508335d47ae9..ed87c6254412c 100644 +--- a/ui/events/gesture_detection/motion_event_generic.h ++++ b/ui/events/gesture_detection/motion_event_generic.h +@@ -55,6 +55,9 @@ class GESTURE_DETECTION_EXPORT MotionEventGeneric : public MotionEvent { + base::TimeTicks event_time, + const PointerProperties& pointer); + MotionEventGeneric(const MotionEventGeneric& other); ++ MotionEventGeneric(MotionEventGeneric&& other); ++ MotionEventGeneric& operator=(const MotionEventGeneric& other); ++ MotionEventGeneric& operator=(MotionEventGeneric&& other); + + ~MotionEventGeneric() override; + +@@ -124,8 +127,7 @@ class GESTURE_DETECTION_EXPORT MotionEventGeneric : public MotionEvent { + protected: + MotionEventGeneric(); + MotionEventGeneric(const MotionEvent& event, bool with_history); +- MotionEventGeneric& operator=(const MotionEventGeneric& other); +- ++ + void PopPointer(); + + private: +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0027-M118-fix-Initialize-percentages-member-on-blink-Font.patch b/recipes-wam/cef/files/chromium/0027-M118-fix-Initialize-percentages-member-on-blink-Font.patch new file mode 100644 index 00000000..9d7e30eb --- /dev/null +++ b/recipes-wam/cef/files/chromium/0027-M118-fix-Initialize-percentages-member-on-blink-Font.patch @@ -0,0 +1,52 @@ +From c206c886eabc8f03289802276f826baedf0e4e54 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 30 Oct 2023 21:20:48 -0300 +Subject: [PATCH 27/33] [M118-fix] Initialize percentages member on + blink::FontPalette + +Fixes the build issue: + +error: constructor for 'blink::FontPalette' must explicitly +initialize the member 'percentages_' + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + .../blink/renderer/platform/fonts/font_palette.h | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/third_party/blink/renderer/platform/fonts/font_palette.h b/third_party/blink/renderer/platform/fonts/font_palette.h +index 9a1a167acf213..8c9a9c02439b5 100644 +--- a/third_party/blink/renderer/platform/fonts/font_palette.h ++++ b/third_party/blink/renderer/platform/fonts/font_palette.h +@@ -202,11 +202,14 @@ class PLATFORM_EXPORT FontPalette : public RefCounted<FontPalette> { + + private: + explicit FontPalette(KeywordPaletteName palette_name) +- : palette_keyword_(palette_name), base_palette_({kNoBasePalette, 0}) {} ++ : palette_keyword_(palette_name), ++ base_palette_({kNoBasePalette, 0}), ++ percentages_{0.0, 0.0} {} + explicit FontPalette(AtomicString palette_values_name) + : palette_keyword_(kCustomPalette), + palette_values_name_(palette_values_name), +- base_palette_({kNoBasePalette, 0}) {} ++ base_palette_({kNoBasePalette, 0}), ++ percentages_{0.0, 0.0} {} + FontPalette( + scoped_refptr<FontPalette> start, + scoped_refptr<FontPalette> end, +@@ -224,7 +227,9 @@ class PLATFORM_EXPORT FontPalette : public RefCounted<FontPalette> { + color_interpolation_space_(color_interpoaltion_space), + hue_interpolation_method_(hue_interpolation_method) {} + FontPalette() +- : palette_keyword_(kNormalPalette), base_palette_({kNoBasePalette, 0}) {} ++ : palette_keyword_(kNormalPalette), ++ base_palette_({kNoBasePalette, 0}), ++ percentages_{0.0, 0.0} {} + + KeywordPaletteName palette_keyword_; + AtomicString palette_values_name_; +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0028-M118-fix-Don-t-delete-ZstdSourceStream-copy-move-cto.patch b/recipes-wam/cef/files/chromium/0028-M118-fix-Don-t-delete-ZstdSourceStream-copy-move-cto.patch new file mode 100644 index 00000000..d387b67c --- /dev/null +++ b/recipes-wam/cef/files/chromium/0028-M118-fix-Don-t-delete-ZstdSourceStream-copy-move-cto.patch @@ -0,0 +1,32 @@ +From f45fd7f3cd85c0d421c37202d0f4dff2f7925162 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Fri, 3 Nov 2023 15:53:09 -0300 +Subject: [PATCH 28/33] [M118-fix] Don't delete ZstdSourceStream copy/move + ctors + +std::unique_ptr requires the deleted ZstdSourceStream deleted +constructors and it causes a build issue. + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + net/filter/zstd_source_stream.cc | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/net/filter/zstd_source_stream.cc b/net/filter/zstd_source_stream.cc +index 551729ac542b7..81d4565608e7a 100644 +--- a/net/filter/zstd_source_stream.cc ++++ b/net/filter/zstd_source_stream.cc +@@ -64,9 +64,6 @@ class ZstdSourceStream : public FilterSourceStream { + } + } + +- ZstdSourceStream(const ZstdSourceStream&) = delete; +- ZstdSourceStream& operator=(const ZstdSourceStream&) = delete; +- + ~ZstdSourceStream() override { + if (ZSTD_isError(decoding_result_)) { + ZSTD_ErrorCode error_code = ZSTD_getErrorCode(decoding_result_); +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0029-M118-fix-Fix-issue-with-structured-bindinds-captured.patch b/recipes-wam/cef/files/chromium/0029-M118-fix-Fix-issue-with-structured-bindinds-captured.patch new file mode 100644 index 00000000..fec15dd8 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0029-M118-fix-Fix-issue-with-structured-bindinds-captured.patch @@ -0,0 +1,68 @@ +From f7581fa1a0c25d2b76407bb04fd77031f5108411 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Fri, 3 Nov 2023 21:08:22 -0300 +Subject: [PATCH 29/33] [M118-fix] Fix issue with structured bindinds captured + by nested lambdas + +In clang <=14 the build fails doesn't when lambdas capture +aliases created in structured bindinds, so we do a few init-captures to +fix that. + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + .../core/layout/ng/grid/ng_grid_layout_algorithm.cc | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc +index 64c7a7481dd15..71eb55954e253 100644 +--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc ++++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc +@@ -3494,7 +3494,7 @@ void NGGridLayoutAlgorithm::PlaceGridItems( + To<NGPhysicalBoxFragment>(result->PhysicalFragment()); + NGBoxFragment fragment(container_writing_direction, physical_fragment); + +- auto BaselineOffset = [&](GridTrackSizingDirection track_direction, ++ auto BaselineOffset = [&, &layout_data = layout_data](GridTrackSizingDirection track_direction, + LayoutUnit size) -> LayoutUnit { + if (!grid_item.IsBaselineAligned(track_direction)) { + return LayoutUnit(); +@@ -3700,7 +3700,7 @@ void NGGridLayoutAlgorithm::PlaceGridItemsForFragmentation( + if (BreakToken()) + child_break_tokens = BreakToken()->ChildBreakTokens(); + +- auto PlaceItems = [&]() { ++ auto PlaceItems = [&, &grid_items = grid_items, &layout_data = layout_data]() { + // Reset our state. + result_and_offsets.clear(); + out_of_fragmentainer_space_item_placement.clear(); +@@ -3933,7 +3933,7 @@ void NGGridLayoutAlgorithm::PlaceGridItemsForFragmentation( + + // Adjust by |delta| the pre-computed item-offset for all grid items with a + // row begin index greater or equal than |row_index|. +- auto AdjustItemOffsets = [&](wtf_size_t row_index, LayoutUnit delta) { ++ auto AdjustItemOffsets = [&, &grid_items = grid_items](wtf_size_t row_index, LayoutUnit delta) { + auto current_item = grid_items.begin(); + + for (auto& item_placement_data : *grid_items_placement_data) { +@@ -3944,7 +3944,7 @@ void NGGridLayoutAlgorithm::PlaceGridItemsForFragmentation( + + // Adjust our grid break-token data to accommodate the larger item in the row. + // Returns true if this function adjusted the break-token data in any way. +- auto ExpandRow = [&]() -> bool { ++ auto ExpandRow = [&, &layout_data = layout_data]() -> bool { + if (max_row_expansion == 0) + return false; + +@@ -3963,7 +3963,7 @@ void NGGridLayoutAlgorithm::PlaceGridItemsForFragmentation( + // Shifts the row where we wish to take a breakpoint (indicated by + // |breakpoint_row_set_index|) into the next fragmentainer. + // Returns true if this function adjusted the break-token data in any way. +- auto ShiftBreakpointIntoNextFragmentainer = [&]() -> bool { ++ auto ShiftBreakpointIntoNextFragmentainer = [&, &layout_data = layout_data]() -> bool { + if (breakpoint_row_set_index == kNotFound) + return false; + +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0030-M118-fix-Only-default-arm_use_neon-to-true-if-its-va.patch b/recipes-wam/cef/files/chromium/0030-M118-fix-Only-default-arm_use_neon-to-true-if-its-va.patch new file mode 100644 index 00000000..08a2db60 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0030-M118-fix-Only-default-arm_use_neon-to-true-if-its-va.patch @@ -0,0 +1,107 @@ +From 55fe851951b11c30e010b5f3df618addf606e3d4 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Wed, 8 Nov 2023 14:35:21 -0300 +Subject: [PATCH 30/33] [M118-fix] Only default arm_use_neon to true if its + value wasn't already set + +arm_use_neon was always being set causing the build to fail. + +Upstream-Status: Needs checking +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + build/config/arm.gni | 58 +++++++++++++++++++++----------------------- + 1 file changed, 27 insertions(+), 31 deletions(-) + +diff --git a/build/config/arm.gni b/build/config/arm.gni +index 5b404c1ca94f0..575871c287c80 100644 +--- a/build/config/arm.gni ++++ b/build/config/arm.gni +@@ -9,36 +9,39 @@ import("//build/config/v8_target_cpu.gni") + # ARM code is being compiled. But they can also be relevant in the + # other contexts when the code will change its behavior based on the + # cpu it wants to generate code for. +-if (current_cpu == "arm" || v8_current_cpu == "arm") { +- declare_args() { +- # Version of the ARM processor when compiling on ARM. Ignored on non-ARM +- # platforms. +- arm_version = 7 ++declare_args() { ++ # Version of the ARM processor when compiling on ARM. Ignored on non-ARM ++ # platforms. ++ arm_version = 7 + +- # The ARM architecture. This will be a string like "armv6" or "armv7-a". +- # An empty string means to use the default for the arm_version. +- arm_arch = "" ++ # The ARM architecture. This will be a string like "armv6" or "armv7-a". ++ # An empty string means to use the default for the arm_version. ++ arm_arch = "" + +- # The ARM floating point hardware. This will be a string like "neon" or +- # "vfpv3". An empty string means to use the default for the arm_version. +- arm_fpu = "" ++ # The ARM floating point hardware. This will be a string like "neon" or ++ # "vfpv3". An empty string means to use the default for the arm_version. ++ arm_fpu = "" + +- # The ARM variant-specific tuning mode. This will be a string like "armv6" +- # or "cortex-a15". An empty string means to use the default for the +- # arm_version. +- arm_tune = "" ++ # The ARM variant-specific tuning mode. This will be a string like "armv6" ++ # or "cortex-a15". An empty string means to use the default for the ++ # arm_version. ++ arm_tune = "" + +- # Whether to use the neon FPU instruction set or not. +- arm_use_neon = "" ++ # Whether to use the neon FPU instruction set or not. ++ arm_use_neon = "" + +- # Whether to enable optional NEON code paths. +- arm_optionally_use_neon = false ++ # Whether to enable optional NEON code paths. ++ arm_optionally_use_neon = false + +- # Thumb is a reduced instruction set available on some ARM processors that +- # has increased code density. +- arm_use_thumb = true +- } ++ # Thumb is a reduced instruction set available on some ARM processors that ++ # has increased code density. ++ arm_use_thumb = true + ++ arm_control_flow_integrity = "none" ++ arm_float_abi = "" ++} ++ ++if (current_cpu == "arm" || v8_current_cpu == "arm") { + # For lacros build, we use ARM v8 by default. + if (is_chromeos_lacros && arm_arch == "") { + # TODO(crbug.com/1467681) Enable i8mm and dotprod instructions for ffmpeg +@@ -49,13 +52,6 @@ if (current_cpu == "arm" || v8_current_cpu == "arm") { + + if (current_os == "android" || target_os == "android") { + arm_float_abi = "softfp" +- } else { +- declare_args() { +- # The ARM floating point mode. This is either the string "hard", "soft", +- # or "softfp". An empty string means to use the default one for the +- # arm_version. +- arm_float_abi = "" +- } + } + assert(arm_float_abi == "" || arm_float_abi == "hard" || + arm_float_abi == "soft" || arm_float_abi == "softfp") +@@ -126,7 +122,7 @@ if (current_cpu == "arm" || v8_current_cpu == "arm") { + } + } + } +-} else if (current_cpu == "arm64" || v8_current_cpu == "arm64") { ++} else if (arm_use_neon == "" && (current_cpu == "arm64" || v8_current_cpu == "arm64")) { + # arm64 supports only "hard". + arm_float_abi = "hard" + arm_use_neon = true +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0031-M118-fix-Add-a-way-to-set-different-lib-paths-host-a.patch b/recipes-wam/cef/files/chromium/0031-M118-fix-Add-a-way-to-set-different-lib-paths-host-a.patch new file mode 100644 index 00000000..fa049e1b --- /dev/null +++ b/recipes-wam/cef/files/chromium/0031-M118-fix-Add-a-way-to-set-different-lib-paths-host-a.patch @@ -0,0 +1,134 @@ +From e376fd5fa64d34803e821e02c0d5199ca7244944 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Sun, 12 Nov 2023 19:41:07 -0300 +Subject: [PATCH 31/33] [M118-fix] Add a way to set different lib paths host + and target + +meta-clang on AGL defines a simplified path structure for clang's +runtime libraries and a different lib naming convention. + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + build/config/clang/BUILD.gn | 79 +++++++++++------------------------- + build/config/clang/clang.gni | 3 ++ + 2 files changed, 26 insertions(+), 56 deletions(-) + +diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn +index fe044e29e428b..81ec24d92da72 100644 +--- a/build/config/clang/BUILD.gn ++++ b/build/config/clang/BUILD.gn +@@ -3,6 +3,7 @@ + # found in the LICENSE file. + + import("//build/config/rust.gni") ++import("//v8/gni/snapshot_toolchain.gni") + import("clang.gni") + + if (is_ios) { +@@ -95,66 +96,32 @@ template("clang_lib") { + } + } else { + config(target_name) { +- _dir = "" ++ if (is_a_target_toolchain) { ++ _base_path = "$clang_base_path_target" ++ _cpu = target_cpu ++ } else { ++ _base_path = "$clang_base_path" ++ _cpu = host_cpu ++ } ++ ++ if (_cpu == "x64") { ++ _suffix = "-x86_64" ++ } else if (_cpu == "x86") { ++ _suffix = "-i386" ++ } else if (_cpu == "arm64") { ++ _suffix = "-aarch64" ++ } else if (_cpu == "arm") { ++ _suffix = "-arm" ++ } else { ++ assert(false) # Unhandled cpu type ++ } ++ ++ _dir = "linux" + _libname = invoker.libname + _prefix = "lib" +- _suffix = "" + _ext = "a" +- if (is_win) { +- _dir = "windows" +- _prefix = "" +- _ext = "lib" +- if (current_cpu == "x64") { +- _suffix = "-x86_64" +- } else if (current_cpu == "x86") { +- _suffix = "-i386" +- } else if (current_cpu == "arm64") { +- _suffix = "-aarch64" +- } else { +- assert(false) # Unhandled cpu type +- } +- } else if (is_apple) { +- _dir = "darwin" +- } else if (is_linux || is_chromeos) { +- if (current_cpu == "x64") { +- _dir = "x86_64-unknown-linux-gnu" +- } else if (current_cpu == "x86") { +- _dir = "i386-unknown-linux-gnu" +- } else if (current_cpu == "arm") { +- _dir = "armv7-unknown-linux-gnueabihf" +- } else if (current_cpu == "arm64") { +- _dir = "aarch64-unknown-linux-gnu" +- } else { +- assert(false) # Unhandled cpu type +- } +- } else if (is_fuchsia) { +- if (current_cpu == "x64") { +- _dir = "x86_64-unknown-fuchsia" +- } else if (current_cpu == "arm64") { +- _dir = "aarch64-unknown-fuchsia" +- } else { +- assert(false) # Unhandled cpu type +- } +- } else if (is_android) { +- _dir = "linux" +- if (current_cpu == "x64") { +- _suffix = "-x86_64-android" +- } else if (current_cpu == "x86") { +- _suffix = "-i686-android" +- } else if (current_cpu == "arm") { +- _suffix = "-arm-android" +- } else if (current_cpu == "arm64") { +- _suffix = "-aarch64-android" +- } else if (current_cpu == "riscv64") { +- _suffix = "-riscv64-android" +- } else { +- assert(false) # Unhandled cpu type +- } +- } else { +- assert(false) # Unhandled target platform +- } + +- _clang_lib_dir = "$clang_base_path/lib/clang/$clang_version/lib" ++ _clang_lib_dir = "$_base_path/lib/clang/$clang_version/lib" + _lib_file = "${_prefix}clang_rt.${_libname}${_suffix}.${_ext}" + libs = [ "$_clang_lib_dir/$_dir/$_lib_file" ] + } +diff --git a/build/config/clang/clang.gni b/build/config/clang/clang.gni +index 1a065b5e348b0..46fb56693b494 100644 +--- a/build/config/clang/clang.gni ++++ b/build/config/clang/clang.gni +@@ -26,6 +26,9 @@ declare_args() { + build_with_chromium && !is_official_build && is_linux && !is_castos + + clang_base_path = default_clang_base_path ++ ++ # used only for linking ++ clang_base_path_target = default_clang_base_path + + # Specifies whether or not bitcode should be embedded during compilation. + # This is used for creating a MLGO corpus from Chromium in the non-ThinLTO case. +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0032-M118-fix-zlib-Fix-arm-build.patch b/recipes-wam/cef/files/chromium/0032-M118-fix-zlib-Fix-arm-build.patch new file mode 100644 index 00000000..3c2b3a77 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0032-M118-fix-zlib-Fix-arm-build.patch @@ -0,0 +1,48 @@ +From 9ae234968078366877a1f8027423644ae7bbfb89 Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 13 Nov 2023 11:07:15 -0300 +Subject: [PATCH 32/33] [M118-fix] zlib: Fix arm build + +Prevent inclusion of cpuid on arm builds. + +error: + +third_party/zlib/cpu_features.c:15: +cpuid.h:14:2: error: this header is for x86 only + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + third_party/zlib/adler32_simd.c | 2 +- + third_party/zlib/cpu_features.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/third_party/zlib/adler32_simd.c b/third_party/zlib/adler32_simd.c +index 58966eecf0b80..25867ace82bd2 100644 +--- a/third_party/zlib/adler32_simd.c ++++ b/third_party/zlib/adler32_simd.c +@@ -49,7 +49,7 @@ + /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + #define NMAX 5552 + +-#if defined(ADLER32_SIMD_SSSE3) ++#if (__x86_64__ || __i386__) && defined(ADLER32_SIMD_SSSE3) + + #include <tmmintrin.h> + +diff --git a/third_party/zlib/cpu_features.c b/third_party/zlib/cpu_features.c +index 64e0428cd2fc2..c26c619970c10 100644 +--- a/third_party/zlib/cpu_features.c ++++ b/third_party/zlib/cpu_features.c +@@ -11,7 +11,7 @@ + #include <stdint.h> + #if defined(_MSC_VER) + #include <intrin.h> +-#elif defined(ADLER32_SIMD_SSSE3) ++#elif (__x86_64__ || __i386__) && defined(ADLER32_SIMD_SSSE3) + #include <cpuid.h> + #endif + +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0033-M118-fix-Fix-skia-linker-issues-for-arm-neon.patch b/recipes-wam/cef/files/chromium/0033-M118-fix-Fix-skia-linker-issues-for-arm-neon.patch new file mode 100644 index 00000000..57f713b2 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0033-M118-fix-Fix-skia-linker-issues-for-arm-neon.patch @@ -0,0 +1,56 @@ +From 0c37732e8443882518b79ce50b9389d1218484ef Mon Sep 17 00:00:00 2001 +From: Roger Zanoni <rzanoni@igalia.com> +Date: Mon, 13 Nov 2023 22:10:25 -0300 +Subject: [PATCH 33/33] [M118-fix] Fix skia linker issues for arm neon + +Fixes the following linker issue: + +error: undefined symbol: skia::ConvolveHorizontally_Neon(...) + +Upstream-Status: Inappropriate +Signed-off-by: Roger Zanoni <rzanoni@igalia.com> +--- + build/config/arm.gni | 5 +++++ + skia/ext/convolver.cc | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/build/config/arm.gni b/build/config/arm.gni +index 575871c287c80..ebf56196c2605 100644 +--- a/build/config/arm.gni ++++ b/build/config/arm.gni +@@ -122,10 +122,14 @@ if (current_cpu == "arm" || v8_current_cpu == "arm") { + } + } + } ++ if (arm_use_neon) { ++ defines += [ "USE_NEON" ] ++ } + } else if (arm_use_neon == "" && (current_cpu == "arm64" || v8_current_cpu == "arm64")) { + # arm64 supports only "hard". + arm_float_abi = "hard" + arm_use_neon = true ++ defines += [ "USE_NEON" ] + declare_args() { + # Enables the new Armv8 branch protection features. Valid strings are: + # - "pac": Enables Pointer Authentication Code (PAC, featured in Armv8.3) +@@ -146,3 +150,4 @@ if (current_cpu == "arm" || v8_current_cpu == "arm") { + arm_control_flow_integrity == "pac", + "Invalid branch protection option") + } ++ +diff --git a/skia/ext/convolver.cc b/skia/ext/convolver.cc +index 8b3bd070d168a..a7d99de48d398 100644 +--- a/skia/ext/convolver.cc ++++ b/skia/ext/convolver.cc +@@ -371,7 +371,7 @@ void SetupSIMD(ConvolveProcs *procs) { + procs->extra_horizontal_reads = 3; + procs->convolve_vertically = &ConvolveVertically_mips_dspr2; + procs->convolve_horizontally = &ConvolveHorizontally_mips_dspr2; +-#elif defined SIMD_NEON ++#elif defined USE_NEON && defined SIMD_NEON + procs->extra_horizontal_reads = 3; + procs->convolve_vertically = &ConvolveVertically_Neon; + procs->convolve_4rows_horizontally = &Convolve4RowsHorizontally_Neon; +-- +2.42.1 + diff --git a/recipes-wam/cef/files/chromium/0034-v8-qemu-wrapper.patch b/recipes-wam/cef/files/chromium/0034-v8-qemu-wrapper.patch new file mode 100644 index 00000000..dec3db35 --- /dev/null +++ b/recipes-wam/cef/files/chromium/0034-v8-qemu-wrapper.patch @@ -0,0 +1,66 @@ +From 733559e6f2c26ccbce97354a2341b14c63563dab Mon Sep 17 00:00:00 2001 +From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com> +Date: Tue, 7 Nov 2017 15:24:32 +0100 +Subject: [PATCH] v8: qemu wrapper + +The patch below makes the V8 binaries run during the build be invoked through +QEMU, as they are built for the target. + +Upstream-Status: Inappropriate [embedder specific] + +Signed-off-by: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com> +Signed-off-by: Maksim Sisov <msisov@igalia.com> + +--- + tools/v8_context_snapshot/BUILD.gn | 1 + + v8/BUILD.gn | 4 ++++ + 2 files changed, 5 insertions(+) + +diff --git a/tools/v8_context_snapshot/BUILD.gn b/tools/v8_context_snapshot/BUILD.gn +index 52504f4..40425d6 100644 +--- a/tools/v8_context_snapshot/BUILD.gn ++++ b/tools/v8_context_snapshot/BUILD.gn +@@ -44,6 +44,7 @@ if (use_v8_context_snapshot) { + output_path = rebase_path(output_file, root_build_dir) + + args = [ ++ "./v8-qemu-wrapper.sh", + "./" + rebase_path(get_label_info(":v8_context_snapshot_generator", + "root_out_dir") + + "/v8_context_snapshot_generator", +diff --git a/v8/BUILD.gn b/v8/BUILD.gn +index 025203d..0c196bb 100644 +--- a/v8/BUILD.gn ++++ b/v8/BUILD.gn +@@ -2134,6 +2134,7 @@ template("run_torque") { + } + + args = [ ++ "./v8-qemu-wrapper.sh", + "./" + rebase_path( + get_label_info(":torque($toolchain)", "root_out_dir") + "/torque", + root_build_dir), +@@ -2291,6 +2292,7 @@ action("generate_bytecode_builtins_list") { + outputs = [ "$target_gen_dir/builtins-generated/bytecodes-builtins-list.h" ] + deps = [ ":bytecode_builtins_list_generator($v8_generator_toolchain)" ] + args = [ ++ "./v8-qemu-wrapper.sh", + "./" + rebase_path( + get_label_info( + ":bytecode_builtins_list_generator($v8_generator_toolchain)", +@@ -2330,6 +2332,7 @@ template("run_mksnapshot") { + data = [] + + args = [ ++ "./v8-qemu-wrapper.sh", + "./" + rebase_path(get_label_info(":mksnapshot($v8_snapshot_toolchain)", + "root_out_dir") + "/mksnapshot", + root_build_dir), +@@ -6931,6 +6934,7 @@ if (v8_enable_i18n_support) { + outputs = [ output_file ] + + args = [ ++ "./v8-qemu-wrapper.sh", + "./" + rebase_path( + get_label_info( + ":gen-regexp-special-case($v8_generator_toolchain)", diff --git a/recipes-wam/cef/gn-utils.inc b/recipes-wam/cef/gn-utils.inc new file mode 100644 index 00000000..34f8a12c --- /dev/null +++ b/recipes-wam/cef/gn-utils.inc @@ -0,0 +1,115 @@ +# GN host architecture helpers. +# +# Copied from https://github.com/OSSystems/meta-browser +# +# BUILD_ARCH's value corresponds to what uname returns as the machine name. +# The mapping in gn_host_arch_name() tries to match several possible values +# returned by the Linux kernel in uname(2) into the corresponding values GN +# understands. + +def gn_host_arch_name(d): + """Returns a GN architecture name corresponding to the build host's machine + architecture.""" + import re + arch_translations = { + r'aarch64.*': 'arm64', + r'arm.*': 'arm', + r'i[3456]86$': 'x86', + r'x86_64$': 'x64', + } + build_arch = d.getVar("BUILD_ARCH") + for arch_regexp, gn_arch_name in arch_translations.items(): + if re.match(arch_regexp, build_arch): + return gn_arch_name + bb.fatal('Unsuported BUILD_ARCH value: "%s"' % build_arch) + +# GN target architecture helpers. +# +# Determining the target architecture is more difficult, as there are many +# different values we can use on the Yocto side (e.g. TUNE_ARCH, TARGET_ARCH, +# MACHINEOVERRIDES etc). What we do is define the mapping with regular, +# non-Python variables with overrides that are generic enough (i.e. "x86" +# instead of "i586") and then use gn_target_arch_name() to return the right +# value with some validation. +GN_TARGET_ARCH_NAME:aarch64 = "arm64" +GN_TARGET_ARCH_NAME:arm = "arm" +GN_TARGET_ARCH_NAME:x86 = "x86" +GN_TARGET_ARCH_NAME:x86-64 = "x64" + +def clang_install_path(d): + """Return clang compiler install path.""" + return d.getVar("STAGING_BINDIR_NATIVE") + +def gn_target_arch_name(d): + """Returns a GN architecture name corresponding to the target machine's + architecture.""" + name = d.getVar("GN_TARGET_ARCH_NAME") + if name is None: + bb.fatal('Unsupported target architecture. A valid override for the ' + 'GN_TARGET_ARCH_NAME variable could not be found.') + return name + +def write_toolchain_file(d, file_path): + """Creates a complete GN toolchain file in |file_path|.""" + import string + # Even though we always use clang, the "clang_toolchain" GN template is too + # restrictive in the way it sets variables such as |cxx|. Since it is just + # a wrapper on top of the "gcc_toolchain" template, we keep using the + # latter directly to accommodate our cross-compilation needs. + toolchain_tmpl = string.Template( + 'gcc_toolchain("${toolchain_name}") {\n' + ' cc = "${cc}"\n' + ' cxx = "${cxx}"\n' + ' ar = "${ar}"\n' + ' ld = cxx # GN expects a compiler, not a linker.\n' + ' nm = "${nm}"\n' + ' readelf = "${readelf}"\n' + ' extra_cflags = "${extra_cflags}"\n' + ' extra_cppflags = "${extra_cppflags}"\n' + ' extra_cxxflags = "${extra_cxxflags}"\n' + ' extra_ldflags = "${extra_ldflags}"\n' + ' toolchain_args = {\n' + ' current_cpu = "${current_cpu}"\n' + ' current_os = "linux"\n' + ' is_clang = true\n' + ' }\n' + '}\n' + ) + + native_toolchain = { + 'toolchain_name': 'yocto_native', + 'current_cpu': gn_host_arch_name(d), + 'cc': d.expand('${BUILD_CC}'), + 'cxx': d.expand('${BUILD_CXX}'), + 'ar': d.expand('${BUILD_AR}'), + 'nm': d.expand('${BUILD_NM}'), + 'readelf': d.expand('${BUILD_PREFIX}readelf'), + 'extra_cflags': d.expand('${BUILD_CFLAGS}'), + 'extra_cppflags': d.expand('${BUILD_CPPFLAGS}'), + 'extra_cxxflags': d.expand('${BUILD_CXXFLAGS}'), + 'extra_ldflags': d.expand('${BUILD_LDFLAGS}'), + } + target_toolchain = { + 'toolchain_name': 'yocto_target', + 'current_cpu': gn_target_arch_name(d), + 'cc': d.expand('${CC}'), + 'cxx': d.expand('${CXX}'), + 'ar': d.expand('${AR}'), + 'nm': d.expand('${NM}'), + 'readelf': d.expand('${READELF}'), + 'extra_cflags': d.expand('${CFLAGS}'), + 'extra_cppflags': d.expand('${CPPFLAGS}'), + 'extra_cxxflags': d.expand('${CXXFLAGS}'), + 'extra_ldflags': d.expand('${LDFLAGS}'), + } + + with open(file_path, 'w') as toolchain_file: + toolchain_file.write( + '# This file has been generated automatically.\n' + '\n' + 'import("//build/toolchain/gcc_toolchain.gni")\n' + '\n' + ) + toolchain_file.write(toolchain_tmpl.substitute(native_toolchain)) + toolchain_file.write(toolchain_tmpl.substitute(target_toolchain)) + diff --git a/recipes-wam/depot_tools/depot-tools-wam-native_git.bb b/recipes-wam/depot_tools/depot-tools-wam-native_git.bb new file mode 100644 index 00000000..9a466bb3 --- /dev/null +++ b/recipes-wam/depot_tools/depot-tools-wam-native_git.bb @@ -0,0 +1,32 @@ +SUMMARY = " A collection of tools for dealing with Chromium development" +DESCRIPTION = "The Chromium depot_tools suite contains many tools to assist/augment the Chromium development environment." +HOMEPAGE = "https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html" + +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=c2c05f9bdd5fc0b458037c2d1fb8d95e" + +SRC_URI = "git://chromium.googlesource.com/chromium/tools/depot_tools.git;protocol=https;branch=main" +SRCREV = "64b61755572b1d03b3a43f1a29b617dcae3a3fe0" + +S = "${WORKDIR}/git" + +inherit native + +do_compile[network] = "1" +do_compile() { + export PATH=${S}:$PATH + ./ensure_bootstrap +} + +do_install() { + install -d ${D}${datadir}/depot_tools + cp -aR --no-dereference --no-preserve=owner ${WORKDIR}/git/. ${D}${datadir}/depot_tools +} + +INSANE_SKIP:${PN} += "already-stripped file-rdeps" + +BBCLASSEXTEND = "native" + +FILES:${PN}-dev += " \ + ${datadir}/depot_tools/* \ +" diff --git a/recipes-wam/grpc-web-proxy/files/databroker-grpc-web-proxy.env b/recipes-wam/grpc-web-proxy/files/databroker-grpc-web-proxy.env new file mode 100644 index 00000000..1435253d --- /dev/null +++ b/recipes-wam/grpc-web-proxy/files/databroker-grpc-web-proxy.env @@ -0,0 +1,7 @@ +EXTRA_ARGS="--backend_addr=localhost:55555 \ + --backend_client_tls_key_file=/etc/kuksa-val/Client.key \ + --backend_client_tls_cert_file=/etc/kuksa-val/Client.pem \ + --server_tls_key_file=/etc/kuksa-val/Server.key \ + --server_tls_cert_file=/etc/kuksa-val/Server.pem \ + --backend_tls_ca_files=/etc/kuksa-val/CA.pem --backend_tls=true \ + --server_http_tls_port=8888 --run_tls_server=true --allowed_origins=true" diff --git a/recipes-wam/grpc-web-proxy/files/databroker-grpc-web-proxy.service b/recipes-wam/grpc-web-proxy/files/databroker-grpc-web-proxy.service new file mode 100644 index 00000000..ff6afe44 --- /dev/null +++ b/recipes-wam/grpc-web-proxy/files/databroker-grpc-web-proxy.service @@ -0,0 +1,13 @@ +[Unit] +Description=gRPC web reverse proxy to kuksa.val databroker +Requires=kuksa-databroker.service +After=kuksa-databroker.service + +[Service] +User=kuksa +EnvironmentFile=-/etc/default/databroker-grpc-web-proxy.env +ExecStart=/usr/bin/grpcwebproxy $EXTRA_ARGS +Restart=on-abort + +[Install] +WantedBy=multi-user.target diff --git a/recipes-wam/grpc-web-proxy/grpc-web-proxy_git.bb b/recipes-wam/grpc-web-proxy/grpc-web-proxy_git.bb new file mode 100644 index 00000000..dfb763b6 --- /dev/null +++ b/recipes-wam/grpc-web-proxy/grpc-web-proxy_git.bb @@ -0,0 +1,34 @@ +SUMMARY = "A small reverse proxy that can front existing gRPC servers and expose their functionality using gRPC-Web protocol, allowing for the gRPC services to be consumed from browsers." +HOMEPAGE = "https://github.com/improbable-eng/grpc-web" + +inherit go-mod systemd + +RDEPENDS:${PN} = "bash" +RDEPENDS:${PN}-dev = "bash" + +GO_IMPORT = "github.com/improbable-eng/grpc-web" +GO_INSTALL = "${GO_IMPORT}/go/grpcwebproxy" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://src/${GO_IMPORT}/LICENSE.txt;md5=71a6955f3cd81a809549da266346dc59" + +SRCREV = "1d9bbb09a0990bdaff0e37499570dbc7d6e58ce8" +SRC_URI = "git://${GO_IMPORT};branch=master;protocol=https \ + file://databroker-grpc-web-proxy.env \ + file://databroker-grpc-web-proxy.service" + +do_compile[network] = "1" + +do_install:append() { + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/databroker-grpc-web-proxy.service ${D}${systemd_system_unitdir} + + install -d ${D}${sysconfdir}/default + install -m 0644 ${WORKDIR}/databroker-grpc-web-proxy.env ${D}${sysconfdir}/default/databroker-grpc-web-proxy.env +} + +SYSTEMD_SERVICE:${PN} = "databroker-grpc-web-proxy.service" + +FILES:${PN} = "${bindir} \ + ${systemd_system_unitdir} \ + ${sysconfdir}/default " diff --git a/recipes-wam/wam/files/0001-agl-cef-Snapshot-with-all-patches-needed-to-enable-w.patch b/recipes-wam/wam/files/0001-agl-cef-Snapshot-with-all-patches-needed-to-enable-w.patch new file mode 100644 index 00000000..65c2e7c6 --- /dev/null +++ b/recipes-wam/wam/files/0001-agl-cef-Snapshot-with-all-patches-needed-to-enable-w.patch @@ -0,0 +1,3702 @@ +From 54da26083a7a08b73fe617b683c3f3c8c895c4a2 Mon Sep 17 00:00:00 2001 +From: Jose Dapena Paz <jdapena@igalia.com> +Date: Fri, 9 Jun 2023 14:08:08 +0200 +Subject: [PATCH] [agl][cef] Snapshot with all patches needed to enable wam-cef + +--- + CMakeLists.txt | 18 +- + src/CMakeLists.txt | 58 ++- + src/agl-cef/CMakeLists.txt | 54 +++ + src/agl-cef/plugin/CMakeLists.txt | 59 +++ + src/agl-cef/plugin/agl_cef_context.cc | 4 + + src/agl-cef/plugin/agl_cef_context.h | 42 ++ + src/agl-cef/plugin/background_cef_app.cc | 33 ++ + src/agl-cef/plugin/background_cef_app.h | 20 + + src/agl-cef/plugin/homescreen_cef_app.cc | 25 ++ + src/agl-cef/plugin/homescreen_cef_app.h | 15 + + src/agl-cef/plugin/regular_cef_app.cc | 11 + + src/agl-cef/plugin/regular_cef_app.h | 12 + + src/agl-cef/plugin/web_app_factory_agl_cef.cc | 49 +++ + src/agl-cef/plugin/web_app_factory_agl_cef.h | 23 ++ + src/agl-cef/web_runtime_agl_cef.cc | 63 +++ + src/agl-cef/web_runtime_agl_cef.h | 11 + + src/agl/web_runtime_agl.cc | 16 +- + src/agl/web_runtime_agl.h | 20 +- + src/cef/cli/CMakeLists.txt | 17 + + src/cef/cli/wam_cli.cc | 171 ++++++++ + src/cef/device_info_cef.cc | 104 +++++ + src/cef/device_info_cef.h | 38 ++ + src/cef/handlers/wam_cef_browser_handler.cc | 31 ++ + src/cef/handlers/wam_cef_browser_handler.h | 23 ++ + src/cef/handlers/wam_cef_client.cc | 39 ++ + src/cef/handlers/wam_cef_client.h | 31 ++ + src/cef/handlers/wam_cef_render_handler.cc | 135 +++++++ + src/cef/handlers/wam_cef_render_handler.h | 54 +++ + src/cef/platform_module_factory_cef.cc | 31 ++ + src/cef/platform_module_factory_cef.h | 27 ++ + src/cef/plugin/web_app_cef.cc | 172 ++++++++ + src/cef/plugin/web_app_cef.h | 95 +++++ + src/cef/plugin/web_page_cef.cc | 48 +++ + src/cef/plugin/web_page_cef.h | 69 ++++ + src/cef/service/CMakeLists.txt | 64 +++ + src/cef/service/applauncher.proto | 50 +++ + src/cef/service/applauncher_client_grpc.cc | 58 +++ + src/cef/service/applauncher_client_grpc.h | 24 ++ + src/cef/service/wam_ipc.proto | 22 + + .../service/web_app_manager_client_grpc.cc | 42 ++ + src/cef/service/web_app_manager_client_grpc.h | 23 ++ + .../service/web_app_manager_service_grpc.cc | 382 ++++++++++++++++++ + .../service/web_app_manager_service_grpc.h | 85 ++++ + src/core/CMakeLists.txt | 4 + + src/core/application_description.cc | 37 ++ + src/core/application_installation_handler.h | 12 + + .../application_installation_handler_stub.cc | 4 + + src/core/memory_pressure_level.h | 6 + + src/core/web_app_manager.cc | 29 +- + src/core/web_app_manager.h | 4 +- + src/core/web_app_manager_service.cc | 4 +- + src/core/web_app_manager_service.h | 3 +- + src/core/web_page_base.h | 6 +- + src/core/web_process_manager.h | 1 + + src/core/web_runtime.h | 3 +- + src/desktop/CMakeLists.txt | 100 +++++ + src/desktop/README.md | 102 +++++ + src/desktop/web_runtime_desktop.cc | 28 ++ + src/desktop/web_runtime_desktop.h | 11 + + src/platform/CMakeLists.txt | 23 +- + src/platform/web_app_window.h | 6 +- + src/util/log_msg_id.h | 2 + + src/util/timer.h | 4 +- + src/wam_main.cc | 4 +- + src/webos/web_app_manager_service_luna.cc | 2 + + src/webos/web_runtime_webos.cc | 2 +- + src/webos/web_runtime_webos.h | 2 +- + 67 files changed, 2693 insertions(+), 74 deletions(-) + create mode 100644 src/agl-cef/CMakeLists.txt + create mode 100644 src/agl-cef/plugin/CMakeLists.txt + create mode 100644 src/agl-cef/plugin/agl_cef_context.cc + create mode 100644 src/agl-cef/plugin/agl_cef_context.h + create mode 100644 src/agl-cef/plugin/background_cef_app.cc + create mode 100644 src/agl-cef/plugin/background_cef_app.h + create mode 100644 src/agl-cef/plugin/homescreen_cef_app.cc + create mode 100644 src/agl-cef/plugin/homescreen_cef_app.h + create mode 100644 src/agl-cef/plugin/regular_cef_app.cc + create mode 100644 src/agl-cef/plugin/regular_cef_app.h + create mode 100644 src/agl-cef/plugin/web_app_factory_agl_cef.cc + create mode 100644 src/agl-cef/plugin/web_app_factory_agl_cef.h + create mode 100644 src/agl-cef/web_runtime_agl_cef.cc + create mode 100644 src/agl-cef/web_runtime_agl_cef.h + create mode 100644 src/cef/cli/CMakeLists.txt + create mode 100644 src/cef/cli/wam_cli.cc + create mode 100644 src/cef/device_info_cef.cc + create mode 100644 src/cef/device_info_cef.h + create mode 100644 src/cef/handlers/wam_cef_browser_handler.cc + create mode 100644 src/cef/handlers/wam_cef_browser_handler.h + create mode 100644 src/cef/handlers/wam_cef_client.cc + create mode 100644 src/cef/handlers/wam_cef_client.h + create mode 100644 src/cef/handlers/wam_cef_render_handler.cc + create mode 100644 src/cef/handlers/wam_cef_render_handler.h + create mode 100644 src/cef/platform_module_factory_cef.cc + create mode 100644 src/cef/platform_module_factory_cef.h + create mode 100644 src/cef/plugin/web_app_cef.cc + create mode 100644 src/cef/plugin/web_app_cef.h + create mode 100644 src/cef/plugin/web_page_cef.cc + create mode 100644 src/cef/plugin/web_page_cef.h + create mode 100644 src/cef/service/CMakeLists.txt + create mode 100644 src/cef/service/applauncher.proto + create mode 100644 src/cef/service/applauncher_client_grpc.cc + create mode 100644 src/cef/service/applauncher_client_grpc.h + create mode 100644 src/cef/service/wam_ipc.proto + create mode 100644 src/cef/service/web_app_manager_client_grpc.cc + create mode 100644 src/cef/service/web_app_manager_client_grpc.h + create mode 100644 src/cef/service/web_app_manager_service_grpc.cc + create mode 100644 src/cef/service/web_app_manager_service_grpc.h + create mode 100644 src/core/application_installation_handler.h + create mode 100644 src/core/application_installation_handler_stub.cc + create mode 100644 src/core/memory_pressure_level.h + create mode 100644 src/desktop/CMakeLists.txt + create mode 100644 src/desktop/README.md + create mode 100644 src/desktop/web_runtime_desktop.cc + create mode 100644 src/desktop/web_runtime_desktop.h + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 1e9f94f..073e326 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -18,22 +18,24 @@ cmake_minimum_required(VERSION 3.13.0) + + project(WebAppMgr VERSION 1.0.0 LANGUAGES CXX) + +-set(CMAKE_CXX_STANDARD 14) ++set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +-set(CMAKE_BUILD_TYPE Release) + + include(FindPkgConfig) + + set(OS_WEBOS FALSE) + set(OS_AGL FALSE) +-set(PLATFORM_NAME "WebOS" CACHE STRING "Target platform name (WebOS, POKY_AGL)") ++set(OS_DESKTOP FALSE) ++set(WEBENGINE_CEF TRUE) ++set(WEBENGINE_CBE FALSE) ++set(PLATFORM_NAME "Desktop" CACHE STRING "Target platform name (WebOS, POKY_AGL, Desktop)") + string(TOLOWER ${PLATFORM_NAME} PLATFORM) + if(${PLATFORM} STREQUAL "webos") + set(OS_WEBOS TRUE) + elseif(${PLATFORM} MATCHES ".*agl") + set(OS_AGL TRUE) + else() +- message(FATAL_ERROR "Unsupported platform: ${PLATFORM}") ++ set(OS_DESKTOP TRUE) + endif() + + if(OS_WEBOS) +@@ -45,4 +47,12 @@ if(OS_WEBOS) + webos_build_system_bus_files(${CMAKE_SOURCE_DIR}/files/sysbus) + endif() + ++message(STATUS "WAM Configuration:") ++message(STATUS "OS_WEBOS: ${OS_WEBOS}") ++message(STATUS "OS_AGL: ${OS_AGL}") ++message(STATUS "OS_DESKTOP: ${OS_DESKTOP}") ++message(STATUS "WEBENGINE_CEF: ${WEBENGINE_CEF}") ++message(STATUS "WEBENGINE_CBE: ${WEBENGINE_CBE}") ++message(STATUS "PLATFORM_NAME: ${PLATFORM_NAME}") ++ + add_subdirectory(src) +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 3cca138..173dafc 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -18,10 +18,12 @@ project(WebAppMgrExec VERSION 1.0.0 DESCRIPTION "WAM") + + set(WAM_ROOT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +-if(NOT DEFINED CHROMIUM_SRC_DIR) +- message(FATAL_ERROR "CHROMIUM_SRC_DIR was not set") ++if (WEBVIEW_CBE) ++ if(NOT DEFINED CHROMIUM_SRC_DIR) ++ message(FATAL_ERROR "CHROMIUM_SRC_DIR was not set") ++ endif() ++ set(CHROMIUM_LDFLAGS -lcbe) + endif() +-set(CHROMIUM_LDFLAGS -lcbe) + + find_package(PkgConfig REQUIRED) + find_package(Boost COMPONENTS filesystem REQUIRED) +@@ -39,6 +41,8 @@ elseif(OS_AGL) + find_package(gRPC REQUIRED) + find_program(GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin REQUIRED) + find_package(Threads) ++elseif(OS_DESKTOP) ++ set(DISABLE_PMLOG(true)) + endif() + + if(DISABLE_PMLOG) +@@ -58,7 +62,6 @@ set(WAM_COMPILER_FLAGS -fno-rtti + -Wall + -fpermissive + -funwind-tables +- -std=c++14 + -Wno-psabi + -Werror + ) +@@ -70,29 +73,68 @@ endif() + add_link_options(-Wl,--no-as-needed -Wno-psabi -rdynamic) + + add_subdirectory(core) +-add_subdirectory(platform) + + set(WAM_INCLUDE_DIRS + ${GLIB_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/core + ${CMAKE_CURRENT_SOURCE_DIR}/util +- ${CMAKE_CURRENT_SOURCE_DIR}/webos + ) + + set(WAM_LIBS + ${CHROMIUM_LDFLAGS} + ${PMLOGLIB_LDFLAGS} +- WebAppMgr + WebAppMgrCore + ) + ++if(WEBENGINE_CBE) ++ add_subdirectory(platform) ++ LIST(APPEND WAM_INCLUDE_DIRS ++ ${CMAKE_CURRENT_SOURCE_DIR}/webos ++ ) ++ LIST(APPEND WAM_LIBS ++ WebAppMgr ++ ) ++endif() ++ ++if(OS_DESKTOP OR WEBENGINE_CEF) ++ if(NOT DEFINED CEF_ROOT) ++ message(FATAL_ERROR "CEF_ROOT needs to point to the binary distribution directory") ++ endif() ++ ++ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CEF_ROOT}/cmake") ++ find_package(CEF REQUIRED) ++ message(STATUS "CEF lib location: ${CEF_LIB_RELEASE}") ++ print_cef_config() ++ ++ add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH} libcef_dll_wrapper) ++ add_library(libcef_lib SHARED IMPORTED) ++ set_target_properties(libcef_lib PROPERTIES IMPORTED_LOCATION ${CEF_LIB_RELEASE}) ++ target_link_libraries(libcef_dll_wrapper libcef_lib) ++ ++ LIST(APPEND WAM_LIBS libcef_lib libcef_dll_wrapper) ++endif() ++ ++if(OS_DESKTOP) ++ add_subdirectory(desktop) ++ add_subdirectory(cef/service) ++ add_subdirectory(cef/cli) ++ LIST(APPEND WAM_LIBS WebAppMgrDesktop) ++endif() ++ + if(OS_WEBOS) + add_subdirectory(plugin) + add_subdirectory(tests) + add_subdirectory(testplugin) + LIST(APPEND WAM_LIBS ${LIBLUNAPREFS_LDFLAGS}) + elseif(OS_AGL) +- add_subdirectory(agl/plugin) ++ if(WEBENGINE_CEF) ++ add_subdirectory(agl-cef) ++ add_subdirectory(cef/service) ++ add_subdirectory(cef/cli) ++ LIST(APPEND WAM_LIBS WebAppMgrAGLCEF) ++ else() ++ add_subdirectory(agl/plugin) ++ endif() + LIST(APPEND WAM_INCLUDE_DIRS + ${Protobuf_INCLUDE_DIRS} + ${gRPC_INCLUDE_DIRS} +diff --git a/src/agl-cef/CMakeLists.txt b/src/agl-cef/CMakeLists.txt +new file mode 100644 +index 0000000..8d29004 +--- /dev/null ++++ b/src/agl-cef/CMakeLists.txt +@@ -0,0 +1,54 @@ ++project(WebAppMgrAGLCEF VERSION 1.0.0 DESCRIPTION "Web Application Manager library") ++ ++set(WAM_LIB_LIBS ++ ${JSONCPP_LDFLAGS} ++ WebAppMgrCore ++ WebAppMgrService ++ libcef_lib ++ libcef_dll_wrapper ++) ++ ++set(SOURCES ++ web_runtime_agl_cef.cc ++) ++ ++set(HEADERS ++ web_runtime_agl_cef.h ++) ++ ++set(WAM_LIB_CEF_DIR ${WAM_ROOT_SOURCE_DIR}/cef) ++ ++set(WAM_LIB_INCLUDE_DIRS ++ ${JSONCPP_INCLUDE_DIRS} ++ ${CEF_INCLUDE_PATH} ++) ++ ++LIST(APPEND SOURCES ++ ${WAM_LIB_CEF_DIR}/device_info_cef.cc ++ ${WAM_LIB_CEF_DIR}/platform_module_factory_cef.cc ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_browser_handler.cc ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_client.cc ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_render_handler.cc ++) ++LIST(APPEND HEADERS ++ ${WAM_LIB_CEF_DIR}/device_info_cef.h ++ ${WAM_LIB_CEF_DIR}/platform_module_factory_cef.h ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_browser_handler.h ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_client.h ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_render_handler.cc ++) ++LIST(APPEND WAM_LIB_INCLUDE_DIRS ++ ${WAM_LIB_CEF_DIR} ++ ${WAM_LIB_CEF_DIR}/handlers ++) ++ ++add_library(${PROJECT_NAME} SHARED ${HEADERS} ${SOURCES}) ++target_include_directories(${PROJECT_NAME} PUBLIC ${WAM_LIB_INCLUDE_DIRS}) ++set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) ++ ++install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/webappmanager) ++ ++target_link_libraries(${PROJECT_NAME} PUBLIC ${WAM_LIB_LIBS}) ++install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++ ++add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/plugin) +diff --git a/src/agl-cef/plugin/CMakeLists.txt b/src/agl-cef/plugin/CMakeLists.txt +new file mode 100644 +index 0000000..052c94e +--- /dev/null ++++ b/src/agl-cef/plugin/CMakeLists.txt +@@ -0,0 +1,59 @@ ++project(webappmgr-default-plugin VERSION 1.0.0 DESCRIPTION "Default WAM plugin") ++ ++set(CEF_PLUGINS_DIR ${WAM_ROOT_SOURCE_DIR}/cef/plugin) ++set(CEF_HANDLERS_DIR ${WAM_ROOT_SOURCE_DIR}/cef/handlers) ++ ++set (SOURCES ++ ${CEF_HANDLERS_DIR}/wam_cef_client.cc ++ ${CEF_PLUGINS_DIR}/web_app_cef.cc ++ ${CEF_PLUGINS_DIR}/web_page_cef.cc ++ agl_cef_context.cc ++ web_app_factory_agl_cef.cc ++ background_cef_app.cc ++ homescreen_cef_app.cc ++ regular_cef_app.cc ++) ++set (HEADERS ++ ${CEF_HANDLERS_DIR}/wam_cef_client.h ++ ${CEF_PLUGINS_DIR}/web_app_cef.h ++ ${CEF_PLUGINS_DIR}/web_page_cef.h ++ agl_cef_context.h ++ web_app_factory_agl_cef.h ++ background_cef_app.h ++ homescreen_cef_app.h ++ regular_cef_app.h ++) ++set (WAM_PLUGIN_INCLUDE_DIRS ++ ${CEF_HANDLERS_DIR} ++ ${CEF_PLUGINS_DIR} ++ ${WAM_ROOT_SOURCE_DIR} ++ ${WAM_ROOT_SOURCE_DIR}/core ++ ${WAM_ROOT_SOURCE_DIR}/platform ++ ${WAM_ROOT_SOURCE_DIR}/platform/webengine ++ ${WAM_ROOT_SOURCE_DIR}/util ++ ${CEF_INCLUDE_PATH} ++) ++set(WAM_PLUGIN_LIBS ++ WebAppMgrService ++ WebAppMgrService-grpc ++ libcef_lib ++ libcef_dll_wrapper ++) ++ ++if (OS_DESKTOP) ++ LIST(APPEND WAM_PLUGIN_LIBS ++ WebAppMgrDesktop ++ ) ++else() ++ LIST(APPEND WAM_PLUGIN_LIBS ++ WebAppMgrAGLCEF ++ ) ++endif() ++ ++add_library(${PROJECT_NAME} SHARED ${HEADERS} ${SOURCES}) ++add_dependencies(${PROJECT_NAME} libcef_lib libcef_dll_wrapper) ++ ++target_include_directories(${PROJECT_NAME} PRIVATE ${WAM_PLUGIN_INCLUDE_DIRS}) ++target_link_libraries(${PROJECT_NAME} PRIVATE ${WAM_PLUGIN_LIBS}) ++install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/webappmanager/plugins) ++install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webappmanager) +diff --git a/src/agl-cef/plugin/agl_cef_context.cc b/src/agl-cef/plugin/agl_cef_context.cc +new file mode 100644 +index 0000000..8c1a390 +--- /dev/null ++++ b/src/agl-cef/plugin/agl_cef_context.cc +@@ -0,0 +1,4 @@ ++#include "agl_cef_context.h" ++ ++AglCefContext* AglCefContext::instance_ = nullptr; ++ +diff --git a/src/agl-cef/plugin/agl_cef_context.h b/src/agl-cef/plugin/agl_cef_context.h +new file mode 100644 +index 0000000..a1e698f +--- /dev/null ++++ b/src/agl-cef/plugin/agl_cef_context.h +@@ -0,0 +1,42 @@ ++#ifndef AGL_CEF_PLUGIN_AGL_CEF_CONTEXT_H ++#define AGL_CEF_PLUGIN_AGL_CEF_CONTEXT_H ++ ++#include <memory> ++ ++class AglCefContext { ++ public: ++ AglCefContext(const AglCefContext&) = delete; ++ AglCefContext& operator=(const AglCefContext&) = delete; ++ ++ static AglCefContext* get() { ++ if (!instance_) { ++ instance_ = new AglCefContext(); ++ } ++ return instance_; ++ } ++ ++ uint32_t activation_area_width() const { return activation_area_width_; } ++ void set_activation_area_width(uint32_t activation_area_width) { ++ activation_area_width_ = activation_area_width; ++ } ++ ++ uint32_t activation_area_height() const { return activation_area_height_; } ++ void set_activation_area_height(uint32_t activation_area_height) { ++ activation_area_height_ = activation_area_height; ++ } ++ ++ uint32_t panel_offset() const { return panel_offset_; } ++ void set_panel_offset(uint32_t panel_offset) { ++ panel_offset_ = panel_offset; ++ } ++ ++ private: ++ AglCefContext() = default; ++ ++ static AglCefContext* instance_; ++ uint32_t activation_area_width_ = 0; ++ uint32_t activation_area_height_ = 0; ++ uint32_t panel_offset_ = 0; ++}; ++ ++#endif // AGL_CEF_PLUGIN_AGL_CEF_CONTEXT_H +diff --git a/src/agl-cef/plugin/background_cef_app.cc b/src/agl-cef/plugin/background_cef_app.cc +new file mode 100644 +index 0000000..c406641 +--- /dev/null ++++ b/src/agl-cef/plugin/background_cef_app.cc +@@ -0,0 +1,33 @@ ++#include "background_cef_app.h" ++ ++BackgroundCefApp::BackgroundCefApp(std::shared_ptr<ApplicationDescription> app_desc) ++ : WebAppCEF(app_desc) { ++ CefRect display_bounds = GetDisplayBounds(); ++ width_override_ = display_bounds.width; ++ height_override_ = display_bounds.height; ++} ++ ++BackgroundCefApp::~BackgroundCefApp() {} ++ ++void BackgroundCefApp::Init(int width, ++ int height, ++ AglShellSurfaceType surface_type, ++ AglShellPanelEdge panel_type) { ++ if (!IsReady()) { ++ return; ++ } ++ ++ /* ++ // TODO: change when in portrait mode ++ window_->SetupActivationArea(AglCefContext::get()->panel_offset(), ++ 0, ++ AglCefContext::get()->activation_area_width(), ++ AglCefContext::get()->activation_area_height()); ++ */ ++ ++ WebAppCEF::Init(width, height, surface_type, panel_type); ++} ++ ++bool BackgroundCefApp::IsReady() const { ++ return window_ != nullptr; ++} +diff --git a/src/agl-cef/plugin/background_cef_app.h b/src/agl-cef/plugin/background_cef_app.h +new file mode 100644 +index 0000000..6681b5d +--- /dev/null ++++ b/src/agl-cef/plugin/background_cef_app.h +@@ -0,0 +1,20 @@ ++#ifndef AGL_CEF_PLUGIN_BACKGROUND_CEF_APP_H ++#define AGL_CEF_PLUGIN_BACKGROUND_CEF_APP_H ++ ++#include "agl_cef_context.h" ++#include "web_app_cef.h" ++ ++class BackgroundCefApp : public WebAppCEF { ++ public: ++ BackgroundCefApp(std::shared_ptr<ApplicationDescription> app_desc); ++ ~BackgroundCefApp(); ++ ++ void Init(int width, ++ int height, ++ AglShellSurfaceType surface_type, ++ AglShellPanelEdge panel_type) override; ++ ++ bool IsReady() const override; ++}; ++ ++#endif // AGL_CEF_PLUGIN_BACKGROUND_CEF_APP_H +diff --git a/src/agl-cef/plugin/homescreen_cef_app.cc b/src/agl-cef/plugin/homescreen_cef_app.cc +new file mode 100644 +index 0000000..cc6af64 +--- /dev/null ++++ b/src/agl-cef/plugin/homescreen_cef_app.cc +@@ -0,0 +1,25 @@ ++#include "homescreen_cef_app.h" ++ ++#include "agl_cef_context.h" ++ ++HomescreenCefApp::HomescreenCefApp(std::shared_ptr<ApplicationDescription> app_desc) ++ : WebAppCEF(app_desc) { ++ CefRect display_bounds = GetDisplayBounds(); ++ uint32_t panel_offset = app_desc->WidthOverride(); // TODO: height when in portrait mode ++ uint32_t activation_width = display_bounds.width - panel_offset - 1; ++ uint32_t activation_height = display_bounds.height; ++ ++ // TODO: change when in portrait mode ++ width_override_ = panel_offset; ++ height_override_ = activation_height; ++ ++ AglCefContext::get()->set_panel_offset(panel_offset); ++ AglCefContext::get()->set_activation_area_width(activation_width); ++ AglCefContext::get()->set_activation_area_height(activation_height); ++} ++ ++HomescreenCefApp::~HomescreenCefApp() {} ++ ++bool HomescreenCefApp::IsReady() const { ++ return window_ && window_->IsSurfaceConfigured(); ++} +diff --git a/src/agl-cef/plugin/homescreen_cef_app.h b/src/agl-cef/plugin/homescreen_cef_app.h +new file mode 100644 +index 0000000..c4f86ab +--- /dev/null ++++ b/src/agl-cef/plugin/homescreen_cef_app.h +@@ -0,0 +1,15 @@ ++#ifndef AGL_CEF_PLUGIN_HOMESCREEN_CEF_APP_H ++#define AGL_CEF_PLUGIN_HOMESCREEN_CEF_APP_H ++ ++#include "web_app_cef.h" ++ ++class HomescreenCefApp : public WebAppCEF { ++ public: ++ HomescreenCefApp(std::shared_ptr<ApplicationDescription> app_desc); ++ ~HomescreenCefApp(); ++ ++ protected: ++ bool IsReady() const override; ++}; ++ ++#endif // AGL_CEF_PLUGIN_BACKGROUND_CEF_APP_H +diff --git a/src/agl-cef/plugin/regular_cef_app.cc b/src/agl-cef/plugin/regular_cef_app.cc +new file mode 100644 +index 0000000..a882314 +--- /dev/null ++++ b/src/agl-cef/plugin/regular_cef_app.cc +@@ -0,0 +1,11 @@ ++#include "regular_cef_app.h" ++ ++#include "agl_cef_context.h" ++ ++RegularCefApp::RegularCefApp(std::shared_ptr<ApplicationDescription> app_desc) ++ : WebAppCEF(app_desc) { ++ width_override_ = AglCefContext::get()->activation_area_width(); ++ height_override_ = AglCefContext::get()->activation_area_height(); ++} ++ ++RegularCefApp::~RegularCefApp() {} +diff --git a/src/agl-cef/plugin/regular_cef_app.h b/src/agl-cef/plugin/regular_cef_app.h +new file mode 100644 +index 0000000..ed4b34d +--- /dev/null ++++ b/src/agl-cef/plugin/regular_cef_app.h +@@ -0,0 +1,12 @@ ++#ifndef AGL_CEF_PLUGIN_REGULAR_CEF_APP_H ++#define AGL_CEF_PLUGIN_REGULAR_CEF_APP_H ++ ++#include "web_app_cef.h" ++ ++class RegularCefApp : public WebAppCEF { ++ public: ++ RegularCefApp(std::shared_ptr<ApplicationDescription> app_desc); ++ ~RegularCefApp(); ++}; ++ ++#endif // AGL_CEF_PLUGIN_REGULAR_CEF_APP_H +diff --git a/src/agl-cef/plugin/web_app_factory_agl_cef.cc b/src/agl-cef/plugin/web_app_factory_agl_cef.cc +new file mode 100644 +index 0000000..8ca2ba8 +--- /dev/null ++++ b/src/agl-cef/plugin/web_app_factory_agl_cef.cc +@@ -0,0 +1,49 @@ ++#include "web_app_factory_agl_cef.h" ++ ++#include "application_description.h" ++#include "plugin_interface.h" ++ ++#include "background_cef_app.h" ++#include "homescreen_cef_app.h" ++#include "regular_cef_app.h" ++ ++#include "web_page_cef.h" ++ ++#include "wam_cef_client.h" ++ ++const char* kPluginApplicationType = "default"; ++ ++WebAppFactoryInterface* CreateInstance() { ++ return new WebAppFactoryCEF(); ++} ++ ++void DeleteInstance(WebAppFactoryInterface* interface) { ++ delete interface; ++} ++ ++WebAppBase* WebAppFactoryCEF::CreateWebApp( ++ const std::string&, ++ std::shared_ptr<ApplicationDescription> app_desc) { ++ std::string app_id = app_desc->Id(); ++ ++ if (app_id == "homescreen") { ++ return new HomescreenCefApp(app_desc); ++ } else if (app_id == "webapps-html5-background") { ++ return new BackgroundCefApp(app_desc); ++ } ++ return new RegularCefApp(app_desc); ++} ++ ++WebAppBase* WebAppFactoryCEF::CreateWebApp( ++ const std::string& win_type, ++ WebPageBase*, ++ std::shared_ptr<ApplicationDescription> desc) { ++ return CreateWebApp(win_type, desc); ++} ++ ++WebPageBase* WebAppFactoryCEF::CreateWebPage( ++ const wam::Url& url, ++ std::shared_ptr<ApplicationDescription> app_desc, ++ const std::string&) { ++ return new WebPageCEF(app_desc, url.ToString()); ++} +diff --git a/src/agl-cef/plugin/web_app_factory_agl_cef.h b/src/agl-cef/plugin/web_app_factory_agl_cef.h +new file mode 100644 +index 0000000..eb4b7ba +--- /dev/null ++++ b/src/agl-cef/plugin/web_app_factory_agl_cef.h +@@ -0,0 +1,23 @@ ++#ifndef AGL_CEF_PLUGIN_WEB_APP_FACTORY_CEF_H ++#define AGL_CEF_PLUGIN_WEB_APP_FACTORY_CEF_H ++ ++#include <memory> ++#include <string> ++ ++#include "web_app_factory_interface.h" ++ ++class WebAppFactoryCEF : public WebAppFactoryInterface { ++ public: ++ WebAppBase* CreateWebApp( ++ const std::string& win_type, ++ std::shared_ptr<ApplicationDescription> desc = 0) override; ++ WebAppBase* CreateWebApp( ++ const std::string& win_type, ++ WebPageBase* page, ++ std::shared_ptr<ApplicationDescription> desc = 0) override; ++ WebPageBase* CreateWebPage(const wam::Url& url, ++ std::shared_ptr<ApplicationDescription> desc, ++ const std::string& launchParams = "") override; ++}; ++ ++#endif // AGL_CEF_PLUGIN_WEB_APP_FACTORY_CEF_H +diff --git a/src/agl-cef/web_runtime_agl_cef.cc b/src/agl-cef/web_runtime_agl_cef.cc +new file mode 100644 +index 0000000..9bc1bd6 +--- /dev/null ++++ b/src/agl-cef/web_runtime_agl_cef.cc +@@ -0,0 +1,63 @@ ++#include "web_runtime_agl_cef.h" ++ ++#include "include/cef_base.h" ++#include "include/cef_origin_whitelist.h" ++ ++#include "wam_cef_browser_handler.h" ++#include "wam_cef_render_handler.h" ++ ++const char kProcessType[] = "type"; ++const char kRendererProcess[] = "renderer"; ++const char kZygoteProcess[] = "zygote"; ++ ++class WamCefUtilityHandler : public CefApp { ++ public: ++ WamCefUtilityHandler () {} ++ ++ private: ++ IMPLEMENT_REFCOUNTING(WamCefUtilityHandler); ++ DISALLOW_COPY_AND_ASSIGN(WamCefUtilityHandler); ++}; ++ ++int WebRuntimeCEF::Run(int argc, char** argv) { ++ CefMainArgs main_args(argc, argv); ++ ++ CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine(); ++ command_line->InitFromArgv(main_args.argc, main_args.argv); ++ ++ std::string app_id = command_line->GetSwitchValue("appid"); ++ if (app_id.empty()) { ++ app_id = "WebAppMgr"; ++ } ++ ++ CefRefPtr<CefApp> app; ++ if (!command_line->HasSwitch(kProcessType)) { ++ app = new WamCefBrowserHandler(); ++ } else { ++ const std::string& process_type = command_line->GetSwitchValue(kProcessType); ++ if (process_type == kRendererProcess || process_type == kZygoteProcess) { ++ app = new WamCefRenderHandler(); ++ } else { ++ app = new WamCefUtilityHandler(); ++ } ++ } ++ ++ auto exit_code = CefExecuteProcess(main_args, app.get(), nullptr); ++ if (exit_code >= 0) { ++ return exit_code; ++ } ++ ++ CefSettings settings; ++ settings.remote_debugging_port = 9998; ++ CefInitialize(main_args, settings, app.get(), nullptr); ++ ++ CefRunMessageLoop(); ++ ++ CefShutdown(); ++ ++ return 0; ++} ++ ++std::unique_ptr<WebRuntime> WebRuntime::Create() { ++ return std::make_unique<WebRuntimeCEF>(); ++} +diff --git a/src/agl-cef/web_runtime_agl_cef.h b/src/agl-cef/web_runtime_agl_cef.h +new file mode 100644 +index 0000000..049e554 +--- /dev/null ++++ b/src/agl-cef/web_runtime_agl_cef.h +@@ -0,0 +1,11 @@ ++#ifndef AGL_CEF_WEB_RUNTIME_AGL_CEF_H_ ++#define AGL_CEF_WEB_RUNTIME_AGL_CEF_H_ ++ ++#include "web_runtime.h" ++ ++class WebRuntimeCEF : public WebRuntime { ++ public: ++ int Run(int argc, char** argv) override; ++}; ++ ++#endif // AGL_CEF_WEB_RUNTIME_CEF_H_ +diff --git a/src/agl/web_runtime_agl.cc b/src/agl/web_runtime_agl.cc +index ce8525b..c791c70 100644 +--- a/src/agl/web_runtime_agl.cc ++++ b/src/agl/web_runtime_agl.cc +@@ -128,7 +128,7 @@ void SingleBrowserProcessWebAppLauncher::Launch( + } + + int SingleBrowserProcessWebAppLauncher::Loop(int argc, +- const char** argv, ++ char** argv, + volatile sig_atomic_t& e_flag) { + AGLMainDelegateWAM delegate; + webos::WebOSMain webOSMain(&delegate); +@@ -154,7 +154,7 @@ void SharedBrowserProcessWebAppLauncher::Launch( + } + + int SharedBrowserProcessWebAppLauncher::Loop(int argc, +- const char** argv, ++ char** argv, + volatile sig_atomic_t& e_flag) { + // TODO: wait for a pid + while (e_flag) +@@ -173,7 +173,7 @@ static void AglShellActivateApp(const std::string& app_id) { + WebAppManagerServiceAGL::Instance()->SendEvent(kActivateEvent, app_id); + } + +-int WebAppLauncherRuntime::Run(int argc, const char** argv) { ++int WebAppLauncherRuntime::Run(int argc, char** argv) { + bool is_wait_host_service = IsWaitForHostService(); + std::string app_id = IsActivateApp(Args::Instance()); + +@@ -334,7 +334,7 @@ bool WebAppLauncherRuntime::ParseJsonConfig(const char* path_to_config) { + return true; + } + +-int SharedBrowserProcessRuntime::Run(int argc, const char** argv) { ++int SharedBrowserProcessRuntime::Run(int argc, char** argv) { + if (WebAppManagerServiceAGL::Instance()->InitializeAsHostService()) { + AGLMainDelegateWAM delegate; + webos::WebOSMain webOSMain(&delegate); +@@ -347,7 +347,7 @@ int SharedBrowserProcessRuntime::Run(int argc, const char** argv) { + } + } + +-int RenderProcessRuntime::Run(int argc, const char** argv) { ++int RenderProcessRuntime::Run(int argc, char** argv) { + AGLMainDelegateWAM delegate; + webos::WebOSMain webOSMain(&delegate); + return webOSMain.Run(argc, argv); +@@ -372,7 +372,7 @@ static void print_help(void) { + exit(EXIT_FAILURE); + } + +-void Args::parse_args(int argc, const char** argv) { ++void Args::parse_args(int argc, char** argv) { + int c; + int option_index; + opterr = 0; +@@ -427,7 +427,7 @@ void Args::parse_args(int argc, const char** argv) { + } + } + +-void Args::copy_cmdline(int argc, const char** argv) { ++void Args::copy_cmdline(int argc, char** argv) { + new_argc = argc; + new_argv = static_cast<char**>(calloc(new_argc + 1, sizeof(*new_argv))); + +@@ -446,7 +446,7 @@ void Args::clear_cmdline(void) { + free(new_argv); + } + +-int WebRuntimeAGL::Run(int argc, const char** argv) { ++int WebRuntimeAGL::Run(int argc, char** argv) { + int ret; + Args::Instance()->parse_args(argc, argv); + +diff --git a/src/agl/web_runtime_agl.h b/src/agl/web_runtime_agl.h +index ad045c2..14bc0ed 100644 +--- a/src/agl/web_runtime_agl.h ++++ b/src/agl/web_runtime_agl.h +@@ -39,7 +39,7 @@ class Args { + static Args* args = new Args(); + return args; + } +- void parse_args(int argc, const char** argv); ++ void parse_args(int argc, char** argv); + + inline void set_flag(unsigned int flag) { flags |= flag; } + +@@ -56,7 +56,7 @@ class Args { + + private: + uint32_t flags = FLAG_NONE; +- void copy_cmdline(int argc, const char** argv); ++ void copy_cmdline(int argc, char** argv); + char** new_argv; + int new_argc; + }; +@@ -69,9 +69,7 @@ class Launcher { + AglShellPanelEdge panel_edge, + int width, + int height) = 0; +- virtual int Loop(int argc, +- const char** argv, +- volatile sig_atomic_t& e_flag) = 0; ++ virtual int Loop(int argc, char** argv, volatile sig_atomic_t& e_flag) = 0; + }; + + class SharedBrowserProcessWebAppLauncher : public Launcher { +@@ -82,7 +80,7 @@ class SharedBrowserProcessWebAppLauncher : public Launcher { + AglShellPanelEdge panel_edge, + int width, + int height) override; +- int Loop(int argc, const char** argv, volatile sig_atomic_t& e_flag) override; ++ int Loop(int argc, char** argv, volatile sig_atomic_t& e_flag) override; + }; + + class SingleBrowserProcessWebAppLauncher : public Launcher { +@@ -93,12 +91,12 @@ class SingleBrowserProcessWebAppLauncher : public Launcher { + AglShellPanelEdge panel_edge, + int width, + int height) override; +- int Loop(int argc, const char** argv, volatile sig_atomic_t& e_flag) override; ++ int Loop(int argc, char** argv, volatile sig_atomic_t& e_flag) override; + }; + + class WebAppLauncherRuntime : public WebRuntime { + public: +- int Run(int argc, const char** argv) override; ++ int Run(int argc, char** argv) override; + + private: + bool Init(Args* args); +@@ -127,17 +125,17 @@ class WebAppLauncherRuntime : public WebRuntime { + + class SharedBrowserProcessRuntime : public WebRuntime { + public: +- int Run(int argc, const char** argv) override; ++ int Run(int argc, char** argv) override; + }; + + class RenderProcessRuntime : public WebRuntime { + public: +- int Run(int argc, const char** argv) override; ++ int Run(int argc, char** argv) override; + }; + + class WebRuntimeAGL : public WebRuntime { + public: +- int Run(int argc, const char** argv) override; ++ int Run(int argc, char** argv) override; + + private: + WebRuntime* runtime_; +diff --git a/src/cef/cli/CMakeLists.txt b/src/cef/cli/CMakeLists.txt +new file mode 100644 +index 0000000..1b5f04a +--- /dev/null ++++ b/src/cef/cli/CMakeLists.txt +@@ -0,0 +1,17 @@ ++project(WebAppMgrCli VERSION 1.0.0 DESCRIPTION "Web Application Manager cli helper") ++ ++set(CLI_EXE ${PROJECT_NAME}) ++set(CLI_EXE_INCLUDE_DIRS ++ ${WAM_ROOT_SOURCE_DIR}/util ++) ++ ++set(CLI_EXE_LIBS ++ WebAppMgrCore ++ WebAppMgrService ++ WebAppMgrService-grpc ++) ++ ++add_executable(${CLI_EXE} wam_cli.cc) ++target_include_directories(${CLI_EXE} PUBLIC ${CLI_EXE_INCLUDE_DIRS}) ++target_link_libraries(${CLI_EXE} PUBLIC ${CLI_EXE_LIBS}) ++install(TARGETS ${CLI_EXE} DESTINATION ${CMAKE_INSTALL_BINDIR}) +diff --git a/src/cef/cli/wam_cli.cc b/src/cef/cli/wam_cli.cc +new file mode 100644 +index 0000000..4775ce4 +--- /dev/null ++++ b/src/cef/cli/wam_cli.cc +@@ -0,0 +1,171 @@ ++// Copyright (c) 2018-2022 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#include <getopt.h> ++#include <optional> ++ ++#include "web_app_manager_client_grpc.h" ++ ++#include "log_manager.h" ++ ++class Args { ++ public: ++ enum flags { ++ FLAG_NONE = 0, ++ FLAG_APP_TYPE = 1 << 0, ++ FLAG_ACTIVATE_APP = 1 << 1, ++ FLAG_HTTP_LINK = 1 << 2, ++ FLAG_APP_ID = 1 << 3, ++ FLAG_APP_DIR = 1 << 4, ++ }; ++ ++ static Args* Instance() { ++ static Args* args = new Args(); ++ return args; ++ } ++ void PrintHelp(void) { ++ fprintf(stderr, "WAM: Web Application Manager\n"); ++ fprintf(stderr, ++ "\t[--activate_app=appid] -- activate application. Interrnal " ++ "usage.\n\tNot needing for starting applications.\n"); ++ fprintf(stderr, ++ "\t[--appid=appid] name of an application id.\n\tRequired if " ++ "starting a " ++ "web application.\n"); ++ fprintf( ++ stderr, ++ "\t[--app-install-dir=/path/to/root_index] installation path for web " ++ "application.\n\tRequired if starting a web application.\n"); ++ fprintf(stderr, "\t-h -- this help message \n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ void ParseArgs(int argc, char** argv) { ++ int c; ++ int option_index; ++ opterr = 0; ++ ++ CopyCmdLine(argc, argv); ++ ++ struct option long_opts[] = {{"help", no_argument, 0, 'h'}, ++ {"activate-app", required_argument, 0, 'x'}, ++ {"appid", required_argument, 0, 'a'}, ++ {"app-install-dir", required_argument, 0, 'd'}, ++ {0, 0, 0, 0}}; ++ ++ while ((c = getopt_long(new_argc, new_argv, "ht:a:i:d:", long_opts, ++ &option_index)) != -1) { ++ switch (c) { ++ case 'h': ++ PrintHelp(); ++ break; ++ case 'x': ++ activate_app_id_ = optarg; ++ break; ++ case 'a': ++ app_id_ = optarg; ++ break; ++ case 'd': ++ app_dir_ = optarg; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ if (optind < new_argc) { ++ // check for 'http://' ++ int p = optind; ++ while (p < new_argc) { ++ if (!strcmp(new_argv[p], "http://")) { ++ http_link_ = new_argv[p]; ++ break; ++ } ++ p++; ++ } ++ } ++ } ++ ++ void ClearCmdLine() { ++ for (int i = 0; i < new_argc; i++) ++ free(new_argv[i]); ++ free(new_argv); ++ } ++ ++ std::string GetAppId() const { ++ return app_id_.has_value() ? *app_id_ : std::string(); ++ } ++ ++ std::string GetAppUri() const { ++ if (http_link_.has_value()) ++ return *http_link_; ++ else if (app_dir_.has_value()) ++ return *app_dir_; ++ return std::string(); ++ } ++ ++ bool HasActivateAppId() const { return activate_app_id_.has_value(); } ++ std::string GetActivateAppId() const { ++ return activate_app_id_.has_value() ? *activate_app_id_ : std::string(); ++ } ++ ++ private: ++ void CopyCmdLine(int argc, char** argv) { ++ new_argc = argc; ++ new_argv = static_cast<char**>(calloc(new_argc + 1, sizeof(*new_argv))); ++ ++ for (int i = 0; i < new_argc; i++) { ++ size_t len = strlen(argv[i]) + 1; ++ new_argv[i] = static_cast<char*>(calloc(len, sizeof(char))); ++ memcpy(new_argv[i], argv[i], len); ++ } ++ ++ new_argv[argc] = nullptr; ++ } ++ char** new_argv; ++ int new_argc; ++ ++ std::optional<std::string> activate_app_id_; ++ std::optional<std::string> http_link_; ++ std::optional<std::string> app_id_; ++ std::optional<std::string> app_dir_; ++}; ++ ++WebAppManagerClientGRPC* GetGrpcClient() { ++ static std::unique_ptr<WebAppManagerClientGRPC> grpc_client; ++ if (!grpc_client) { ++ grpc_client = std::make_unique<WebAppManagerClientGRPC>(); ++ } ++ return grpc_client.get(); ++} ++ ++int main(int argc, char** argv) { ++ auto* args = Args::Instance(); ++ args->ParseArgs(argc, argv); ++ ++ // TODO: handle completed grpc calls ++ // and get the correct ok() result ++ if (args->HasActivateAppId()) { ++ GetGrpcClient()->Activate(args->GetActivateAppId()); ++ } else { ++ WebAppManagerClientGRPC::LaunchParams params; ++ params.app_id = args->GetAppId(); ++ params.uri = args->GetAppUri(); ++ GetGrpcClient()->Launch(params); ++ } ++ ++ return 0; ++} +diff --git a/src/cef/device_info_cef.cc b/src/cef/device_info_cef.cc +new file mode 100644 +index 0000000..f5fd681 +--- /dev/null ++++ b/src/cef/device_info_cef.cc +@@ -0,0 +1,104 @@ ++#include "device_info_cef.h" ++ ++#include <string> ++ ++#include <glib.h> ++#include <json/value.h> ++ ++#include "log_manager.h" ++#include "utils.h" ++ ++DeviceInfoCEF::DeviceInfoCEF() = default; ++ ++void DeviceInfoCEF::Initialize() { ++ const std::string& json_string = ++ util::ReadFile("/var/luna/preferences/localeInfo"); ++ if (json_string.empty()) { ++ return; ++ } ++ ++ Json::Value locale_json = util::StringToJson(json_string); ++ if (!locale_json.isObject() || locale_json.empty() || ++ !locale_json["localeInfo"].isObject() || ++ !locale_json["localeInfo"]["locales"].isObject() || ++ !locale_json["localeInfo"]["locales"]["UI"].isString() || ++ !locale_json["country"].isString() || ++ !locale_json["smartServiceCountryCode3"].isString()) { ++ LOG_ERROR(MSGID_LOCALEINFO_READ_FAIL, 1, ++ PMLOGKS("CONTENT", json_string.c_str()), ""); ++ return; ++ } ++ ++ Json::Value locale_info = locale_json["localeInfo"]; ++ ++ std::string language(locale_info["locales"]["UI"].asString()); ++ std::string localcountry(locale_json["country"].asString()); ++ std::string smartservicecountry( ++ locale_json["smartServiceCountryCode3"].asString()); ++ ++ SetSystemLanguage(language.c_str()); ++ SetDeviceInfo("LocalCountry", localcountry.c_str()); ++ SetDeviceInfo("SmartServiceCountry", smartservicecountry.c_str()); ++} ++ ++void DeviceInfoCEF::InitDisplayInfo() { ++ // Display information ++ // -------------------------------------------------------- ++ float screen_density_ = 1.0f; ++ int hardware_screen_width = 0; ++ int hardware_screen_height = 0; ++ ++ std::string hardware_screen_width_str; ++ std::string hardware_screen_height_str; ++ if (GetDeviceInfo("HardwareScreenWidth", hardware_screen_width_str) && ++ GetDeviceInfo("HardwareScreenHeight", hardware_screen_height_str)) { ++ hardware_screen_width = ++ util::StrToIntWithDefault(hardware_screen_width_str, 0); ++ hardware_screen_height = ++ util::StrToIntWithDefault(hardware_screen_height_str, 0); ++ } else { ++ GetDisplayWidth(hardware_screen_width); ++ GetDisplayHeight(hardware_screen_height); ++ } ++ ++ screen_width_ = static_cast<int>(hardware_screen_width / screen_density_); ++ screen_height_ = static_cast<int>(hardware_screen_height / screen_density_); ++} ++ ++void DeviceInfoCEF::InitPlatformInfo() { ++ // normally like this info ++ /* ++ "modelName": "WEBOS1", ++ "platformVersion": "00.00.00", ++ "platformVersionDot": 00, ++ "platformVersionMajor_pos": 00, ++ "platformVersionMinor": 00, ++ */ ++ ++ std::string value; ++ if (GetDeviceInfo("ModelName", value)) ++ model_name_ = value; ++ if (GetDeviceInfo("FirmwareVersion", value)) ++ platform_version_ = value; ++ ++ size_t major_pos = 0, minor_pos = 0; ++ major_pos = platform_version_.find_first_of('.'); ++ if (major_pos != std::string::npos && ++ major_pos <= platform_version_.size() - 1) ++ minor_pos = platform_version_.find_first_of('.', major_pos + 1); ++ if (major_pos == std::string::npos || minor_pos == std::string::npos) { ++ version_major_ = version_minor_ = version_dot_ = -1; ++ } else { ++ version_major_ = ++ util::StrToIntWithDefault(platform_version_.substr(0, major_pos), 0); ++ version_minor_ = util::StrToIntWithDefault( ++ platform_version_.substr(major_pos + 1, minor_pos), 0); ++ version_dot_ = ++ util::StrToIntWithDefault(platform_version_.substr(minor_pos + 1), 0); ++ } ++} ++ ++void DeviceInfoCEF::GatherInfo() { ++ InitDisplayInfo(); ++ InitPlatformInfo(); ++} +diff --git a/src/cef/device_info_cef.h b/src/cef/device_info_cef.h +new file mode 100644 +index 0000000..e2b3712 +--- /dev/null ++++ b/src/cef/device_info_cef.h +@@ -0,0 +1,38 @@ ++#ifndef CEF_DEVICE_INFO_CEF_H_ ++#define CEF_DEVICE_INFO_CEF_H_ ++ ++#include <string> ++ ++#include "device_info.h" ++ ++class DeviceInfoCEF : public DeviceInfo { ++ public: ++ DeviceInfoCEF(); ++ ++ void Initialize() override; ++ ++ private: ++ int screen_width_ = 0; ++ int screen_height_ = 0; ++ ++ float screen_density_ = 1.0f; ++ ++ std::string model_name_ = "webOS.Open.CEF"; ++ std::string platform_version_ = "00.00.00"; ++ ++ // platform versions are <major>.<minor>.<dot> ++ int version_major_ = 0; ++ int version_minor_ = 0; ++ int version_dot_ = 0; ++ ++ bool support_3d_ = false; ++ std::string ota_id_; ++ std::string hardware_version_ = "0x00000001"; ++ std::string firmware_version_ = "00.00.01"; ++ ++ void InitDisplayInfo(); ++ void InitPlatformInfo(); ++ void GatherInfo(); ++}; ++ ++#endif // CEF_DEVICE_INFO_IMPL_H_ +diff --git a/src/cef/handlers/wam_cef_browser_handler.cc b/src/cef/handlers/wam_cef_browser_handler.cc +new file mode 100644 +index 0000000..0708363 +--- /dev/null ++++ b/src/cef/handlers/wam_cef_browser_handler.cc +@@ -0,0 +1,31 @@ ++#include "wam_cef_browser_handler.h" ++ ++#include "log_manager.h" ++#include "log_msg_id.h" ++#include "platform_module_factory_cef.h" ++#include "wam_cef_client.h" ++#include "web_app_manager_service_grpc.h" ++ ++WamCefBrowserHandler::WamCefBrowserHandler() : ++ client_(new WamCefClient()) { ++ WebAppManager::Instance()->SetPlatformModules( ++ std::make_unique<PlatformModuleFactoryCEF>()); ++} ++ ++WamCefBrowserHandler::~WamCefBrowserHandler() {} ++ ++CefRefPtr<CefBrowserProcessHandler> WamCefBrowserHandler::GetBrowserProcessHandler() { ++ return this; ++} ++ ++CefRefPtr<CefClient> WamCefBrowserHandler::GetDefaultClient() { ++ return client_; ++} ++ ++void WamCefBrowserHandler::OnContextInitialized() { ++ if (!WebAppManagerServiceGRPC::Instance()->InitializeAsHostService()) { ++ LOG_ERROR(MSGID_ERROR_CANNOT_LOCK_SERVICE, 0, ++ "Cannot lock WAM GRPC service IPC"); ++ } ++ WebAppManagerServiceGRPC::Instance()->StartService(); ++} +diff --git a/src/cef/handlers/wam_cef_browser_handler.h b/src/cef/handlers/wam_cef_browser_handler.h +new file mode 100644 +index 0000000..58c7f20 +--- /dev/null ++++ b/src/cef/handlers/wam_cef_browser_handler.h +@@ -0,0 +1,23 @@ ++#ifndef CEF_HANDLERS_WAM_CEF_BROWSER_HANDLER_H ++#define CEF_HANDLERS_WAM_CEF_BROWSER_HANDLER_H ++ ++#include "include/cef_app.h" ++#include "include/cef_browser_process_handler.h" ++ ++#include "wam_cef_client.h" ++ ++class WamCefBrowserHandler : public CefApp, public CefBrowserProcessHandler { ++ public: ++ WamCefBrowserHandler(); ++ virtual ~WamCefBrowserHandler(); ++ ++ CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() override; ++ CefRefPtr<CefClient> GetDefaultClient() override; ++ void OnContextInitialized() override; ++ ++ private: ++ IMPLEMENT_REFCOUNTING(WamCefBrowserHandler); ++ CefRefPtr<WamCefClient> client_; ++}; ++ ++#endif // CEF_HANDLERS_WAM_CEF_BROWSER_HANDLER_H +diff --git a/src/cef/handlers/wam_cef_client.cc b/src/cef/handlers/wam_cef_client.cc +new file mode 100644 +index 0000000..5ba6201 +--- /dev/null ++++ b/src/cef/handlers/wam_cef_client.cc +@@ -0,0 +1,39 @@ ++#include "wam_cef_client.h" ++ ++#include "include/wrapper/cef_helpers.h" ++ ++WamCefClient* g_instance = nullptr; ++ ++WamCefClient::WamCefClient() { ++ DCHECK(!g_instance); ++ g_instance = this; ++} ++ ++// static ++WamCefClient* WamCefClient::GetInstance() { ++ return g_instance; ++} ++ ++bool WamCefClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, ++ CefRefPtr<CefFrame> frame, ++ CefProcessId source_process, ++ CefRefPtr<CefProcessMessage> message) { ++ std::string message_name = message->GetName(); ++ CefRefPtr<CefListValue> args = message->GetArgumentList(); ++ if (message_name == "start") { ++ if (args->GetSize() != 1) { ++ return false; ++ } ++ std::string app_id = args->GetString(0); ++ applauncher_.Start(app_id); ++ return true; ++ } else if (message_name == "get_applications") { ++ if (args->GetSize() != 1) { ++ return false; ++ } ++ bool only_graphical = args->GetBool(0); ++ applauncher_.GetApplications(browser, only_graphical); ++ return true; ++ } ++ return false; ++} +diff --git a/src/cef/handlers/wam_cef_client.h b/src/cef/handlers/wam_cef_client.h +new file mode 100644 +index 0000000..3189c42 +--- /dev/null ++++ b/src/cef/handlers/wam_cef_client.h +@@ -0,0 +1,31 @@ ++#ifndef CEF_HANDLERS_WAM_CEF_CLIENT_H ++#define CEF_HANDLERS_WAM_CEF_CLIENT_H ++ ++#include "include/cef_client.h" ++ ++#include "applauncher_client_grpc.h" ++ ++class WamCefClient : public CefClient, ++ public CefLifeSpanHandler { ++ public: ++ WamCefClient(); ++ ++ static WamCefClient* GetInstance(); ++ ++ CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { ++ return this; ++ } ++ ++ bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, ++ CefRefPtr<CefFrame> frame, ++ CefProcessId source_process, ++ CefRefPtr<CefProcessMessage> message) override; ++ ++ private: ++ AppLauncherClientGRPC applauncher_; ++ ++ IMPLEMENT_REFCOUNTING(WamCefClient); ++ DISALLOW_COPY_AND_ASSIGN(WamCefClient); ++}; ++ ++#endif // CEF_HANDLERS_WAM_CEF_CLIENT_H +diff --git a/src/cef/handlers/wam_cef_render_handler.cc b/src/cef/handlers/wam_cef_render_handler.cc +new file mode 100644 +index 0000000..48c881a +--- /dev/null ++++ b/src/cef/handlers/wam_cef_render_handler.cc +@@ -0,0 +1,135 @@ ++#include "wam_cef_render_handler.h" ++ ++#include "include/cef_parser.h" ++#include "include/cef_process_message.h" ++ ++WamCefRenderHandler::WamCefRenderHandler() {} ++ ++void WamCefRenderHandler::OnContextCreated(CefRefPtr<CefBrowser> browser, ++ CefRefPtr<CefFrame> frame, ++ CefRefPtr<CefV8Context> context) { ++ ++ CefRefPtr<CefV8Value> app_service = CefV8Value::CreateObject(nullptr, nullptr); ++ ++ CefRefPtr<CefV8Value> start = CefV8Value::CreateFunction("start", this); ++ app_service->SetValue("start", start, V8_PROPERTY_ATTRIBUTE_NONE); ++ ++ CefRefPtr<CefV8Value> get_applications = CefV8Value::CreateFunction("getApplications", this); ++ app_service->SetValue("getApplications", get_applications, V8_PROPERTY_ATTRIBUTE_NONE); ++ ++ CefRefPtr<CefV8Value> global = context->GetGlobal(); // window object ++ CefRefPtr<CefV8Value> navigator = global->GetValue("navigator"); ++ ++ navigator->SetValue("appService", app_service, V8_PROPERTY_ATTRIBUTE_NONE); ++} ++ ++void WamCefRenderHandler::OnContextReleased(CefRefPtr<CefBrowser> browser, ++ CefRefPtr<CefFrame> frame, ++ CefRefPtr<CefV8Context> context) { ++ if (callback_map_.empty()) { ++ return; ++ } ++ ++ CallbackMap::iterator it = callback_map_.begin(); ++ for (; it != callback_map_.end();) { ++ if (it->second.first->IsSame(context)) { ++ callback_map_.erase(it++); ++ } else { ++ ++it; ++ } ++ } ++} ++ ++void WamCefRenderHandler::Start(const std::string &app_id) { ++ CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create("start"); ++ CefRefPtr<CefListValue> args = message->GetArgumentList(); ++ args->SetString(0, app_id); ++ auto context = CefV8Context::GetCurrentContext(); ++ context->GetFrame()->SendProcessMessage(PID_BROWSER, message); ++} ++ ++void WamCefRenderHandler::GetApplications(bool only_graphical, CefRefPtr<CefV8Value> callback) { ++ std::string message_name = "get_applications"; ++ ++ // store the callback until we receive the browser's response ++ CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext(); ++ int browser_id = context->GetBrowser()->GetIdentifier(); ++ callback_map_.insert( ++ std::make_pair(std::make_pair(message_name, browser_id), ++ std::make_pair(context, callback))); ++ ++ CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create(message_name); ++ CefRefPtr<CefListValue> args = message->GetArgumentList(); ++ args->SetBool(0, only_graphical); ++ context->GetFrame()->SendProcessMessage(PID_BROWSER, message); ++} ++ ++bool WamCefRenderHandler::Execute(const CefString& name, ++ CefRefPtr<CefV8Value> object, ++ const CefV8ValueList& arguments, ++ CefRefPtr<CefV8Value>& retval, ++ CefString& exception) { ++ if (name == "start") { ++ if (arguments.size() != 1 || !arguments[0]->IsString()) { ++ return false; ++ } ++ std::string app_id = arguments[0]->GetStringValue(); ++ Start(app_id); ++ return true; ++ } else if (name == "getApplications") { ++ if (arguments.size() != 2 || ++ !arguments[0]->IsBool() || ++ !arguments[1]->IsFunction()) { ++ return false; ++ } ++ GetApplications(arguments[0]->GetBoolValue(), arguments[1]); ++ return true; ++ } ++ ++ return false; ++} ++ ++bool WamCefRenderHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, ++ CefRefPtr<CefFrame> frame, ++ CefProcessId source_process, ++ CefRefPtr<CefProcessMessage> message) { ++ std::string message_name = message->GetName(); ++ CefRefPtr<CefListValue> args = message->GetArgumentList(); ++ if (message_name == "get_applications") { ++ CallbackMap::const_iterator it = callback_map_.find( ++ std::make_pair(message_name, ++ browser->GetIdentifier())); ++ if (it == callback_map_.end()) { ++ return false; ++ } ++ ++ CefRefPtr<CefV8Context> context = it->second.first; ++ CefRefPtr<CefV8Value> callback = it->second.second; ++ ++ context->Enter(); ++ ++ CefRefPtr<CefValue> apps_list_value = CefParseJSON(args->GetString(0), JSON_PARSER_RFC); ++ ++ CefRefPtr<CefListValue> list = apps_list_value->GetList(); ++ int size = list->GetSize(); ++ CefRefPtr<CefV8Value> apps_list = CefV8Value::CreateArray(size); ++ for (int i = 0; i < size; i++) { ++ CefRefPtr<CefDictionaryValue> app_info_dict = list->GetDictionary(i); ++ CefRefPtr<CefV8Value> dict = CefV8Value::CreateObject(nullptr, nullptr); ++ dict->SetValue("id", CefV8Value::CreateString(app_info_dict->GetString("id")), V8_PROPERTY_ATTRIBUTE_NONE); ++ dict->SetValue("name", CefV8Value::CreateString(app_info_dict->GetString("name")), V8_PROPERTY_ATTRIBUTE_NONE); ++ dict->SetValue("icon", CefV8Value::CreateString(app_info_dict->GetString("icon")), V8_PROPERTY_ATTRIBUTE_NONE); ++ apps_list->SetValue(i, dict); ++ } ++ ++ CefV8ValueList arguments; ++ arguments.push_back(apps_list); ++ callback->ExecuteFunctionWithContext(context, nullptr, arguments); ++ ++ context->Exit(); ++ ++ return true; ++ } ++ ++ return false; ++} +diff --git a/src/cef/handlers/wam_cef_render_handler.h b/src/cef/handlers/wam_cef_render_handler.h +new file mode 100644 +index 0000000..4a05ed6 +--- /dev/null ++++ b/src/cef/handlers/wam_cef_render_handler.h +@@ -0,0 +1,54 @@ ++#ifndef CEF_HANDLERS_WAM_CEF_RENDER_HANDLER_H ++#define CEF_HANDLERS_WAM_CEF_RENDER_HANDLER_H ++ ++#include <map> ++#include <string> ++ ++#include "include/cef_app.h" ++#include "include/cef_render_process_handler.h" ++#include "include/cef_v8.h" ++ ++class WamCefRenderHandler : public CefApp, ++ public CefRenderProcessHandler, ++ public CefV8Handler { ++ public: ++ typedef std::map<std::pair<std::string, int>, ++ std::pair<CefRefPtr<CefV8Context>, CefRefPtr<CefV8Value>>> CallbackMap; ++ ++ WamCefRenderHandler(); ++ ++ CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() override { ++ return this; ++ } ++ ++ void OnContextCreated(CefRefPtr<CefBrowser> browser, ++ CefRefPtr<CefFrame> frame, ++ CefRefPtr<CefV8Context> context) override; ++ ++ ++ void OnContextReleased(CefRefPtr<CefBrowser> browser, ++ CefRefPtr<CefFrame> frame, ++ CefRefPtr<CefV8Context> context) override; ++ ++ bool Execute(const CefString& name, ++ CefRefPtr<CefV8Value> object, ++ const CefV8ValueList& arguments, ++ CefRefPtr<CefV8Value>& retval, ++ CefString& exception) override; ++ ++ bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, ++ CefRefPtr<CefFrame> frame, ++ CefProcessId source_process, ++ CefRefPtr<CefProcessMessage> message) override; ++ ++ void Start(const std::string &app_id); ++ void GetApplications(bool only_graphical, CefRefPtr<CefV8Value> callback); ++ ++ private: ++ IMPLEMENT_REFCOUNTING(WamCefRenderHandler); ++ DISALLOW_COPY_AND_ASSIGN(WamCefRenderHandler); ++ ++ CallbackMap callback_map_; ++}; ++ ++#endif // CEF_HANDLERS_WAM_CEF_RENDER_HANDLER_H +diff --git a/src/cef/platform_module_factory_cef.cc b/src/cef/platform_module_factory_cef.cc +new file mode 100644 +index 0000000..e225b9d +--- /dev/null ++++ b/src/cef/platform_module_factory_cef.cc +@@ -0,0 +1,31 @@ ++#include "platform_module_factory_cef.h" ++ ++#include "device_info_cef.h" ++#include "service_sender.h" ++#include "web_app_manager_config.h" ++#include "web_process_manager.h" ++ ++PlatformModuleFactoryCEF::PlatformModuleFactoryCEF() { ++ PrepareRenderingContext(); ++} ++ ++std::unique_ptr<ServiceSender> ++PlatformModuleFactoryCEF::CreateServiceSender() { ++ return nullptr; ++} ++ ++std::unique_ptr<WebProcessManager> ++PlatformModuleFactoryCEF::CreateWebProcessManager() { ++ return nullptr; ++} ++ ++std::unique_ptr<DeviceInfo> PlatformModuleFactoryCEF::CreateDeviceInfo() { ++ return std::make_unique<DeviceInfoCEF>(); ++} ++ ++std::unique_ptr<WebAppManagerConfig> ++PlatformModuleFactoryCEF::CreateWebAppManagerConfig() { ++ return std::unique_ptr<WebAppManagerConfig>(new WebAppManagerConfig()); ++} ++ ++void PlatformModuleFactoryCEF::PrepareRenderingContext() {} +diff --git a/src/cef/platform_module_factory_cef.h b/src/cef/platform_module_factory_cef.h +new file mode 100644 +index 0000000..5015dda +--- /dev/null ++++ b/src/cef/platform_module_factory_cef.h +@@ -0,0 +1,27 @@ ++#ifndef CEF_PLATFORM_MODULE_FACTORY_CEF_H_ ++#define CEF_PLATFORM_MODULE_FACTORY_CEF_H_ ++ ++#include <memory> ++ ++#include "platform_module_factory.h" ++ ++class ServiceSender; ++class WebProcessManager; ++class DeviceInfo; ++class WebAppManagerConfig; ++ ++class PlatformModuleFactoryCEF : public PlatformModuleFactory { ++ public: ++ PlatformModuleFactoryCEF(); ++ ++ protected: ++ std::unique_ptr<ServiceSender> CreateServiceSender() override; ++ std::unique_ptr<WebProcessManager> CreateWebProcessManager() override; ++ std::unique_ptr<DeviceInfo> CreateDeviceInfo() override; ++ std::unique_ptr<WebAppManagerConfig> CreateWebAppManagerConfig() override; ++ ++ private: ++ void PrepareRenderingContext(); ++}; ++ ++#endif // CEF_PLATFORM_MODULE_FACTORY_CEF_H_ +diff --git a/src/cef/plugin/web_app_cef.cc b/src/cef/plugin/web_app_cef.cc +new file mode 100644 +index 0000000..f57212b +--- /dev/null ++++ b/src/cef/plugin/web_app_cef.cc +@@ -0,0 +1,172 @@ ++#include "web_app_cef.h" ++ ++#include "include/base/cef_callback.h" ++#include "include/views/cef_display.h" ++#include "include/wrapper/cef_closure_task.h" ++ ++#include "web_page_cef.h" ++ ++WebAppCEF::WebAppCEF(std::shared_ptr<ApplicationDescription> app_desc) { ++ SetAppDescription(app_desc); ++} ++ ++WebAppCEF::~WebAppCEF() {} ++ ++void WebAppCEF::Init(int width, ++ int height, ++ AglShellSurfaceType surface_type, ++ AglShellPanelEdge panel_type) { ++ ApplicationDescription* app_desc = GetAppDescription(); ++ std::string app_id = app_desc->Id(); ++ ++ if (!IsReady()) { ++ return; ++ } ++ ++ surface_type_ = surface_type; ++ panel_type_ = panel_type; ++ ++ switch (surface_type_) { ++ case AglShellSurfaceType::kBackground: ++ window_->AglSetBackGroundApp(); ++ window_->AglSetAppReady(); ++ break; ++ case AglShellSurfaceType::kPanel: ++ window_->AglSetPanelApp(static_cast<int>(panel_type_)); ++ break; ++ case AglShellSurfaceType::kNone: ++ surface_type_ = AglShellSurfaceType::kNone; ++ CefPostDelayedTask( ++ TID_UI, ++ base::BindOnce(&WebAppCEF::DelayedActivate, this), ++ 500); ++ break; ++ } ++} ++ ++void WebAppCEF::TryInitialize() { ++ ApplicationDescription* app_desc = GetAppDescription(); ++ ++ if (!IsReady()) { ++ CefPostDelayedTask( ++ TID_UI, ++ base::BindOnce(&WebAppCEF::TryInitialize, this), ++ 500); ++ return; ++ // TODO: add a maximum number of retries ++ } ++ ++ Init(app_desc->WidthOverride(), ++ app_desc->HeightOverride(), ++ app_desc->SurfaceType(), ++ app_desc->PanelType()); ++} ++ ++void WebAppCEF::Attach(WebPageBase* web_page) { ++ WebAppBase::Attach(web_page); ++ ++ WebPageCEF* web_page_cef = static_cast<WebPageCEF*>(Page()); ++ if (!web_page_cef) { ++ // TODO: handle error ++ return; ++ } ++ web_page_cef->SetWebApp(this); ++} ++ ++void WebAppCEF::OnWindowCreated(CefRefPtr<CefWindow> window) { ++ if (!browser_view_) { ++ return; ++ } ++ ++ window_ = window; ++ window_->AddChildView(browser_view_); ++ window_->Show(); ++ ++ TryInitialize(); ++} ++ ++CefRect WebAppCEF::GetDisplayBounds() const { ++ CefRefPtr<CefDisplay> display = CefDisplay::GetPrimaryDisplay(); ++ CefRect display_bounds; ++ if (display) { ++ display_bounds = display->GetBounds(); ++ } ++ return display_bounds; ++} ++ ++CefSize WebAppCEF::GetPreferredSize(CefRefPtr<CefView> view) { ++ return CefSize(width_override_, height_override_); ++} ++ ++CefRect WebAppCEF::GetInitialBounds(CefRefPtr<CefWindow> window) { ++ return CefRect(0, 0, width_override_, height_override_); ++} ++ ++void WebAppCEF::SendAglReady() { ++ // Empty because it's called on Init() ++} ++ ++void WebAppCEF::SetAglAppId(const char* app_id) { ++ if (!window_) { ++ return; ++ } ++ window_->SetTitle(app_id); ++ window_->AglSetAppId(app_id); ++} ++ ++void WebAppCEF::SendAglActivate(const char* app_id) { ++ if (!window_) { ++ return; ++ } ++ window_->AglActivateApp(app_id); ++} ++ ++void WebAppCEF::Resize(int width, int height) { ++ if (!window_) { ++ return; ++ } ++ window_->SetSize(CefSize(width, height)); ++} ++ ++bool WebAppCEF::IsReady() const { ++ return window_ != nullptr; ++} ++ ++void WebAppCEF::Hide(bool forced_hide) { ++ if (!window_) { ++ return; ++ } ++ window_->Hide(); ++} ++ ++bool WebAppCEF::HideWindow() { ++ if (!window_) { ++ return false; ++ } ++ window_->Hide(); ++ return true; ++} ++ ++void WebAppCEF::Raise() { ++ if (!window_) { ++ return; ++ } ++ window_->BringToTop(); ++} ++ ++void WebAppCEF::DelayedActivate() { ++ ApplicationDescription* app_desc = GetAppDescription(); ++ SendAglActivate(app_desc->Id().c_str()); ++} ++ ++void WebAppCEF::Relaunch(const std::string& args, ++ const std::string& launching_app_id) { ++ if (!window_) { ++ return; ++ } ++ ++ ApplicationDescription* app_desc = GetAppDescription(); ++ std::string app_id = app_desc->Id(); ++ ++ SendAglActivate(app_id.c_str()); ++} +diff --git a/src/cef/plugin/web_app_cef.h b/src/cef/plugin/web_app_cef.h +new file mode 100644 +index 0000000..57145cf +--- /dev/null ++++ b/src/cef/plugin/web_app_cef.h +@@ -0,0 +1,95 @@ ++#ifndef CEF_PLUGIN_WEB_APP_CEF_H ++#define CEF_PLUGIN_WEB_APP_CEF_H ++ ++#include <cstdint> ++#include <memory> ++ ++#include "web_app_base.h" ++ ++#include "include/views/cef_window.h" ++#include "include/views/cef_browser_view.h" ++#include "include/views/cef_window_delegate.h" ++ ++#include "application_description.h" ++ ++class WebAppCEF : public WebAppBase, public CefWindowDelegate { ++ public: ++ WebAppCEF(std::shared_ptr<ApplicationDescription> app_desc); ++ ++ ~WebAppCEF(); ++ ++ virtual void Init(int width, ++ int height, ++ AglShellSurfaceType surface_type, ++ AglShellPanelEdge panel_type) override; ++ ++ void SuspendAppRendering() override {} ++ void ResumeAppRendering() override {} ++ bool IsFocused() const override { return false; } ++ void Resize(int width, int height) override; ++ bool IsActivated() const override { return false; } ++ bool IsMinimized() override { return false; } ++ bool IsNormal() override { return true; } ++ void OnStageActivated() override {} ++ void OnStageDeactivated() override {} ++ void DoAttach() override {} ++ void ConfigureWindow(const std::string& type) override {} ++ void SetWindowProperty(const std::string& name, ++ const std::string& value) override {} ++ void PlatformBack() override {} ++ void SetCursor(const std::string& cursor_arg, ++ int hotspot_x, ++ int hotspot_y) override {} ++ void SetInputRegion(const Json::Value& json_doc) override {} ++ void SetKeyMask(const Json::Value& json_doc) override {} ++ void Hide(bool forced_hide = false) override; ++ void Focus() override {} ++ void Unfocus() override {} ++ void SetOpacity(float opacity) override {} ++ void Raise() override; ++ void GoBackground() override {} ++ void DoPendingRelaunch() override {} ++ void DeleteSurfaceGroup() override {} ++ void DoClose() override {} ++ void SetUseVirtualKeyboard(const bool enable) override {} ++ bool HideWindow() override; ++ ++ void SendAglReady() override; ++ void SendAglActivate(const char* app_id) override; ++ void SetAglAppId(const char* app_id) override; ++ ++ void Attach(WebPageBase* web_page) override; ++ ++ void Relaunch(const std::string& args, ++ const std::string& launching_app_id) override; ++ ++ void SetBrowserView(CefRefPtr<CefBrowserView> browser_view) { ++ browser_view_ = browser_view; ++ } ++ ++ virtual bool IsReady() const; ++ ++ // CEF overrides ++ void OnWindowCreated(CefRefPtr<CefWindow> window) override; ++ CefSize GetPreferredSize(CefRefPtr<CefView> view) override; ++ CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override; ++ bool IsFrameless(CefRefPtr<CefWindow> window) override { return true; } ++ ++ protected: ++ void TryInitialize(); ++ void DelayedActivate(); ++ ++ CefRect GetDisplayBounds() const; ++ ++ CefRefPtr<CefBrowserView> browser_view_; ++ CefRefPtr<CefWindow> window_; ++ AglShellSurfaceType surface_type_; ++ AglShellPanelEdge panel_type_; ++ uint32_t width_override_ = 0; ++ uint32_t height_override_ = 0; ++ ++ private: ++ IMPLEMENT_REFCOUNTING(WebAppCEF); ++}; ++ ++#endif // CEF_PLUGIN_WEB_APP_CEF_H +diff --git a/src/cef/plugin/web_page_cef.cc b/src/cef/plugin/web_page_cef.cc +new file mode 100644 +index 0000000..32c6e89 +--- /dev/null ++++ b/src/cef/plugin/web_page_cef.cc +@@ -0,0 +1,48 @@ ++#include "web_page_cef.h" ++#include "application_description.h" ++ ++#include "include/views/cef_window.h" ++ ++#include "wam_cef_client.h" ++ ++WebPageCEF::WebPageCEF(std::shared_ptr<ApplicationDescription> app_desc, const std::string& url) ++ : url_{url} { ++ SetApplicationDescription(app_desc); ++} ++ ++WebPageCEF::~WebPageCEF() {} ++ ++void WebPageCEF::LoadUrl(const std::string& url) { ++ CefBrowserSettings browser_settings; ++ browser_view_ = CefBrowserView::CreateBrowserView( ++ WamCefClient::GetInstance(), url, browser_settings, nullptr, nullptr, this); ++ ++ web_app_->SetBrowserView(browser_view_); ++ ++ ApplicationDescription* app_desc = GetAppDescription(); ++ CefWindow::CreateTopLevelWindowWithId(web_app_, app_desc->Id()); ++} ++ ++void WebPageCEF::LoadDefaultUrl() { ++ LoadUrl(url_); ++} ++ ++bool WebPageCEF::HasBeenShown() const { ++ if (!web_app_) { ++ return false; ++ } ++ ++ return web_app_->IsReady(); ++} ++ ++ ++void WebPageCEF::EvaluateJavaScript(const std::string& jsCode) { ++ /*if (!browser_view_) { ++ return; ++ } ++ CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser(); ++ if (!browser) { ++ return; ++ } ++ browser->GetMainFrame()->ExecuteJavaScript(jsCode, url_, 0);*/ ++} +diff --git a/src/cef/plugin/web_page_cef.h b/src/cef/plugin/web_page_cef.h +new file mode 100644 +index 0000000..f62c223 +--- /dev/null ++++ b/src/cef/plugin/web_page_cef.h +@@ -0,0 +1,69 @@ ++#ifndef CEF_PLUGIN_WEB_PAGE_CEF_H ++#define CEF_PLUGIN_WEB_PAGE_CEF_H ++ ++#include <memory> ++ ++#include "web_page_base.h" ++#include "web_app_cef.h" ++ ++#include "include/views/cef_browser_view_delegate.h" ++ ++class WebPageCEF : public WebPageBase, ++ public CefBrowserViewDelegate { ++ public: ++ WebPageCEF(std::shared_ptr<ApplicationDescription> app_desc, const std::string& url); ++ ~WebPageCEF() override; ++ ++ void Init() override {} ++ void* GetWebContents() override { return nullptr; } ++ ++ wam::Url Url() const override { return wam::Url(""); } ++ std::string FailedUrl() const override { return ""; } ++ void LoadUrl(const std::string& url) override; ++ int Progress() const override { return 0; } ++ bool HasBeenShown() const override; ++ void SetPageProperties() override {} ++ void SetPreferredLanguages(const std::string& language) override {} ++ void SetDefaultFont(const std::string& font) override {} ++ void ReloadDefaultPage() override {} ++ void Reload() override {} ++ void SetVisibilityState(WebPageVisibilityState visibility_state) override {} ++ void SetFocus(bool focus) override {} ++ std::string Title() override { return ""; } ++ bool CanGoBack() override { return false; } ++ void CloseVkb() override {} ++ void HandleDeviceInfoChanged(const std::string& device_info) override {} ++ void EvaluateJavaScript(const std::string& jsCode) override; ++ void EvaluateJavaScriptInAllFrames(const std::string& js_code, ++ const char* method = {}) override {} ++ uint32_t GetWebProcessProxyID() override { return 0; } ++ uint32_t GetWebProcessPID() const override { return 0; } ++ void CreatePalmSystem(WebAppBase* app) override {} ++ ++ void SuspendWebPageAll() override {} ++ void ResumeWebPageAll() override {} ++ void SuspendWebPageMedia() override {} ++ void ResumeWebPageMedia() override {} ++ void ResumeWebPagePaintingAndJSExecution() override {} ++ void ForwardEvent(void* event) override {} ++ ++ void SuspendWebPagePaintingAndJSExecution() override {} ++ ++ void SetWebApp(CefRefPtr<WebAppCEF> web_app) { web_app_ = web_app; } ++ ++ protected: ++ void LoadDefaultUrl() override; ++ void AddUserScript(const std::string& script) override {} ++ void AddUserScriptUrl(const wam::Url& url) override {} ++ void LoadErrorPage(int error_code) override {} ++ void RecreateWebView() override {} ++ ++ private: ++ IMPLEMENT_REFCOUNTING(WebPageCEF); ++ ++ CefRefPtr<CefBrowserView> browser_view_; ++ CefRefPtr<WebAppCEF> web_app_; ++ std::string url_; ++}; ++ ++#endif // CEF_PLUGIN_WEB_PAGE_CEF_H +diff --git a/src/cef/service/CMakeLists.txt b/src/cef/service/CMakeLists.txt +new file mode 100644 +index 0000000..763b527 +--- /dev/null ++++ b/src/cef/service/CMakeLists.txt +@@ -0,0 +1,64 @@ ++project(WebAppMgrService VERSION 1.0.0 DESCRIPTION "Web Application Manager cli helper") ++ ++find_package(gRPC REQUIRED) ++find_program(GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin REQUIRED) ++find_package(Protobuf REQUIRED) ++find_package(Threads) ++ ++set(WAM_GRPC_LIB_NAME ${PROJECT_NAME}-grpc) ++set(APPLAUNCHER_LIB_NAME WamAppLauncher-grpc) ++ ++set(WAM_GRPC_LIBS ++ protobuf::libprotobuf ++ gRPC::grpc ++ gRPC::grpc++ ++ gRPC::grpc++_reflection ++) ++set(WAM_SERVICE_LIBS ++ ${WAM_GRPC_LIBS} ++ ${WAM_GRPC_LIB_NAME} ++ ${APPLAUNCHER_LIB_NAME} ++ libcef_lib ++ libcef_dll_wrapper ++) ++set(WAM_GRPC_INCLUDE_DIRS ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_BINARY_DIR} ++) ++set(WAM_SERVICE_INCLUDE_DIRS ++ ${CEF_INCLUDE_PATH} ++ ${WAM_ROOT_SOURCE_DIR}/core ++ ${WAM_ROOT_SOURCE_DIR}/util ++) ++set(SOURCES ++ applauncher_client_grpc.cc ++ web_app_manager_client_grpc.cc ++ web_app_manager_service_grpc.cc ++) ++set(HEADERS ++ applauncher_client_grpc.h ++ web_app_manager_client_grpc.h ++ web_app_manager_service_grpc.h ++) ++ ++ ++macro(add_wam_grpc_lib target proto) ++ add_library(${target} SHARED ${proto}) ++ target_include_directories(${target} PUBLIC ${WAM_GRPC_INCLUDE_DIRS}) ++ target_link_libraries(${target} PUBLIC ${WAM_GRPC_LIBS}) ++ set_target_properties(${target} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) ++ protobuf_generate(TARGET ${target} LANGUAGE cpp APPEND_PATH) ++ protobuf_generate(TARGET ${target} LANGUAGE grpc APPEND_PATH GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${GRPC_CPP_PLUGIN_EXECUTABLE}") ++ install(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++endmacro(add_wam_grpc_lib) ++ ++add_wam_grpc_lib(${WAM_GRPC_LIB_NAME} wam_ipc.proto) ++add_wam_grpc_lib(${APPLAUNCHER_LIB_NAME} applauncher.proto) ++ ++add_library(${PROJECT_NAME} SHARED ${HEADERS} ${SOURCES}) ++set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) ++add_dependencies(${PROJECT_NAME} ${WAM_GRPC_LIB_NAME}) ++target_include_directories(${PROJECT_NAME} PUBLIC ${WAM_SERVICE_INCLUDE_DIRS}) ++target_link_libraries(${PROJECT_NAME} PUBLIC ${WAM_SERVICE_LIBS}) ++install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +diff --git a/src/cef/service/applauncher.proto b/src/cef/service/applauncher.proto +new file mode 100644 +index 0000000..0b8e0fc +--- /dev/null ++++ b/src/cef/service/applauncher.proto +@@ -0,0 +1,50 @@ ++syntax = "proto3"; ++ ++package automotivegradelinux; ++ ++service AppLauncher { ++ rpc StartApplication(StartRequest) returns (StartResponse) {} ++ rpc ListApplications(ListRequest) returns (ListResponse) {} ++ rpc GetStatusEvents(StatusRequest) returns (stream StatusResponse) {} ++} ++ ++message StartRequest { ++ string id = 1; ++} ++ ++message StartResponse { ++ bool status = 1; ++ string message = 2; ++} ++ ++message ListRequest { ++} ++ ++message ListResponse { ++ repeated AppInfo apps = 1; ++} ++ ++message AppInfo { ++ string id = 1; ++ string name = 2; ++ string icon_path = 3; ++} ++ ++message StatusRequest { ++} ++ ++message AppStatus { ++ string id = 1; ++ string status = 2; ++} ++ ++// Future-proofing for e.g. potentially signaling a list refresh ++message LauncherStatus { ++} ++ ++message StatusResponse { ++ oneof status { ++ AppStatus app = 1; ++ LauncherStatus launcher = 2; ++ } ++} +diff --git a/src/cef/service/applauncher_client_grpc.cc b/src/cef/service/applauncher_client_grpc.cc +new file mode 100644 +index 0000000..f704742 +--- /dev/null ++++ b/src/cef/service/applauncher_client_grpc.cc +@@ -0,0 +1,58 @@ ++#include "applauncher_client_grpc.h" ++ ++#include <grpcpp/ext/proto_server_reflection_plugin.h> ++#include <grpcpp/grpcpp.h> ++#include <grpcpp/health_check_service_interface.h> ++ ++#include "include/cef_parser.h" ++ ++AppLauncherClientGRPC::AppLauncherClientGRPC() ++ : stub_{MakeStub()} { ++} ++ ++std::unique_ptr<automotivegradelinux::AppLauncher::Stub>AppLauncherClientGRPC::MakeStub() const { ++ return automotivegradelinux::AppLauncher::NewStub(grpc::CreateChannel("localhost:50052", ++ grpc::InsecureChannelCredentials())); ++} ++ ++void AppLauncherClientGRPC::Start(const std::string& app_id) { ++ automotivegradelinux::StartRequest request; ++ request.set_id(app_id); ++ ++ grpc::ClientContext context; ++ automotivegradelinux::StartResponse response; ++ ++ grpc::Status status = stub_->StartApplication(&context, request, &response); ++} ++ ++void AppLauncherClientGRPC::GetApplications(CefRefPtr<CefBrowser> browser, bool only_graphical) { ++ automotivegradelinux::ListRequest request; ++ automotivegradelinux::ListResponse response; ++ grpc::ClientContext context; ++ ++ grpc::Status status = stub_->ListApplications(&context, request, &response); ++ if (!status.ok()) { ++ return; ++ } ++ ++ CefRefPtr<CefListValue> apps_list = CefListValue::Create(); ++ for (int i = 0; i < response.apps_size(); i++) { ++ automotivegradelinux::AppInfo app_info = response.apps(i); ++ CefRefPtr<CefDictionaryValue> app_info_dict = CefDictionaryValue::Create(); ++ app_info_dict->SetString("id", app_info.id()); ++ app_info_dict->SetString("name", app_info.name()); ++ app_info_dict->SetString("icon", app_info.icon_path()); ++ apps_list->SetDictionary(i, app_info_dict); ++ } ++ ++ CefRefPtr<CefValue> apps_list_value = CefValue::Create(); ++ apps_list_value->SetList(apps_list); ++ std::string response_string = CefWriteJSON(apps_list_value, JSON_WRITER_DEFAULT); ++ ++ // send the response to renderer process ++ CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create("get_applications"); ++ CefRefPtr<CefListValue> args = message->GetArgumentList(); ++ args->SetString(0, response_string); ++ browser->GetMainFrame()->SendProcessMessage(PID_RENDERER, message); ++} ++ +diff --git a/src/cef/service/applauncher_client_grpc.h b/src/cef/service/applauncher_client_grpc.h +new file mode 100644 +index 0000000..4a3f289 +--- /dev/null ++++ b/src/cef/service/applauncher_client_grpc.h +@@ -0,0 +1,24 @@ ++#ifndef CEF_SERVICE_APPLAUNCHER_CLIENT_GRPC_H ++#define CEF_SERVICE_APPLAUNCHER_CLIENT_GRPC_H ++ ++#include <string> ++ ++#include "applauncher.grpc.pb.h" ++ ++#include "include/cef_browser.h" ++ ++class AppLauncherClientGRPC { ++ public: ++ ++ AppLauncherClientGRPC(); ++ ++ void Start(const std::string& app_id); ++ void GetApplications(CefRefPtr<CefBrowser> browser, bool only_graphical); ++ ++ private: ++ std::unique_ptr<automotivegradelinux::AppLauncher::Stub> MakeStub() const; ++ ++ std::unique_ptr<automotivegradelinux::AppLauncher::Stub> stub_; ++}; ++ ++#endif // CEF_SERVICE_APPLAUNCHER_CLIENT_GRPC_H +diff --git a/src/cef/service/wam_ipc.proto b/src/cef/service/wam_ipc.proto +new file mode 100644 +index 0000000..313de8f +--- /dev/null ++++ b/src/cef/service/wam_ipc.proto +@@ -0,0 +1,22 @@ ++syntax = "proto3"; ++import "google/protobuf/empty.proto"; ++package wam_ipc; ++ ++service WebAppManagerService { ++ rpc Launch(LaunchRequest) returns (google.protobuf.Empty) {} ++ rpc Activate(ActivateRequest) returns (google.protobuf.Empty) {} ++ rpc Kill(KillRequest) returns (google.protobuf.Empty) {} ++} ++ ++message LaunchRequest { ++ string app_id = 1; ++ string uri = 2; ++} ++ ++message ActivateRequest { ++ string app_id = 1; ++} ++ ++message KillRequest { ++ string app_id = 1; ++} +diff --git a/src/cef/service/web_app_manager_client_grpc.cc b/src/cef/service/web_app_manager_client_grpc.cc +new file mode 100644 +index 0000000..8529868 +--- /dev/null ++++ b/src/cef/service/web_app_manager_client_grpc.cc +@@ -0,0 +1,42 @@ ++#include "web_app_manager_client_grpc.h" ++ ++#include <grpcpp/ext/proto_server_reflection_plugin.h> ++#include <grpcpp/grpcpp.h> ++#include <grpcpp/health_check_service_interface.h> ++ ++const char kDefaultGrpcServiceAddress[] = "127.0.0.1:15000"; ++ ++WebAppManagerClientGRPC::WebAppManagerClientGRPC() { ++ auto channel = grpc::CreateChannel(kDefaultGrpcServiceAddress, ++ grpc::InsecureChannelCredentials()); ++ stub_ = wam_ipc::WebAppManagerService::NewStub(channel); ++} ++ ++bool WebAppManagerClientGRPC::Launch(const LaunchParams& params) { ++ wam_ipc::LaunchRequest request; ++ request.set_app_id(params.app_id); ++ request.set_uri(params.uri); ++ ++ grpc::ClientContext context; ++ google::protobuf::Empty reply; ++ grpc::Status status = stub_->Launch(&context, request, &reply); ++ return status.ok(); ++} ++ ++bool WebAppManagerClientGRPC::Activate(const std::string& app_id) { ++ grpc::ClientContext context; ++ google::protobuf::Empty reply; ++ wam_ipc::ActivateRequest request; ++ request.set_app_id(app_id); ++ grpc::Status status = stub_->Activate(&context, request, &reply); ++ return status.ok(); ++} ++ ++bool WebAppManagerClientGRPC::Kill(const std::string& app_id) { ++ grpc::ClientContext context; ++ google::protobuf::Empty reply; ++ wam_ipc::KillRequest request; ++ request.set_app_id(app_id); ++ grpc::Status status = stub_->Kill(&context, request, &reply); ++ return status.ok(); ++} +diff --git a/src/cef/service/web_app_manager_client_grpc.h b/src/cef/service/web_app_manager_client_grpc.h +new file mode 100644 +index 0000000..9c4be70 +--- /dev/null ++++ b/src/cef/service/web_app_manager_client_grpc.h +@@ -0,0 +1,23 @@ ++#ifndef CEF_SERVICE_WEB_APP_MANAGER_CLIENT_GRPC_H ++#define CEF_SERVICE_WEB_APP_MANAGER_CLIENT_GRPC_H ++ ++#include "wam_ipc.grpc.pb.h" ++ ++class WebAppManagerClientGRPC { ++ public: ++ struct LaunchParams { ++ std::string app_id; ++ std::string uri; ++ }; ++ ++ WebAppManagerClientGRPC(); ++ bool Launch(const LaunchParams& params); ++ bool Activate(const std::string& app_id); ++ bool Kill(const std::string& app_id); ++ ++ private: ++ std::unique_ptr<wam_ipc::WebAppManagerService::Stub> stub_; ++}; ++ ++#endif // CEF_SERVICE_WEB_APP_MANAGER_CLIENT_GRPC_H ++ +diff --git a/src/cef/service/web_app_manager_service_grpc.cc b/src/cef/service/web_app_manager_service_grpc.cc +new file mode 100644 +index 0000000..52de924 +--- /dev/null ++++ b/src/cef/service/web_app_manager_service_grpc.cc +@@ -0,0 +1,382 @@ ++// Copyright (c) 2018-2022 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#include "web_app_manager_service_grpc.h" ++ ++#include <grpcpp/ext/proto_server_reflection_plugin.h> ++#include <grpcpp/grpcpp.h> ++#include <grpcpp/health_check_service_interface.h> ++#include <pthread.h> ++#include <sys/file.h> ++#include <sys/un.h> ++#include <unistd.h> ++#include <algorithm> ++#include <cassert> ++#include <climits> ++#include <cstdlib> ++#include <exception> ++#include <fstream> ++#include <iostream> ++#include <set> ++#include <sstream> ++ ++#include <json/value.h> ++ ++#include "log_manager.h" ++#include "utils.h" ++#include "wam_ipc.grpc.pb.h" ++#include "web_app_base.h" ++#include "web_app_manager.h" ++ ++namespace { ++const char kDefaultGrpcServiceAddress[] = "127.0.0.1:15000"; ++} // namespace ++ ++class WamIPCLockFile { ++ public: ++ WamIPCLockFile() { ++ const char* runtime_dir; ++ if ((runtime_dir = getenv("XDG_RUNTIME_DIR")) == NULL) { ++ LOG_DEBUG("Failed to retrieve XDG_RUNTIME_DIR, falling back to /tmp"); ++ runtime_dir = "/tmp"; ++ } ++ lock_file_ = std::string(runtime_dir); ++ lock_file_.append("/wamipc.lock"); ++ } ++ ++ ~WamIPCLockFile() { ++ if (lock_fd_ != -1) ++ ReleaseLock(lock_fd_); ++ if (lock_fd_ != -1) ++ close(lock_fd_); ++ } ++ ++ bool CreateAndLock() { ++ lock_fd_ = OpenLockFile(); ++ if (!AcquireLock(lock_fd_)) { ++ LOG_DEBUG("Failed to lock file %d", lock_fd_); ++ return false; ++ } ++ return true; ++ } ++ ++ bool OwnsLock() const { return lock_fd_ != -1; } ++ ++ bool TryAcquireLock() { ++ int fd = OpenLockFile(); ++ if (fd != -1) { ++ if (AcquireLock(fd)) { ++ ReleaseLock(fd); ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ private: ++ int OpenLockFile() { ++ int fd = open(lock_file_.c_str(), O_CREAT | O_TRUNC, S_IRWXU); ++ if (fd == -1) { ++ LOG_DEBUG("Failed to open lock file descriptor"); ++ return fd; ++ } ++ ++ int flags = fcntl(fd, F_GETFD); ++ if (flags == -1) ++ LOG_DEBUG("Could not get flags for lock file %d", fd); ++ ++ flags |= FD_CLOEXEC; ++ ++ if (fcntl(fd, F_SETFD, flags) == -1) ++ LOG_DEBUG("Could not set flags for lock file %d", fd); ++ ++ return fd; ++ } ++ ++ bool AcquireLock(int fd) { ++ if (flock(fd, LOCK_EX | LOCK_NB) != 0) ++ return false; ++ return true; ++ } ++ ++ void ReleaseLock(int fd) { flock(fd, LOCK_UN); } ++ ++ std::string lock_file_; ++ int lock_fd_ = -1; ++}; ++ ++class GrpcServiceImpl final ++ : public wam_ipc::WebAppManagerService::CallbackService { ++ grpc::ServerUnaryReactor* Launch(grpc::CallbackServerContext* context, ++ const ::wam_ipc::LaunchRequest* request, ++ google::protobuf::Empty* /*response*/) { ++ WebAppManagerServiceGRPC::LaunchParams launch_params; ++ launch_params.app_id = request->app_id(); ++ launch_params.uri = request->uri(); ++ launch_params.width = 0; ++ launch_params.height = 0; ++ ++ WebAppManagerServiceGRPC::Instance()->LaunchOnIdle(launch_params); ++ ++ grpc::ServerUnaryReactor* reactor = context->DefaultReactor(); ++ reactor->Finish(grpc::Status::OK); ++ return reactor; ++ } ++ grpc::ServerUnaryReactor* Activate(grpc::CallbackServerContext* context, ++ const ::wam_ipc::ActivateRequest* request, ++ google::protobuf::Empty* /*response*/) { ++ WebAppManagerServiceGRPC::Instance()->SendEventOnIdle(kActivateEvent, ++ request->app_id()); ++ grpc::ServerUnaryReactor* reactor = context->DefaultReactor(); ++ reactor->Finish(grpc::Status::OK); ++ return reactor; ++ } ++ grpc::ServerUnaryReactor* Kill(grpc::CallbackServerContext* context, ++ const ::wam_ipc::KillRequest* request, ++ google::protobuf::Empty* /*response*/) { ++ WebAppManagerServiceGRPC::Instance()->SendEventOnIdle(kKilledApp, ++ request->app_id()); ++ grpc::ServerUnaryReactor* reactor = context->DefaultReactor(); ++ reactor->Finish(grpc::Status::OK); ++ return reactor; ++ } ++}; ++ ++WebAppManagerServiceGRPC::WebAppManagerServiceGRPC() ++ : lock_file_(std::make_unique<WamIPCLockFile>()) {} ++ ++WebAppManagerServiceGRPC* WebAppManagerServiceGRPC::Instance() { ++ static WebAppManagerServiceGRPC* srv = new WebAppManagerServiceGRPC(); ++ return srv; ++} ++ ++bool WebAppManagerServiceGRPC::InitializeAsHostService() { ++ return lock_file_->CreateAndLock(); ++} ++ ++bool WebAppManagerServiceGRPC::IsHostServiceRunning() { ++ return !lock_file_->TryAcquireLock(); ++} ++ ++void* RunGrpcService(void*) { ++ std::string server_address(kDefaultGrpcServiceAddress); ++ GrpcServiceImpl service; ++ ++ grpc::EnableDefaultHealthCheckService(true); ++ grpc::reflection::InitProtoReflectionServerBuilderPlugin(); ++ ++ grpc::ServerBuilder builder; ++ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); ++ builder.RegisterService(&service); ++ ++ std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); ++ std::cout << "Server listening on " << server_address << std::endl; ++ server->Wait(); ++ ++ return nullptr; ++} ++ ++bool WebAppManagerServiceGRPC::StartService() { ++ if (lock_file_->OwnsLock()) { ++ pthread_t thread_id; ++ if (pthread_create(&thread_id, nullptr, RunGrpcService, nullptr) < 0) { ++ perror("Could not create thread"); ++ LOG_DEBUG("Could not create thread..."); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++void WebAppManagerServiceGRPC::LaunchOnIdle(const LaunchParams& params) { ++ auto launch_params = std::make_unique<LaunchParams>(params); ++ ++ auto* timer = ++ new OneShotTimerWithData<WebAppManagerServiceGRPC, LaunchParams>(); ++ timer->Start(0, this, &WebAppManagerServiceGRPC::OnLaunchApp, ++ std::move(launch_params)); ++} ++ ++void WebAppManagerServiceGRPC::SendEventOnIdle(const std::string& event, ++ const std::string& app_id) { ++ auto event_data = std::make_unique<EventData>(); ++ event_data->app_id = app_id; ++ auto* timer = new OneShotTimerWithData<WebAppManagerServiceGRPC, EventData>(); ++ if (event == kActivateEvent) ++ timer->Start(0, this, &WebAppManagerServiceGRPC::OnActivateEvent, ++ std::move(event_data)); ++ else if (event == kDeactivateEvent) ++ timer->Start(0, this, &WebAppManagerServiceGRPC::OnDeactivateEvent, ++ std::move(event_data)); ++ else if (event == kKilledApp) ++ timer->Start(1000, this, &WebAppManagerServiceGRPC::OnKillEvent, ++ std::move(event_data)); ++} ++ ++void WebAppManagerServiceGRPC::OnLaunchApp(LaunchParams* params) { ++ LOG_DEBUG("Triggering app start: %s", params->uri.c_str()); ++ if (!params->uri.empty()) { ++ if (params->uri.find("http://") == 0) { ++ LaunchStartupAppFromURL(params); ++ } else { ++ LaunchStartupAppFromJsonConfig(params); ++ } ++ } ++} ++ ++void WebAppManagerServiceGRPC::LaunchStartupAppFromJsonConfig( ++ LaunchParams* params) { ++ std::string configfile; ++ configfile.append(params->uri); ++ configfile.append("/appinfo.json"); ++ ++ Json::Value root; ++ Json::CharReaderBuilder builder; ++ JSONCPP_STRING errs; ++ ++ std::ifstream ifs; ++ ifs.open(configfile.c_str()); ++ ++ if (!parseFromStream(builder, ifs, &root, &errs)) { ++ LOG_DEBUG("Failed to parse %s configuration file", configfile.c_str()); ++ } ++ ++ root["folderPath"] = params->uri.c_str(); ++ ++ auto surface_obj = root["surface"]; ++ auto surface_type = surface_obj["type"].asString(); ++ if (surface_type == "background") { ++ root["surface_type"] = 1; // AglShellSurfaceType::kBackground; ++ } else if (surface_type == "panel") { ++ root["surface_type"] = 2; // AglShellSurfaceType::kPanel; ++ } else { ++ root["surface_type"] = 0; // AglShellSurfaceType::kNone; ++ } ++ ++ std::string app_desc = util::JsonToString(root); ++ std::string empty_params = "{}"; ++ std::string app_id = root["id"].asString(); ++ int err_code = 0; ++ std::string err_msg; ++ WebAppManagerService::OnLaunch(app_desc, empty_params, app_id, err_code, ++ err_msg); ++} ++ ++void WebAppManagerServiceGRPC::LaunchStartupAppFromURL(LaunchParams* params) { ++ LOG_DEBUG("WebAppManagerServiceGRPC::LaunchStartupAppFromURL"); ++ LOG_DEBUG(" url: %s", params->uri.c_str()); ++ Json::Value obj(Json::objectValue); ++ obj["id"] = params->app_id; ++ obj["version"] = "1.0"; ++ obj["vendor"] = "some vendor"; ++ obj["type"] = "web"; ++ obj["main"] = params->uri; ++ obj["title"] = "webapp"; ++ obj["uiRevision"] = "2"; ++ ++ obj["widthOverride"] = params->width; ++ obj["heightOverride"] = params->height; ++ ++ std::string app_desc = util::JsonToString(obj); ++ std::string app_id = params->app_id; ++ int err_code = 0; ++ std::string empty_params = "{}"; ++ std::string err_msg; ++ ++ LOG_DEBUG("Launching with appDesc=[%s]", app_desc.c_str()); ++ ++ WebAppManagerService::OnLaunch(app_desc, empty_params, app_id, err_code, ++ err_msg); ++ LOG_DEBUG("onLaunch: Done."); ++} ++ ++Json::Value WebAppManagerServiceGRPC::launchApp(const Json::Value& request) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::killApp(const Json::Value& request) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::pauseApp(const Json::Value& request) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::logControl(const Json::Value& request) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::setInspectorEnable( ++ const Json::Value& request) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::closeAllApps(const Json::Value& request) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::discardCodeCache( ++ const Json::Value& request) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::listRunningApps( ++ const Json::Value& request, ++ bool subscribed) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::getWebProcessSize( ++ const Json::Value& request) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::clearBrowsingData( ++ const Json::Value& request) { ++ return Json::Value(Json::objectValue); ++} ++ ++Json::Value WebAppManagerServiceGRPC::webProcessCreated( ++ const Json::Value& request, ++ bool subscribed) { ++ return Json::Value(Json::objectValue); ++} ++ ++void WebAppManagerServiceGRPC::OnActivateEvent(EventData* event_data) { ++ LOG_DEBUG("Activate app=%s", event_data->app_id.c_str()); ++ WebAppBase* web_app = ++ WebAppManager::Instance()->FindAppById(event_data->app_id); ++ if (web_app) { ++ web_app->OnStageActivated(); ++ web_app->SendAglActivate(event_data->app_id.c_str()); ++ } else { ++ LOG_DEBUG("Not found app=%s running", event_data->app_id.c_str()); ++ } ++} ++ ++void WebAppManagerServiceGRPC::OnDeactivateEvent(EventData* event_data) { ++ LOG_DEBUG("Dectivate app=%s", event_data->app_id.c_str()); ++ WebAppBase* web_app = ++ WebAppManager::Instance()->FindAppById(event_data->app_id); ++ if (web_app) ++ web_app->OnStageDeactivated(); ++} ++ ++void WebAppManagerServiceGRPC::OnKillEvent(EventData* event_data) { ++ LOG_DEBUG("Kill app=%s", event_data->app_id.c_str()); ++ WebAppManager::Instance()->OnKillApp(event_data->app_id, event_data->app_id); ++} +diff --git a/src/cef/service/web_app_manager_service_grpc.h b/src/cef/service/web_app_manager_service_grpc.h +new file mode 100644 +index 0000000..69ea0ed +--- /dev/null ++++ b/src/cef/service/web_app_manager_service_grpc.h +@@ -0,0 +1,85 @@ ++// Copyright (c) 2018-2022 LG Electronics, Inc. ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// http://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++// ++// SPDX-License-Identifier: Apache-2.0 ++ ++#ifndef CEF_SERVICE_WEB_APP_MANAGER_SERVICE_GRPC_H ++#define CEF_SERVICE_WEB_APP_MANAGER_SERVICE_GRPC_H ++ ++#include <memory> ++ ++#include "timer.h" ++#include "web_app_manager_service.h" ++ ++constexpr char kStartApp[] = "start-app"; ++constexpr char kKilledApp[] = "killed-app"; ++constexpr char kActivateEvent[] = "activate-event"; ++constexpr char kDeactivateEvent[] = "deactivate-event"; ++ ++class GrpcClient; ++class WamIPCLockFile; ++ ++class WebAppManagerServiceGRPC : public WebAppManagerService, ++ public TimerReceiver { ++ public: ++ struct LaunchParams { ++ std::string app_id; ++ std::string uri; ++ int width = 0; ++ int height = 0; ++ }; ++ ++ static WebAppManagerServiceGRPC* Instance(); ++ ++ bool InitializeAsHostService(); ++ bool IsHostServiceRunning(); ++ ++ void LaunchOnIdle(const LaunchParams& params); ++ void SendEventOnIdle(const std::string& event, const std::string& app_id); ++ ++ // WebAppManagerService ++ bool StartService() override; ++ Json::Value launchApp(const Json::Value& request) override; ++ Json::Value killApp(const Json::Value& request) override; ++ Json::Value pauseApp(const Json::Value& request) override; ++ Json::Value logControl(const Json::Value& request) override; ++ Json::Value setInspectorEnable(const Json::Value& request) override; ++ Json::Value closeAllApps(const Json::Value& request) override; ++ Json::Value discardCodeCache(const Json::Value& request) override; ++ Json::Value listRunningApps(const Json::Value& request, ++ bool subscribed) override; ++ Json::Value getWebProcessSize(const Json::Value& request) override; ++ Json::Value clearBrowsingData(const Json::Value& request) override; ++ Json::Value webProcessCreated(const Json::Value& request, ++ bool subscribed) override; ++ ++ void TriggerStartupApp(); ++ ++ private: ++ WebAppManagerServiceGRPC(); ++ ++ void OnLaunchApp(LaunchParams* launch_data); ++ void LaunchStartupAppFromJsonConfig(LaunchParams*); ++ void LaunchStartupAppFromURL(LaunchParams*); ++ struct EventData { ++ std::string app_id; ++ }; ++ void OnActivateEvent(EventData* event_data); ++ void OnDeactivateEvent(EventData* event_data); ++ void OnKillEvent(EventData* event_data); ++ ++ std::unique_ptr<WamIPCLockFile> lock_file_; ++}; ++ ++#endif // CEF_SERVICE_WEB_APP_MANAGER_SERVICE_GRPC_H +diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt +index 182f96a..41871b9 100644 +--- a/src/core/CMakeLists.txt ++++ b/src/core/CMakeLists.txt +@@ -18,6 +18,7 @@ project(WebAppMgrCore VERSION 1.0.0 DESCRIPTION "Core of the Web Application Man + + set(SOURCES + application_description.cc ++ application_installation_handler_stub.cc + device_info.cc + palm_system_base.cc + plugin_service.cc +@@ -44,7 +45,9 @@ set(SOURCES + set(HEADERS + agl_shell_types.h + application_description.h ++ application_installation_handler.h + device_info.h ++ memory_pressure_level.h + palm_system_base.h + platform_module_factory.h + plugin_service.h +@@ -95,6 +98,7 @@ set(CORE_INCLUDE_DIRS + set(CORE_LIBS + ${CHROMIUM_LDFLAGS} + ${GLIB_LDFLAGS} ++ ${JSONCPP_LDFLAGS} + ${PMLOGLIB_LDFLAGS} + Boost::filesystem + dl +diff --git a/src/core/application_description.cc b/src/core/application_description.cc +index 9b494fc..adbb7d8 100644 +--- a/src/core/application_description.cc ++++ b/src/core/application_description.cc +@@ -144,12 +144,49 @@ std::unique_ptr<ApplicationDescription> ApplicationDescription::FromJsonString( + auto app_desc = + std::unique_ptr<ApplicationDescription>(new ApplicationDescription()); + ++ + app_desc->surface_type_ = + static_cast<AglShellSurfaceType>(json_obj["surface_type"].asInt()); + app_desc->panel_type_ = + static_cast<AglShellPanelEdge>(json_obj["panel_type"].asInt()); + app_desc->width_override_ = json_obj["widthOverride"].asInt(); + app_desc->height_override_ = json_obj["heightOverride"].asInt(); ++ ++ // override previous values if the json config file contains ++ // a "surface" object with nested data ++ auto surface_obj = json_obj["surface"]; ++ if (!surface_obj.empty()) { ++ std::string surface_type = surface_obj["type"].asString(); ++ if (surface_type == "background") { ++ app_desc->surface_type_ = AglShellSurfaceType::kBackground; ++ } else if (surface_type == "panel") { ++ app_desc->surface_type_ = AglShellSurfaceType::kPanel; ++ } else { ++ app_desc->surface_type_ = AglShellSurfaceType::kNone; ++ } ++ ++ std::string panel_edge = surface_obj["panel_edge"].asString(); ++ if (panel_edge == "left") { ++ app_desc->panel_type_ = AglShellPanelEdge::kLeft; ++ } else if (panel_edge == "right") { ++ app_desc->panel_type_ = AglShellPanelEdge::kRight; ++ } else if (panel_edge == "top") { ++ app_desc->panel_type_ = AglShellPanelEdge::kTop; ++ } else if (panel_edge == "bottom") { ++ app_desc->panel_type_ = AglShellPanelEdge::kBottom; ++ } ++ ++ int width = 0; ++ if (!surface_obj["width"].empty()) ++ util::StrToInt(surface_obj["width"].asString(), width); ++ app_desc->width_override_ = width; ++ ++ int height = 0; ++ if (!surface_obj["height"].empty()) ++ util::StrToInt(surface_obj["height"].asString(), height); ++ app_desc->height_override_ = height; ++ } ++ + app_desc->transparency_ = json_obj["transparent"].asBool(); + auto vendor_extension = + json_obj.get("vendorExtension", Json::Value(Json::objectValue)); +diff --git a/src/core/application_installation_handler.h b/src/core/application_installation_handler.h +new file mode 100644 +index 0000000..054bc9d +--- /dev/null ++++ b/src/core/application_installation_handler.h +@@ -0,0 +1,12 @@ ++#ifndef CORE_APPLICATION_INSTALLATION_HANDLER_H_ ++#define CORE_APPLICATION_INSTALLATION_HANDLER_H_ ++ ++#include <string> ++ ++class ApplicationInstallationHandler { ++ public: ++ static void OnAppInstalled(const std::string& app_id); ++ static void OnAppRemoved(const std::string& app_id); ++}; ++ ++#endif // CORE_APPLICATION_INSTALLATION_HANDLER_H_ +\ No newline at end of file +diff --git a/src/core/application_installation_handler_stub.cc b/src/core/application_installation_handler_stub.cc +new file mode 100644 +index 0000000..016c7d2 +--- /dev/null ++++ b/src/core/application_installation_handler_stub.cc +@@ -0,0 +1,4 @@ ++#include "application_installation_handler.h" ++ ++void ApplicationInstallationHandler::OnAppInstalled(const std::string&) {} ++void ApplicationInstallationHandler::OnAppRemoved(const std::string&) {} +\ No newline at end of file +diff --git a/src/core/memory_pressure_level.h b/src/core/memory_pressure_level.h +new file mode 100644 +index 0000000..01c9316 +--- /dev/null ++++ b/src/core/memory_pressure_level.h +@@ -0,0 +1,6 @@ ++#ifndef CORE_MEMORY_PRESSURE_LEVEL_H_ ++#define CORE_MEMORY_PRESSURE_LEVEL_H_ ++ ++enum class MemoryPressureLevel { kNone, kLow, kCritical }; ++ ++#endif // CORE_MEMORY_PRESSURE_LEVEL_H_ +\ No newline at end of file +diff --git a/src/core/web_app_manager.cc b/src/core/web_app_manager.cc +index ca64ef1..42e8be7 100644 +--- a/src/core/web_app_manager.cc ++++ b/src/core/web_app_manager.cc +@@ -22,10 +22,9 @@ + #include <string> + + #include <json/value.h> +-#include "webos/application_installation_handler.h" +-#include "webos/public/runtime.h" + + #include "application_description.h" ++#include "application_installation_handler.h" + #include "base_check.h" + #include "device_info.h" + #include "log_manager.h" +@@ -63,8 +62,7 @@ WebAppManager::~WebAppManager() { + device_info_->Terminate(); + } + +-void WebAppManager::NotifyMemoryPressure( +- webos::WebViewBase::MemoryPressureLevel level) { ++void WebAppManager::NotifyMemoryPressure(MemoryPressureLevel level) { + std::list<const WebAppBase*> app_list = RunningApps(); + for (auto it = app_list.begin(); it != app_list.end(); ++it) { + const WebAppBase* app = *it; +@@ -72,15 +70,14 @@ void WebAppManager::NotifyMemoryPressure( + // critical (when system is on low or critical) because they will be killed + // anyway + if (app->IsActivated() && +- (!app->Page()->IsPreload() || +- level != webos::WebViewBase::MEMORY_PRESSURE_CRITICAL)) ++ (!app->Page()->IsPreload() || level != MemoryPressureLevel::kCritical)) + app->Page()->NotifyMemoryPressure(level); + else { + LOG_DEBUG( + "Skipping memory pressure handler for" + " instanceId(%s) appId(%s) isActivated(%d) isPreload(%d) Level(%d)", + app->InstanceId().c_str(), app->AppId().c_str(), app->IsActivated(), +- app->Page()->IsPreload(), level); ++ app->Page()->IsPreload(), static_cast<int>(level)); + } + } + } +@@ -341,8 +338,10 @@ WebAppBase* WebAppManager::OnLaunchUrl( + WebPageAdded(page); + + /* if the surface role is a background send ready to display them */ +- if (app_desc->SurfaceType() == AglShellSurfaceType::kBackground) ++ if (app_desc->SurfaceType() == AglShellSurfaceType::kBackground) { ++ LOG_DEBUG("Sending agl_ready from app %s", app_desc->Id().c_str()); + app->SendAglReady(); ++ } + + app_list_.push_back(app); + +@@ -831,8 +830,10 @@ void WebAppManager::UpdateNetworkStatus(const Json::Value& object) { + NetworkStatus status; + status.FromJsonObject(object); + ++#if defined(OS_WEBOS) + webos::Runtime::GetInstance()->SetNetworkConnected( + status.IsInternetConnectionAvailable()); ++#endif + network_status_manager_->UpdateNetworkStatus(status); + + if (status.IsInternetConnectionAvailable()) { +@@ -867,16 +868,12 @@ int WebAppManager::MaskForBrowsingDataType(const char* type) { + + void WebAppManager::AppInstalled(const std::string& app_id) { + LOG_INFO(MSGID_WAM_DEBUG, 0, "App installed; id=%s", app_id.c_str()); +- auto p = webos::ApplicationInstallationHandler::GetInstance(); +- if (p) +- p->OnAppInstalled(app_id); ++ ApplicationInstallationHandler::OnAppInstalled(app_id); + } + + void WebAppManager::AppRemoved(const std::string& app_id) { + LOG_INFO(MSGID_WAM_DEBUG, 0, "App removed; id=%s", app_id.c_str()); +- auto p = webos::ApplicationInstallationHandler::GetInstance(); +- if (p) +- p->OnAppRemoved(app_id); ++ ApplicationInstallationHandler::OnAppRemoved(app_id); + } + + std::string WebAppManager::IdentifierForSecurityOrigin( +@@ -889,5 +886,9 @@ std::string WebAppManager::IdentifierForSecurityOrigin( + LOG_WARNING(MSGID_APPID_HAS_UPPERCASE, 0, + "Application id should not contain capital letters"); + } ++#if defined(OS_WEBOS) + return (lowcase_identifier + webos::WebViewBase::kSecurityOriginPostfix); ++#else ++ return lowcase_identifier; ++#endif + } +diff --git a/src/core/web_app_manager.h b/src/core/web_app_manager.h +index b10f53d..0f30a85 100644 +--- a/src/core/web_app_manager.h ++++ b/src/core/web_app_manager.h +@@ -24,7 +24,7 @@ + #include <unordered_map> + #include <vector> + +-#include "webos/webview_base.h" ++#include "memory_pressure_level.h" + + class ApplicationDescription; + class DeviceInfo; +@@ -150,7 +150,7 @@ class WebAppManager { + const std::string& payload, + const std::string& app_id); + void UpdateNetworkStatus(const Json::Value& object); +- void NotifyMemoryPressure(webos::WebViewBase::MemoryPressureLevel level); ++ void NotifyMemoryPressure(MemoryPressureLevel level); + + bool IsEnyoApp(const std::string& app_id); + +diff --git a/src/core/web_app_manager_service.cc b/src/core/web_app_manager_service.cc +index 1770d02..90b880f 100644 +--- a/src/core/web_app_manager_service.cc ++++ b/src/core/web_app_manager_service.cc +@@ -19,6 +19,7 @@ + #include <json/value.h> + + #include "log_manager.h" ++#include "memory_pressure_level.h" + #include "web_app_base.h" + #include "web_app_manager_tracer.h" + +@@ -158,8 +159,7 @@ void WebAppManagerService::UpdateNetworkStatus(const Json::Value& object) { + WebAppManager::Instance()->UpdateNetworkStatus(object); + } + +-void WebAppManagerService::NotifyMemoryPressure( +- webos::WebViewBase::MemoryPressureLevel level) { ++void WebAppManagerService::NotifyMemoryPressure(MemoryPressureLevel level) { + WebAppManager::Instance()->NotifyMemoryPressure(level); + } + +diff --git a/src/core/web_app_manager_service.h b/src/core/web_app_manager_service.h +index 7ead117..c294e50 100644 +--- a/src/core/web_app_manager_service.h ++++ b/src/core/web_app_manager_service.h +@@ -22,7 +22,6 @@ + #include <vector> + + #include "web_app_manager.h" +-#include "webos/webview_base.h" + + namespace Json { + class Value; +@@ -114,7 +113,7 @@ class WebAppManagerService { + void KillCustomPluginProcess(const std::string& app_base_path); + void RequestKillWebProcess(uint32_t pid); + void UpdateNetworkStatus(const Json::Value& object); +- void NotifyMemoryPressure(webos::WebViewBase::MemoryPressureLevel level); ++ void NotifyMemoryPressure(MemoryPressureLevel level); + void SetAccessibilityEnabled(bool enable); + uint32_t GetWebProcessId(const std::string& app_id, + const std::string& instance_id); +diff --git a/src/core/web_page_base.h b/src/core/web_page_base.h +index 7bbca84..8a689a7 100644 +--- a/src/core/web_page_base.h ++++ b/src/core/web_page_base.h +@@ -20,8 +20,7 @@ + #include <memory> + #include <string> + +-#include "webos/webview_base.h" +- ++#include "memory_pressure_level.h" + #include "observer_list.h" + #include "util/url.h" + +@@ -58,8 +57,7 @@ class WebPageBase { + virtual void Init() = 0; + virtual void* GetWebContents() = 0; + virtual void SetLaunchParams(const std::string& params); +- virtual void NotifyMemoryPressure( +- webos::WebViewBase::MemoryPressureLevel level) {} ++ virtual void NotifyMemoryPressure(MemoryPressureLevel level) {} + + virtual std::string GetIdentifier() const; + virtual wam::Url Url() const = 0; +diff --git a/src/core/web_process_manager.h b/src/core/web_process_manager.h +index b63d270..c7ffde1 100644 +--- a/src/core/web_process_manager.h ++++ b/src/core/web_process_manager.h +@@ -17,6 +17,7 @@ + #ifndef CORE_WEB_PROCESS_MANAGER_H_ + #define CORE_WEB_PROCESS_MANAGER_H_ + ++#include <cstdint> + #include <list> + #include <string> + #include <unordered_map> +diff --git a/src/core/web_runtime.h b/src/core/web_runtime.h +index 69bc204..1ae6ca9 100644 +--- a/src/core/web_runtime.h ++++ b/src/core/web_runtime.h +@@ -21,8 +21,9 @@ + + class WebRuntime { + public: ++ virtual ~WebRuntime() = default; + static std::unique_ptr<WebRuntime> Create(); +- virtual int Run(int argc, const char** argv) = 0; ++ virtual int Run(int argc, char** argv) = 0; + }; + + #endif // CORE_WEB_RUNTIME_H_ +diff --git a/src/desktop/CMakeLists.txt b/src/desktop/CMakeLists.txt +new file mode 100644 +index 0000000..06078da +--- /dev/null ++++ b/src/desktop/CMakeLists.txt +@@ -0,0 +1,100 @@ ++project(WebAppMgrDesktop VERSION 1.0.0 DESCRIPTION "Web Application Manager library") ++ ++find_package(gRPC REQUIRED) ++find_program(GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin REQUIRED) ++find_package(Protobuf REQUIRED) ++find_package(Threads) ++ ++set(WAM_IPC_LIB_NAME ${PROJECT_NAME}IPC) ++set(WAM_IPC_PROTO_FILES ${WAM_ROOT_SOURCE_DIR}/cef/ipc/wam_ipc.proto) ++set(WAM_IPC_LIBS ++ protobuf::libprotobuf ++ gRPC::grpc ++ gRPC::grpc++ ++ gRPC::grpc++_reflection ++) ++set(WAM_IPC_INCLUDE_DIRS ++ ${CMAKE_CURRENT_BINARY_DIR} ++) ++ ++set(WAM_LIB_LIBS ++ ${JSONCPP_LDFLAGS} ++ WebAppMgrCore ++ ${WAM_IPC_LIB_NAME} ++ libcef_lib ++ libcef_dll_wrapper ++) ++ ++set(SOURCES ++ web_runtime_desktop.cc ++) ++ ++set(HEADERS ++ web_runtime_desktop.h ++) ++ ++set(WAM_LIB_CEF_DIR ${WAM_ROOT_SOURCE_DIR}/cef) ++ ++ ++set(WAM_LIB_INCLUDE_DIRS ++ ${JSONCPP_INCLUDE_DIRS} ++ ${CEF_INCLUDE_PATH} ++) ++ ++add_library(${WAM_IPC_LIB_NAME} SHARED ${WAM_IPC_PROTO_FILES}) ++target_include_directories(${WAM_IPC_LIB_NAME} PUBLIC ${WAM_IPC_INCLUDE_DIRS}) ++target_link_libraries(${WAM_IPC_LIB_NAME} PUBLIC ${WAM_IPC_LIBS}) ++set_target_properties(${WAM_IPC_LIB_NAME} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) ++protobuf_generate(TARGET ${WAM_IPC_LIB_NAME} LANGUAGE cpp APPEND_PATH) ++protobuf_generate(TARGET ${WAM_IPC_LIB_NAME} LANGUAGE grpc APPEND_PATH GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${GRPC_CPP_PLUGIN_EXECUTABLE}") ++install(TARGETS ${WAM_IPC_LIB_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++ ++ ++LIST(APPEND SOURCES ++ ${WAM_LIB_CEF_DIR}/device_info_cef.cc ++ ${WAM_LIB_CEF_DIR}/platform_module_factory_cef.cc ++ ${WAM_LIB_CEF_DIR}/ipc/web_app_manager_service_grpc.cc ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_browser_handler.cc ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_client.cc ++) ++LIST(APPEND HEADERS ++ ${WAM_LIB_CEF_DIR}/device_info_cef.h ++ ${WAM_LIB_CEF_DIR}/platform_module_factory_cef.h ++ ${WAM_LIB_CEF_DIR}/ipc/web_app_manager_service_grpc.h ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_browser_handler.h ++ ${WAM_LIB_CEF_DIR}/handlers/wam_cef_client.h ++) ++LIST(APPEND WAM_LIB_INCLUDE_DIRS ++ ${WAM_LIB_CEF_DIR} ++ ${WAM_LIB_CEF_DIR}/ipc ++ ${WAM_LIB_CEF_DIR}/webapp ++) ++ ++add_library(${PROJECT_NAME} SHARED ${HEADERS} ${SOURCES}) ++target_include_directories(${PROJECT_NAME} PUBLIC ${WAM_LIB_INCLUDE_DIRS}) ++set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) ++ ++install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/webappmanager) ++ ++macro(INSTALL_CEF_FILES file_list source_dir target_dir) ++ foreach(FILENAME ${file_list}) ++ set(source_file ${source_dir}/${FILENAME}) ++ ++ # Remove the target file path component. ++ get_filename_component(target_name ${FILENAME} NAME) ++ set(target_file ${target_dir}/${target_name}) ++ ++ if (IS_DIRECTORY ${source_file}) ++ install(DIRECTORY ${source_file} DESTINATION ${target_dir}) ++ else() ++ install(FILES ${source_file} DESTINATION ${target_dir}) ++ endif() ++ endforeach() ++endmacro() ++ ++# Copy CEF dependencies ++install_cef_files("${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${CMAKE_INSTALL_PREFIX}") ++install_cef_files("${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${CMAKE_INSTALL_PREFIX}") ++ ++target_link_libraries(${PROJECT_NAME} PUBLIC ${WAM_LIB_LIBS}) ++install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) +diff --git a/src/desktop/README.md b/src/desktop/README.md +new file mode 100644 +index 0000000..2d32b39 +--- /dev/null ++++ b/src/desktop/README.md +@@ -0,0 +1,102 @@ ++# CEF backend ++ ++This is an experimental CEF backend for WAM. ++ ++## Compilation ++ ++### Preparations ++ ++First prepare a workspace: ++``` ++mkdir wam-cef ++cd wam-cef ++``` ++ ++Now clone WAM repository: ++``` ++git clone ssh://git@gitlab.igalia.com:4429/dape/wam.git ++``` ++ ++Fetch latest stable CEF binary distribution (standard) for your system, from [CEF binary download](https://cef-builds.spotifycdn.com/index.html). Then uncompress the tarball: ++``` ++tar xvf ...path...to...binary/cef_binary...tar.bz2 ++``` ++ ++### Compilation of CEF DLL wrapper ++ ++Create a folder to compile the CEF DLL wrapper `.a` file: ++``` ++mkdir build-cef-dll ++cd build-cef-dll ++``` ++ ++Prepare compilation scripts: ++``` ++cmake ../cef_binary_... ++``` ++ ++Then compile the DLL wrapper: ++``` ++make libcef_dll_wrapper ++``` ++ ++Finally go back to the top directory: ++``` ++cd .. ++``` ++ ++After this, you can see the wrapper at `build-cef-dll/libcef_dll_wrapper/libcef_dll_wrapper.a`. ++ ++### Test applications ++ ++You can just use webOS `test-apps` repository: ++``` ++git clone https://github.com/webosose/test-apps.git ++``` ++ ++### Compilation of WAM ++ ++Prepare build folder: ++ ++``` ++mkdir build-wam ++cd build-wam ++mkdir wam-install ++``` ++ ++Then call *CMake* to generate the compilation scripts. You will need to pass several variables: ++* `CEF_ROOT`: full path to the CEF dist directory. ++* `CMAKE_INSTALL_PREFIX`: base install directory. ++* `CMAKE_INSTALL_BINDIR`: where executables will go. ++* `CMAKE_INSTALL_LIBDIR`: libraries. ++* `CMAKE_INSTALL_INCLUDEDIR`: path for includes. ++ ++You can also use `CMAKE_BUILD_TYPE` to set `Debug` or `Release` builds. ++ ++An example of the *CMake* invokation: ++``` ++cmake -DCMAKE_INSTALL_PREFIX=$PWD/wam-install -DCMAKE_INSTALL_BINDIR=$PWD/wam-install/bin -DCMAKE_INSTALL_LIBDIR=$PWD/wam-install/lib -DCMAKE_INSTALL_INCLUDEDIR=$PWD/wam-install/include -DCEF_ROOT=$WAM_BASE_PATH/cef_binary_114.2.10+g398e3c3+chromium-114.0.5735.110_linux64/Debug/ -DCMAKE_BUILD_TYPE=Debug ++``` ++ ++And finally compilation of WAM: ++``` ++make ++``` ++ ++And installation: ++``` ++make install ++``` ++ ++## Running ++ ++To run the daemon, you can do: ++``` ++cd wam-install/bin ++WEBAPPFACTORY_PLUGIN_PATH=../lib/webappmanager/plugins/ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../lib:$WAM_BASE_PATH/cef_binary_114.2.10+g398e3c3+chromium-114.0.5735.110_linux64/Release/ ./WebAppMgr & ++``` ++ ++Then, you can launch an application: ++``` ++LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../lib ../WebAppMgrDesktopCli --app-id=bareapp --app-install-dir=$WAM_BASE_PATH/test-apps/bareapp/ ++``` +diff --git a/src/desktop/web_runtime_desktop.cc b/src/desktop/web_runtime_desktop.cc +new file mode 100644 +index 0000000..49d1914 +--- /dev/null ++++ b/src/desktop/web_runtime_desktop.cc +@@ -0,0 +1,28 @@ ++#include "web_runtime_desktop.h" ++ ++#include "include/cef_base.h" ++ ++#include "wam_cef_browser_handler.h" ++ ++int WebRuntimeDesktop::Run(int argc, char** argv) { ++ CefMainArgs main_args(argc, argv); ++ ++ CefRefPtr<CefApp> app = new WamCefBrowserHandler; ++ auto exit_code = CefExecuteProcess(main_args, app.get(), nullptr); ++ if (exit_code >= 0) { ++ return exit_code; ++ } ++ ++ CefSettings settings; ++ CefInitialize(main_args, settings, app.get(), nullptr); ++ ++ CefRunMessageLoop(); ++ ++ CefShutdown(); ++ ++ return 0; ++} ++ ++std::unique_ptr<WebRuntime> WebRuntime::Create() { ++ return std::make_unique<WebRuntimeDesktop>(); ++} +diff --git a/src/desktop/web_runtime_desktop.h b/src/desktop/web_runtime_desktop.h +new file mode 100644 +index 0000000..e65f738 +--- /dev/null ++++ b/src/desktop/web_runtime_desktop.h +@@ -0,0 +1,11 @@ ++#ifndef DESKTOP_WEB_RUNTIME_CEF_H_ ++#define DESKTOP_WEB_RUNTIME_CEF_H_ ++ ++#include "web_runtime.h" ++ ++class WebRuntimeDesktop : public WebRuntime { ++ public: ++ int Run(int argc, char** argv) override; ++}; ++ ++#endif // DESKTOP_WEB_RUNTIME_CEF_H_ +diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt +index 876921b..b401dca 100644 +--- a/src/platform/CMakeLists.txt ++++ b/src/platform/CMakeLists.txt +@@ -17,10 +17,6 @@ + project(WebAppMgr VERSION 1.0.0 DESCRIPTION "Web Application Manager library") + + set(SOURCES +- palm_system_webos.cc +- web_app_wayland.cc +- web_app_wayland_window.cc +- web_app_window_impl.cc + webengine/blink_web_process_manager.cc + webengine/blink_web_view.cc + webengine/blink_web_view_profile_helper.cc +@@ -32,12 +28,8 @@ set(SOURCES + ) + + set(HEADERS +- palm_system_webos.h +- web_app_wayland.h +- web_app_wayland_window.h + web_app_window.h + web_app_window_factory.h +- web_app_window_impl.h + webengine/blink_web_process_manager.h + webengine/blink_web_view.h + webengine/blink_web_view_profile_helper.h +@@ -67,6 +59,21 @@ set(WAM_LIB_LIBS + WebAppMgrCore + ) + ++if (WEBENGINE_CBE) ++ LIST(APPEND SOURCES ++ web_app_window_impl.h ++ web_app_wayland_window.cc ++ palm_system_webos.cc ++ web_app_wayland.cc ++ ) ++ LIST(APPEND HEADERS ++ palm_system_webos.h ++ web_app_wayland.h ++ web_app_wayland_window.h ++ web_app_window_impl.h ++ ) ++endif() ++ + if (OS_WEBOS) + LIST(APPEND SOURCES + ${WAM_ROOT_SOURCE_DIR}/webos/palm_service_base.cc +diff --git a/src/platform/web_app_window.h b/src/platform/web_app_window.h +index 7381b0c..a90127f 100644 +--- a/src/platform/web_app_window.h ++++ b/src/platform/web_app_window.h +@@ -20,8 +20,6 @@ + #include <string> + #include <vector> + +-#include "webos/webapp_window_base.h" +- + class WebAppWayland; + + class WebAppWindow { +@@ -32,12 +30,14 @@ class WebAppWindow { + virtual int DisplayWidth() = 0; + virtual int DisplayHeight() = 0; + virtual void InitWindow(int width, int height) = 0; +- virtual void SetLocationHint(webos::WebAppWindowBase::LocationHint value) = 0; ++ virtual void SetLocationHint(const std::string& value) = 0; + virtual webos::NativeWindowState GetWindowHostState() const = 0; ++#if defined(OS_WEBOS) + virtual void CreateWindowGroup( + const webos::WindowGroupConfiguration& config) = 0; + virtual void AttachToWindowGroup(const std::string& name, + const std::string& layer) = 0; ++#endif + virtual bool IsKeyboardVisible() = 0; + virtual void SetKeyMask(webos::WebOSKeyMask key_mask) = 0; + virtual void SetKeyMask(webos::WebOSKeyMask key_mask, bool set) = 0; +diff --git a/src/util/log_msg_id.h b/src/util/log_msg_id.h +index 7d114cf..71d9621 100644 +--- a/src/util/log_msg_id.h ++++ b/src/util/log_msg_id.h +@@ -150,6 +150,8 @@ + + #define MSGID_DL_ERROR "DL_ERROR" /** Dinamic load library error **/ + ++#define MSGID_ERROR_CANNOT_LOCK_SERVICE "MSGID_CANNOT_LOCK_SERVICE" /** Cannot lock the GRPC IPC lock **/ ++ + // clang-format on + + #endif // LOGMSGID_H +diff --git a/src/util/timer.h b/src/util/timer.h +index 795a38c..6824fb8 100644 +--- a/src/util/timer.h ++++ b/src/util/timer.h +@@ -30,12 +30,12 @@ class Timer { + : source_id_(0), is_running_(false), is_repeating_(is_repeating) {} + virtual ~Timer() {} + +- // Timer + virtual void HandleCallback() = 0; +- virtual void Start(int delay_in_milli_seconds); + + bool IsRunning() { return is_running_; } + bool IsRepeating() { return is_repeating_; } ++ ++ void Start(int delay_in_milli_seconds); + void Stop(); + + protected: +diff --git a/src/wam_main.cc b/src/wam_main.cc +index 0c04a40..d559ee4 100644 +--- a/src/wam_main.cc ++++ b/src/wam_main.cc +@@ -14,11 +14,9 @@ + // + // SPDX-License-Identifier: Apache-2.0 + +-#include <webos/app/webos_main.h> +- + #include "web_runtime.h" + +-int main(int argc, const char** argv) { ++int main(int argc, char** argv) { + std::unique_ptr<WebRuntime> web_runtime(WebRuntime::Create()); + return web_runtime->Run(argc, argv); + } +diff --git a/src/webos/web_app_manager_service_luna.cc b/src/webos/web_app_manager_service_luna.cc +index 627cf31..b69635f 100644 +--- a/src/webos/web_app_manager_service_luna.cc ++++ b/src/webos/web_app_manager_service_luna.cc +@@ -632,6 +632,7 @@ void WebAppManagerServiceLuna::GetForegroundAppInfoCallback( + if (cleared_cache_) + cleared_cache_ = false; + ++#if defined(OS_WEBOS) + if (reply["returnValue"] == true) { + if (reply.isMember("appId") && reply["appId"].isString()) { + std::string appId = reply["appId"].asString(); +@@ -639,6 +640,7 @@ void WebAppManagerServiceLuna::GetForegroundAppInfoCallback( + WebAppManagerService::IsEnyoApp(appId.c_str())); + } + } ++#endif + } + + void WebAppManagerServiceLuna::BootdConnectCallback(const Json::Value& reply) { +diff --git a/src/webos/web_runtime_webos.cc b/src/webos/web_runtime_webos.cc +index 9dd2f72..cab7e5a 100644 +--- a/src/webos/web_runtime_webos.cc ++++ b/src/webos/web_runtime_webos.cc +@@ -70,7 +70,7 @@ class WebOSMainDelegateWAM : public webos::WebOSMainDelegate { + void AboutToCreateContentBrowserClient() override { StartWebAppManager(); } + }; + +-int WebRuntimeWebOS::Run(int argc, const char** argv) { ++int WebRuntimeWebOS::Run(int argc, char** argv) { + WebOSMainDelegateWAM delegate; + webos::WebOSMain webos_main(&delegate); + return webOSMain.Run(argc, argv); +diff --git a/src/webos/web_runtime_webos.h b/src/webos/web_runtime_webos.h +index eb52348..fa031a2 100644 +--- a/src/webos/web_runtime_webos.h ++++ b/src/webos/web_runtime_webos.h +@@ -21,7 +21,7 @@ + + class WebRuntimeWebOS : public WebRuntime { + public: +- int Run(int argc, const char** argv) override; ++ int Run(int argc, char** argv) override; + }; + + #endif // WEBOS_WEB_RUNTIME_WEBOS_H_ +-- +2.39.2 + diff --git a/recipes-wam/wam/files/WebAppMgr-cef.env b/recipes-wam/wam/files/WebAppMgr-cef.env new file mode 100644 index 00000000..adc18b94 --- /dev/null +++ b/recipes-wam/wam/files/WebAppMgr-cef.env @@ -0,0 +1,81 @@ +# Set wam executable file path +HOOK_SEGV=NO + +# Set wam name for user-agent +WAM_NAME="WebAppManager" + +WAM_IS_CEF=true + +# Only allow UTF8 encoding for luna-service messages. +LS_ENABLE_UTF8=1 + +# suspending javascript execution delay for page visibility +WAM_SUSPEND_DELAY_IN_MS=250 + +WAM_DATA_PATH="/home/agl-driver/wamdata" + +# setup 50 Mb maximum for ApplicationCache +WAM_APPCACHE_MAXSIZE=52428800 + +# setup 10 Mb maximum for ApplicationCache per domain +WAM_APPCACHE_DOMAINLIMIT=10485760 + +# setup 50 Mb maximum for DiskCache +WAM_DISKCACHE_MAXSIZE=52428800 + +# setup 256 Kb maximum for resource buffer allocation +WAM_RESOURCE_BUFFER_MAX_ALLOC_SIZE=262144 + +# setup 1 Mb for resource buffer +WAM_RESOURCE_BUFFER_SIZE=1048576 + +# setup 200 seconds for watchdog timeout of render process +WATCHDOG_RENDER_TIMEOUT=200 + +# setup nubmer of raster threads to 1 +BLINK_NUM_RASTER_THREADS=2 + +# use default tile width if not sed by recipe +BLINK_NUM_RASTER_THREADS=1 + +# setup 6 Mb maximum for the program GPU cache +GPU_PROGRAM_CACHE_SIZE=6144 + +# Set location of all NPAPI plugins +NPAPI_PLUGIN_PATH=${HBBTV_PLUGIN_PATH}":"${NETCAST_PLUGIN_PATH}":"${PRIVILEGED_PLUGIN_PATH} + +# setup 8 Mb minimum codecache capacity +JSC_minGlobalCodeCacheCapacity=8388608 + +# Enable more explicit logging of timing with regards to rendering +# export WAM2_ENABLE_DEBUG_RENDER_TIMING=1 + +# enable Web Inspector and Tellurium if in developer mode +TELLURIUM_NUB_PATH=/usr/palm/tellurium/telluriumnub.js +ENABLE_INSPECTOR=1 + +# Enable cursor by default +ENABLE_CURSOR_BY_DEFAULT=1 + +# Enable launch optimization +ENABLE_LAUNCH_OPTIMIZATION=1 + +# Set the duration(seconds) passed from last network activity (e.g. FMP Detector) +# If set to a positive value, adjust a custom timeout for a network stable timer in FMPDetector +NETWORK_STABLE_TIMEOUT=3 + +LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/share/wam + +WAM_SWITCHES="\ + --user-data-dir=\"$WAM_DATA_PATH\" \ + --use-gl=egl \ + --ozone-platform=wayland \ + --no-sandbox \ + --use-viz-fmp-with-timeout=0 \ + --remote-debugging-port=9998 \ + --webos-wam \ + --agl-shell-appid=homescreen \ + --disable-gpu-vsync \ + --ignore-gpu-blocklist \ + --allow-universal-access-from-files \ + --allow-file-access-from-files" diff --git a/recipes-wam/wam/files/WebAppMgr.env b/recipes-wam/wam/files/WebAppMgr.env new file mode 100644 index 00000000..f1d0f28f --- /dev/null +++ b/recipes-wam/wam/files/WebAppMgr.env @@ -0,0 +1,78 @@ +# Set wam executable file path +HOOK_SEGV=NO + +# Set wam name for user-agent +WAM_NAME="WebAppManager" + +WAM_IS_CEF=false + +# Only allow UTF8 encoding for luna-service messages. +LS_ENABLE_UTF8=1 + +# suspending javascript execution delay for page visibility +WAM_SUSPEND_DELAY_IN_MS=250 + +WAM_DATA_PATH="/home/agl-driver/wamdata" + +# setup 50 Mb maximum for ApplicationCache +WAM_APPCACHE_MAXSIZE=52428800 + +# setup 10 Mb maximum for ApplicationCache per domain +WAM_APPCACHE_DOMAINLIMIT=10485760 + +# setup 50 Mb maximum for DiskCache +WAM_DISKCACHE_MAXSIZE=52428800 + +# setup 256 Kb maximum for resource buffer allocation +WAM_RESOURCE_BUFFER_MAX_ALLOC_SIZE=262144 + +# setup 1 Mb for resource buffer +WAM_RESOURCE_BUFFER_SIZE=1048576 + +# setup 200 seconds for watchdog timeout of render process +WATCHDOG_RENDER_TIMEOUT=200 + +# setup nubmer of raster threads to 1 +BLINK_NUM_RASTER_THREADS=2 + +# use default tile width if not sed by recipe +BLINK_NUM_RASTER_THREADS=1 + +# setup 6 Mb maximum for the program GPU cache +GPU_PROGRAM_CACHE_SIZE=6144 +# Set location of all NPAPI plugins +NPAPI_PLUGIN_PATH=${HBBTV_PLUGIN_PATH}":"${NETCAST_PLUGIN_PATH}":"${PRIVILEGED_PLUGIN_PATH} + +# setup 8 Mb minimum codecache capacity +JSC_minGlobalCodeCacheCapacity=8388608 + +# Enable more explicit logging of timing with regards to rendering +# export WAM2_ENABLE_DEBUG_RENDER_TIMING=1 + +# enable Web Inspector and Tellurium if in developer mode +TELLURIUM_NUB_PATH=/usr/palm/tellurium/telluriumnub.js +ENABLE_INSPECTOR=1 + +# Enable cursor by default +ENABLE_CURSOR_BY_DEFAULT=1 + +# Enable launch optimization +ENABLE_LAUNCH_OPTIMIZATION=1 + +# Set the duration(seconds) passed from last network activity (e.g. FMP Detector) +# If set to a positive value, adjust a custom timeout for a network stable timer in FMPDetector +NETWORK_STABLE_TIMEOUT=3 + +WAM_SWITCHES="\ + --user-data-dir=$WAM_DATA_PATH \ + --use-gl=egl \ + --enable-features=UseOzonePlatform \ + --ozone-platform=wayland \ + --no-sandbox \ + --use-viz-fmp-with-timeout=0 \ + --in-process-gpu \ + --remote-debugging-port=9998 \ + --webos-wam \ + --agl-shell-appid=homescreen \ + --disable-gpu-vsync \ + --ignore-gpu-blocklist" diff --git a/recipes-wam/wam/files/WebAppMgr.service b/recipes-wam/wam/files/WebAppMgr.service new file mode 100644 index 00000000..5f025a18 --- /dev/null +++ b/recipes-wam/wam/files/WebAppMgr.service @@ -0,0 +1,34 @@ +# @@@LICENSE +# +# Copyright (c) 2017-2018 LG Electronics, Inc. +# +# Confidential computer software. Valid license from LG required for +# possession, use or copying. Consistent with FAR 12.211 and 12.212, +# Commercial Computer Software, Computer Software Documentation, and +# Technical Data for Commercial Items are licensed to the U.S. Government +# under vendor's standard commercial license. +# +# LICENSE@@@ + +[Unit] +Description="WebAppMgr is responsible for running web apps and manage their lifecycle" +After=agl-compositor.service nss-agl-driver-db.service +Requires=agl-compositor.service nss-agl-driver-db.service +Before=graphical.target +BindTo=agl-compositor.service + +[Service] +User=agl-driver +WorkingDirectory=/home/agl-driver +Type=simple +UMask=0077 +OOMScoreAdjust=-1000 +EnvironmentFile=-/etc/default/WebAppMgr.env +Environment=XDG_RUNTIME_DIR=/run/user/1001/ +ExecStart=@WAM_EXE_DIR@/WebAppMgr $WAM_SWITCHES +ExecStop=pkill -U %U WebAppMgr +Restart=on-failure +RestartSec=50 + +[Install] +WantedBy=graphical.target diff --git a/recipes-wam/wam/files/WebAppMgrCli b/recipes-wam/wam/files/WebAppMgrCli new file mode 100755 index 00000000..4312e047 --- /dev/null +++ b/recipes-wam/wam/files/WebAppMgrCli @@ -0,0 +1,9 @@ +#!/bin/bash + +WAM_CLI_EXE="/usr/bin/WebAppMgr" + +if [ "$WAM_IS_CEF" = true ] ; then + WAM_CLI_EXE="/usr/share/wam/WebAppMgrCli" +fi + +exec $WAM_CLI_EXE $@ diff --git a/recipes-wam/wam/wam-cef.inc b/recipes-wam/wam/wam-cef.inc new file mode 100644 index 00000000..f0fdcd35 --- /dev/null +++ b/recipes-wam/wam/wam-cef.inc @@ -0,0 +1,40 @@ +SRC_URI:append = " file://0001-agl-cef-Snapshot-with-all-patches-needed-to-enable-w.patch" + +do_configure[depends] += "cef:do_populate_sysroot" + +CEF_ROOT = "${STAGING_DATADIR}/cef" +WAM_OUT_DIR = "${datadir}/wam" + +RUNTIME = "llvm" +TOOLCHAIN = "clang" + +DEPENDS:append:toolchain-clang = " clang-cross-${TARGET_ARCH}" + +PREFERRED_PROVIDER_libgcc = "compiler-rt" + +COMPATIBLE_MACHINE = "(-)" +COMPATIBLE_MACHINE:aarch64 = "(.*)" +COMPATIBLE_MACHINE:armv7 = "(.*)" +COMPATIBLE_MACHINE:armv7a = "(.*)" +COMPATIBLE_MACHINE:armv7ve = "(.*)" +COMPATIBLE_MACHINE:x86 = "(.*)" +COMPATIBLE_MACHINE:x86-64 = "(.*)" + +EXTRA_OECMAKE = "\ + -DPROJECT_ARCH=${TUNE_ARCH} \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${prefix} \ + -DPLATFORM_NAME=${@'${DISTRO}'.upper().replace('-', '_')} \ + -DCEF_ROOT=${CEF_ROOT} \ + -DCMAKE_INSTALL_BINDIR=${WAM_OUT_DIR}" + +do_install:append() { + cp -R --no-dereference --preserve=mode,links -v ${CEF_ROOT}/Release/* ${D}${WAM_OUT_DIR} + cp -R --no-dereference --preserve=mode,links -v ${CEF_ROOT}/Resources/* ${D}${WAM_OUT_DIR} + install -v -D -m 644 ${WORKDIR}/WebAppMgr-cef.env ${D}${sysconfdir}/default/WebAppMgr.env + sed -i -e 's#@WAM_EXE_DIR@#${WAM_OUT_DIR}#g' ${D}${systemd_system_unitdir}/WebAppMgr.service +} + +INSANE_SKIP:${PN} += "already-stripped file-rdeps libdir" + +FILES:${PN} += "${WAM_OUT_DIR}" diff --git a/recipes-wam/wam/wam_git.bb b/recipes-wam/wam/wam_git.bb new file mode 100644 index 00000000..f76641e5 --- /dev/null +++ b/recipes-wam/wam/wam_git.bb @@ -0,0 +1,55 @@ +SUMMARY = "WAM" +AUTHOR = "Jani Hautakangas <jani.hautakangas@lge.com>" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +DEPENDS = "glib-2.0 jsoncpp boost protobuf protobuf-native grpc grpc-native" + +SRC_URI = "\ + git://github.com/igalia/${BPN}.git;branch=@58.agl;protocol=https \ + file://WebAppMgrCli \ + file://WebAppMgr.service \ + file://WebAppMgr.env \ + file://WebAppMgr-cef.env \ +" + +SRCREV = "4fbd6e648913bcf0fba63e4460eb44242c11f71b" + +PV = "ose58.agl" + +S = "${WORKDIR}/git" + +inherit cmake pkgconfig systemd + +# Disable some of security flags +# Disable D_FORTIFY_SOURCE=2 and -fstack-protector-strong +# Refer conf/distro/include/security_flags.inc in meta-webos/conf/distro/include/webos.inc +lcl_maybe_fortify = "" +SECURITY_STACK_PROTECTOR = "" + +SYSTEMD_SERVICE:${PN} = "WebAppMgr.service" + +do_install:append() { + install -v -d ${D}${sysconfdir}/wam + install -v -m 644 ${S}/files/launch/security_policy.conf ${D}${sysconfdir}/wam/security_policy.conf + install -v -D -m 644 ${WORKDIR}/WebAppMgr.service ${D}${systemd_system_unitdir}/WebAppMgr.service + install -v -D -m 755 ${WORKDIR}/WebAppMgrCli ${D}${bindir}/WebAppMgrCli +} + +CXXFLAGS:append:agl-devel = " -DAGL_DEVEL" + +do_install:append:agl-devel() { + # Enable remote inspector and dev mode + install -d ${D}${localstatedir}/agl-devel/preferences + touch ${D}${localstatedir}/agl-devel/preferences/debug_system_apps + touch ${D}${localstatedir}/agl-devel/preferences/devmode_enabled +} + +require wam-cef.inc + +FILES:${PN} += "${sysconfdir}/init \ + ${sysconfdir}/wam \ + ${bindir} \ + ${libdir}/webappmanager/plugins/*.so" + +RDEPENDS:${PN} += " bash grpc-web-proxy" diff --git a/scripts/ci-yocto-check-layer.sh b/scripts/ci-yocto-check-layer.sh new file mode 120000 index 00000000..fa7c110b --- /dev/null +++ b/scripts/ci-yocto-check-layer.sh @@ -0,0 +1 @@ +run-yocto-check-layer.sh
\ No newline at end of file diff --git a/scripts/run-yocto-check-layer.sh b/scripts/run-yocto-check-layer.sh new file mode 100755 index 00000000..0f8e8f97 --- /dev/null +++ b/scripts/run-yocto-check-layer.sh @@ -0,0 +1,62 @@ +#!/bin/bash +#set -x + +SCRIPTPATH="$( cd $(dirname $0) >/dev/null 2>&1 ; pwd -P )" +echo $SCRIPTPATH +AGLROOT="$SCRIPTPATH/../.." +POKYDIR="$AGLROOT/external/poky" +TMPROOT=`mktemp -d` + +rm -rf ${TMPROOT}/testbuild-ycl || true +mkdir -p ${TMPROOT}/testbuild-ycl +cd ${TMPROOT}/testbuild-ycl + +source $POKYDIR/oe-init-build-env . + +cat << EOF >> conf/local.conf +# just define defaults +AGL_FEATURES ?= "" +AGL_EXTRA_IMAGE_FSTYPES ?= "" + +# important settings imported from poky-agl.conf +# we cannot import the distro config right away +# as the initial values are poky only till the layer +# is added in + +AGL_DEFAULT_DISTRO_FEATURES := "usrmerge largefile opengl wayland pam bluetooth bluez5 3g polkit" +DISTRO_FEATURES:append := " systemd wayland pam \${AGL_DEFAULT_DISTRO_FEATURES}" +DISTRO_FEATURES_BACKFILL_CONSIDERED:append = " sysvinit" +VIRTUAL-RUNTIME_init_manager = "systemd" + +# required by meta-flutter/recipes-graphics/toyota/flutter-auto_git.bb" +LICENSE_FLAGS_ACCEPTED += "commercial" + +# Need to ignore as we have more recent version +# meta-openembedded/meta-oe/recipes-graphics/libvncserver/libvncserver_0.9.13.bb +BBMASK += "meta-openembedded/meta-oe/recipes-graphics/libvncserver/libvncserver_*" + +# due to this, we also ignore: +BBMASK += "meta-oe/recipes-support/remmina/remmina_* meta-oe/recipes-graphics/x11vnc/x11vnc_* " + + +EOF + +yocto-check-layer --no-auto-dependency \ + --dependency \ + $AGLROOT/meta-agl/meta-agl-core \ + $AGLROOT/meta-agl/meta-app-framework \ + $AGLROOT/external/meta-openembedded/meta-oe \ + $AGLROOT/external/meta-openembedded/meta-python \ + $AGLROOT/external/meta-openembedded/meta-networking \ + $AGLROOT/external/meta-openembedded/meta-multimedia \ + $AGLROOT/external/meta-flutter \ + $AGLROOT/external/meta-flutter/meta-flutter-apps \ + $AGLROOT/external/meta-qt5 \ + $AGLROOT/external/meta-clang \ + -- \ + $AGLROOT/meta-agl-demo + + +[ $? = 0 ] && rm -rf ${TMPROOT}/testbuild-ycl + +exit 0 diff --git a/templates/feature/agl-cluster-demo-support/50_local.conf.inc b/templates/feature/agl-cluster-demo-support/50_local.conf.inc deleted file mode 100644 index f4724b58..00000000 --- a/templates/feature/agl-cluster-demo-support/50_local.conf.inc +++ /dev/null @@ -1 +0,0 @@ -DISTRO_FEATURES_append = " agl-cluster-demo-support" diff --git a/templates/feature/agl-cluster-demo-support/README_feature_agl-cluster-demo-support.md b/templates/feature/agl-cluster-demo-support/README_feature_agl-cluster-demo-support.md deleted file mode 100644 index bdb04f0b..00000000 --- a/templates/feature/agl-cluster-demo-support/README_feature_agl-cluster-demo-support.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: Feature agl-cluster-demo-support -authors: Scott Murray <scott.murray@konsulko.com> ---- - -### Feature agl-cluster-demo-support - -*Description is missing - please complete file meta-agl-demo/templates/feature/agl-cluster-demo-support/README_feature_agl-cluster-demo-support.md* - -#### Dependent features pulled by agl-cluster-demo-support - -The following features are pulled: - -* agl-gstrecorder - diff --git a/templates/feature/agl-cluster-demo-support/included.dep b/templates/feature/agl-cluster-demo-support/included.dep deleted file mode 100644 index 17ef3ba9..00000000 --- a/templates/feature/agl-cluster-demo-support/included.dep +++ /dev/null @@ -1 +0,0 @@ -agl-gstrecorder diff --git a/templates/feature/agl-container-guest-demo/50_local.conf.inc b/templates/feature/agl-container-guest-demo/50_local.conf.inc new file mode 100644 index 00000000..50f0197e --- /dev/null +++ b/templates/feature/agl-container-guest-demo/50_local.conf.inc @@ -0,0 +1,2 @@ +#see meta-agl-demo/conf/include/agl-container-guest-demo.inc +require conf/include/agl-container-guest-demo.inc diff --git a/templates/feature/agl-container-guest-demo/README_feature_agl-container-guest-demo.md b/templates/feature/agl-container-guest-demo/README_feature_agl-container-guest-demo.md new file mode 100644 index 00000000..c5d74de3 --- /dev/null +++ b/templates/feature/agl-container-guest-demo/README_feature_agl-container-guest-demo.md @@ -0,0 +1,16 @@ +--- +description: Feature agl-container-guest-demo +authors: Naoto Yamaguchi <naoto.yamaguchi@automotivelinux.org> +--- + +### Feature agl-container-guest-demo + +* Enables container guest support for AGL demo images + +### Dependent features pulled by agl-container-guest-demo + +The following features are pulled: + +* agl-demo +* agl-drm-lease + diff --git a/templates/feature/agl-container-guest-demo/included.dep b/templates/feature/agl-container-guest-demo/included.dep new file mode 100644 index 00000000..97ffbec5 --- /dev/null +++ b/templates/feature/agl-container-guest-demo/included.dep @@ -0,0 +1 @@ +agl-demo agl-drm-lease diff --git a/templates/feature/agl-demo-cluster-support/50_local.conf.inc b/templates/feature/agl-demo-cluster-support/50_local.conf.inc new file mode 100644 index 00000000..188d8e8e --- /dev/null +++ b/templates/feature/agl-demo-cluster-support/50_local.conf.inc @@ -0,0 +1 @@ +AGL_FEATURES:append = " agl-demo-cluster-support" diff --git a/templates/feature/agl-demo-cluster-support/README_feature_agl-demo-cluster-support.md b/templates/feature/agl-demo-cluster-support/README_feature_agl-demo-cluster-support.md new file mode 100644 index 00000000..a9ff2cfb --- /dev/null +++ b/templates/feature/agl-demo-cluster-support/README_feature_agl-demo-cluster-support.md @@ -0,0 +1,17 @@ +--- +description: Feature agl-demo-cluster-support +authors: Scott Murray <scott.murray@konsulko.com> +--- + +### Feature agl-demo-cluster-support + +Enables support for remote navigation display on a connected board running +the agl-cluster-demo-platform image. The configuration is in large part +intended for use with the AGL tradeshow demo setup. + +#### Dependent features pulled by agl-demo-cluster-support + +The following features are pulled: + +* agl-weston-remoting + diff --git a/templates/feature/agl-demo-cluster-support/included.dep b/templates/feature/agl-demo-cluster-support/included.dep new file mode 100644 index 00000000..1e9b35fb --- /dev/null +++ b/templates/feature/agl-demo-cluster-support/included.dep @@ -0,0 +1 @@ +agl-weston-remoting diff --git a/templates/feature/agl-demo-soundmanager/50_bblayers.conf.inc b/templates/feature/agl-demo-soundmanager/50_bblayers.conf.inc deleted file mode 100644 index 7e85c574..00000000 --- a/templates/feature/agl-demo-soundmanager/50_bblayers.conf.inc +++ /dev/null @@ -1,5 +0,0 @@ -# This layer contains the WIP feature/demo code only -#--------------------------------------------------- -BBLAYERS =+ " \ - ${METADIR}/meta-agl-demo \ -" diff --git a/templates/feature/agl-demo-soundmanager/50_local.conf.inc b/templates/feature/agl-demo-soundmanager/50_local.conf.inc deleted file mode 100644 index 76626243..00000000 --- a/templates/feature/agl-demo-soundmanager/50_local.conf.inc +++ /dev/null @@ -1,2 +0,0 @@ -#see meta-agl-demo/conf/include/agl-demo.inc -require conf/include/agl-demo.inc diff --git a/templates/feature/agl-demo-soundmanager/README_feature_agl-demo-soundmanager.md b/templates/feature/agl-demo-soundmanager/README_feature_agl-demo-soundmanager.md deleted file mode 100644 index 28feb6eb..00000000 --- a/templates/feature/agl-demo-soundmanager/README_feature_agl-demo-soundmanager.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -description: Feature agl-demo-soundmanager -authors: Stephane Desneux <stephane.desneux@iot.bzh> ---- - -### Feature agl-demo-soundmanager - -*Description is missing - please complete file meta-agl-demo/templates/feature/agl-demo-soundmanager/README_feature_agl-demo-soundmanager.md* - -#### Dependent features pulled by agl-demo-soundmanager - -The following features are pulled: - -* agl-appfw-smack -* agl-hmi-framework -* agl-profile-graphical-qt5 -* agl-audio-soundmanager-framework - diff --git a/templates/feature/agl-demo-soundmanager/included.dep b/templates/feature/agl-demo-soundmanager/included.dep deleted file mode 100644 index b0b94285..00000000 --- a/templates/feature/agl-demo-soundmanager/included.dep +++ /dev/null @@ -1 +0,0 @@ -agl-appfw-smack agl-hmi-framework agl-profile-graphical-qt5 agl-audio-soundmanager-framework diff --git a/templates/feature/agl-demo/50_bblayers.conf.inc b/templates/feature/agl-demo/50_bblayers.conf.inc index 7e85c574..384a3b3f 100644 --- a/templates/feature/agl-demo/50_bblayers.conf.inc +++ b/templates/feature/agl-demo/50_bblayers.conf.inc @@ -3,3 +3,12 @@ BBLAYERS =+ " \ ${METADIR}/meta-agl-demo \ " + +AGL_META_FILESYSTEMS = "${METADIR}/external/meta-openembedded/meta-filesystems" +AGL_META_MULTIMEDIA = "${METADIR}/external/meta-openembedded/meta-multimedia" +AGL_META_NETWORKING = "${METADIR}/external/meta-openembedded/meta-networking" +AGL_META_PYTHON = "${METADIR}/external/meta-openembedded/meta-python" +AGL_META_QT5 = "${METADIR}/external/meta-qt5" + +# Needed to satisfy uutils-coreutils DEPENDS when using SELinux +AGL_META_CLANG = "${METADIR}/external/meta-clang" diff --git a/templates/feature/agl-demo/README_feature_agl-demo.md b/templates/feature/agl-demo/README_feature_agl-demo.md index 76b587ed..31883cd6 100644 --- a/templates/feature/agl-demo/README_feature_agl-demo.md +++ b/templates/feature/agl-demo/README_feature_agl-demo.md @@ -11,8 +11,6 @@ authors: Jan-Simon Möller <jsmoeller@linuxfoundation.org>, Martin Kelly <mkelly The following features are pulled: -* agl-appfw-smack -* agl-hmi-framework * agl-profile-graphical-qt5 * agl-pipewire diff --git a/templates/feature/agl-demo/included.dep b/templates/feature/agl-demo/included.dep index cbf86e8d..e94759e3 100644 --- a/templates/feature/agl-demo/included.dep +++ b/templates/feature/agl-demo/included.dep @@ -1 +1 @@ -agl-appfw-smack agl-hmi-framework agl-profile-graphical-qt5 agl-pipewire agl-speech-framework +agl-pipewire agl-app-framework agl-selinux agl-flutter diff --git a/templates/feature/agl-kvm-host-audio/50_local.conf.inc b/templates/feature/agl-kvm-host-audio/50_local.conf.inc new file mode 100644 index 00000000..7bd20e39 --- /dev/null +++ b/templates/feature/agl-kvm-host-audio/50_local.conf.inc @@ -0,0 +1 @@ +AGL_FEATURES += "agl-kvm-host-audio" diff --git a/templates/feature/agl-kvm-host-audio/README_feature_agl-kvm-host-kuksa.md b/templates/feature/agl-kvm-host-audio/README_feature_agl-kvm-host-kuksa.md new file mode 100644 index 00000000..93a4b9ad --- /dev/null +++ b/templates/feature/agl-kvm-host-audio/README_feature_agl-kvm-host-kuksa.md @@ -0,0 +1,17 @@ +--- +description: Feature agl-kvm-host-audio +authors: Scott Murray <scott.murray@konsulko.com> +--- + +### Feature agl-kvm-host-audio + +* Enables support for running audio services on host in KVM+QEMU demo images + +### Dependent features pulled by agl-kvm-host-audio + +The following features are pulled: + +* agl-kvm agl-kvm-host-kuksa + +Note that enabling this feature results in a configuration where building images +other than agl-kvm-demo-platform will likely not give the desired results. diff --git a/templates/feature/agl-kvm-host-audio/included.dep b/templates/feature/agl-kvm-host-audio/included.dep new file mode 100644 index 00000000..f1f0a2f9 --- /dev/null +++ b/templates/feature/agl-kvm-host-audio/included.dep @@ -0,0 +1 @@ +agl-kvm agl-kvm-host-kuksa diff --git a/templates/feature/agl-kvm-host-kuksa/50_local.conf.inc b/templates/feature/agl-kvm-host-kuksa/50_local.conf.inc new file mode 100644 index 00000000..6259e41f --- /dev/null +++ b/templates/feature/agl-kvm-host-kuksa/50_local.conf.inc @@ -0,0 +1 @@ +AGL_FEATURES += "agl-kvm-host-kuksa" diff --git a/templates/feature/agl-kvm-host-kuksa/README_feature_agl-kvm-host-kuksa.md b/templates/feature/agl-kvm-host-kuksa/README_feature_agl-kvm-host-kuksa.md new file mode 100644 index 00000000..1b607aa3 --- /dev/null +++ b/templates/feature/agl-kvm-host-kuksa/README_feature_agl-kvm-host-kuksa.md @@ -0,0 +1,17 @@ +--- +description: Feature agl-kvm-host-kuksa +authors: Scott Murray <scott.murray@konsulko.com> +--- + +### Feature agl-kvm-host-kuksa + +* Enables support for running KUKSA.val databroker on host in KVM+QEMU demo images + +### Dependent features pulled by agl-kvm-host-kuksa + +The following features are pulled: + +* agl-kvm + +Note that enabling this feature results in a configuration where building images +other than agl-kvm-demo-platform will likely not give the desired results. diff --git a/templates/feature/agl-kvm-host-kuksa/included.dep b/templates/feature/agl-kvm-host-kuksa/included.dep new file mode 100644 index 00000000..b2b1014c --- /dev/null +++ b/templates/feature/agl-kvm-host-kuksa/included.dep @@ -0,0 +1 @@ +agl-kvm diff --git a/templates/feature/agl-kvm/50_bblayers.conf.inc b/templates/feature/agl-kvm/50_bblayers.conf.inc new file mode 100644 index 00000000..e5e39118 --- /dev/null +++ b/templates/feature/agl-kvm/50_bblayers.conf.inc @@ -0,0 +1,4 @@ +AGL_META_PYTHON = "${METADIR}/external/meta-openembedded/meta-python" +AGL_META_NETWORKING = "${METADIR}/external/meta-openembedded/meta-networking" +AGL_META_FILESYSTEMS = "${METADIR}/external/meta-openembedded/meta-filesystems" +AGL_META_VIRTUALIZATION = "${METADIR}/external/meta-virtualization" diff --git a/templates/feature/agl-kvm/50_local.conf.inc b/templates/feature/agl-kvm/50_local.conf.inc new file mode 100644 index 00000000..2798116a --- /dev/null +++ b/templates/feature/agl-kvm/50_local.conf.inc @@ -0,0 +1,2 @@ +#see meta-agl-demo/conf/include/agl-kvm.inc +require conf/include/agl-kvm.inc diff --git a/templates/feature/agl-kvm/README_feature_agl-kvm.md b/templates/feature/agl-kvm/README_feature_agl-kvm.md new file mode 100644 index 00000000..46ab1551 --- /dev/null +++ b/templates/feature/agl-kvm/README_feature_agl-kvm.md @@ -0,0 +1,17 @@ +--- +description: Feature agl-kvm +authors: Scott Murray <scott.murray@konsulko.com> +--- + +### Feature agl-kvm + +* Enables support for building multiconfig based KVM+QEMU demo images + +### Dependent features pulled by agl-kvm + +The following features are pulled: + +* agl-demo + +Note that enabling this feature results in a configuration where building images +other than agl-kvm-demo-platform will likely not give the desired results. diff --git a/templates/feature/agl-kvm/included.dep b/templates/feature/agl-kvm/included.dep new file mode 100644 index 00000000..f61c6e00 --- /dev/null +++ b/templates/feature/agl-kvm/included.dep @@ -0,0 +1 @@ +agl-demo agl-demo-cluster-support agl-demo-preload diff --git a/templates/feature/agl-sdl/50_bblayers.conf.inc b/templates/feature/agl-sdl/50_bblayers.conf.inc deleted file mode 100644 index ebff033b..00000000 --- a/templates/feature/agl-sdl/50_bblayers.conf.inc +++ /dev/null @@ -1,3 +0,0 @@ -BBLAYERS =+ "${METADIR}/external/meta-sdl \ - ${METADIR}/external/meta-openembedded/meta-gnome \ - " diff --git a/templates/feature/agl-sdl/50_local.conf.inc b/templates/feature/agl-sdl/50_local.conf.inc deleted file mode 100644 index 10b81886..00000000 --- a/templates/feature/agl-sdl/50_local.conf.inc +++ /dev/null @@ -1 +0,0 @@ -DISTRO_FEATURES_append = " agl-sdl" diff --git a/templates/feature/agl-sdl/README_feature_agl-sdl.md b/templates/feature/agl-sdl/README_feature_agl-sdl.md deleted file mode 100644 index 47306f45..00000000 --- a/templates/feature/agl-sdl/README_feature_agl-sdl.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: Feature agl-sdl -authors: Jan-Simon Möller <jsmoeller@linuxfoundation.org>, Phong Tran <tranmanphong@gmail.com>, Stephane Desneux <stephane.desneux@iot.bzh> ---- - -### Feature agl-sdl - -*Description is missing - please complete file meta-agl-demo/templates/feature/agl-sdl/README_feature_agl-sdl.md* - |