first commit

This commit is contained in:
2026-03-05 13:07:40 +01:00
commit 64ba0721ee
25709 changed files with 4691006 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
# ChangeLog
##[1.0.6] - 2022-02-03
- Split showing payment methods to two options
##[1.0.5] - 2022-01-26
- Bugfix about BLIK inside the store
##[1.0.4] - 2022-01-25
- Bugfix about featured methods
##[1.0.3] - 2022-01-25
- Add option to clear configuration
##[1.0.2] - 2022-01-19
- Add compatability with WooCommerce Active Payments
- Fix order cancellation if there are custom statuses
- More use of newer Przelewy24 API
##[1.0.1] - 2021-12-27
- fixes for php 8.0
##[1.0.0] - 2021-12-02
- add support for WooCommerce 6

View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser 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
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@@ -0,0 +1,36 @@
=== WooCommerce4 Przelewy24 Payment Gateway ===
Contributors: przelewy24
Donate link: http://www.przelewy24.pl
Tags: woocommerce, Przelewy24, payment, payment gateway, platnosci
Requires at least: 5.0.0
Tested up to: 5.8.2
Stable tag: 1.0.6
License: GPLv3
== Description ==
Przelewy24 Payment Gateway supports:
* Polish online transfers and installments
= Features =
The Przelewy24 Payment Gateway for WooCommerce adds the Przelewy24 payment option and enables you to process the following operations in your shop:
* Creating a payment order
* Updating order status (canceling/completing an order will simultaneously update payment's status)
= Usage =
Przelewy24 Payment Gateway is visible for your customers as a single "Buy and Pay" button during checkout. After clicking the button customer is redirected to the Payment Summary page to choose payment method. After successful payment customer is redirected back to your shop.
== Installation ==
If you do not already have Przelewy24 merchant account [please register](https://www.przelewy24.pl/rejestracja).
In the Wordpress administration panel:
1. Go to **WooCommerce** -> **Settings section**
2. Choose **Checkout** tab and scroll down to the **"Payment Gateways"** section
3. Choose **Settings** option next to the **Przelewy24** name
4. Enable and configure the plugin

View File

@@ -0,0 +1,20 @@
#p24-change-currency-widget {
display: inline-block;
margin-bottom: 2em;
padding: 1em;
border-style: solid;
border-width: 1px;
border-color: black;
border-radius: .2em;
background: white;
color: black;
}
#p24-change-currency-widget label {
display: inline-block;
}
#p24-change-currency-widget select {
background: white;
color: black;
}

View File

@@ -0,0 +1,46 @@
p.p24-info {
max-width: 40em;
}
p.p24-warning {
max-width: 40em;
font-weight: bold;
color: brown;
}
nav.p24-horizontal-tab-menu {
margin-top: 1em;
display: table;
border-spacing: 1em 0;
border-style: solid;
border-color: lightgrey;
border-width: 0 0 1px 0;
font-weight: bold;
}
nav.p24-horizontal-tab-menu a {
text-decoration: none;
color: #555;
}
nav.p24-horizontal-tab-menu span {
color: gray;
}
nav.p24-horizontal-tab-menu a,
nav.p24-horizontal-tab-menu span {
background-color: #e5e5e5;
position: relative;
top: 1px;
display: table-cell;
padding: .4em;
border-style: solid;
border-color: lightgrey;
border-width: 1px 1px 1px 1px;
}
nav.p24-horizontal-tab-menu .active {
background-color: #f1f1f1;
border-bottom-color: #f1f1f1;
color: black;
}

View File

@@ -0,0 +1,33 @@
p.p24-error {
max-width: 40em;
font-weight: bold;
color: red;
}
table.p24-border {
border: solid 2px gray;
}
table.p24-border th,
table.p24-border td
{
border: solid 1px gray;
padding: .3em;
}
form.p24-label-form label {
position: relative;
display: block;
width: 20em;
clear: both;
line-height: 1.4em;
}
form.p24-label-form label input {
float: right;
}
.order-status.status-processing-p24 {
background:#c6e1c6;
color:#5b841b
}

View File

@@ -0,0 +1,633 @@
@font-face {
font-family: 'FontAwesome';
src: url("../fonts/fontawesome-webfont.eot?v=1.0");
src: url("../fonts/fontawesome-webfont.eot?#iefix&v=1.0") format("embedded-opentype"),
url("../fonts/fontawesome-webfont.woff?v=1.0") format("woff"),
url("../fonts/fontawesome-webfont.ttf?v=1.0") format("truetype"),
url("../fonts/fontawesome-webfont.svg?v=1.0#fontawesomeregular") format("svg");
font-weight: normal;
font-style: normal
}
#P24FormAreaHolder {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5);
z-index: 10000;
}
#P24FormAreaHolder > #P24FormArea.popup {
float: none;
box-shadow: 0 0 40px #000;
margin: 0;
position: absolute;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -175px;
padding: 14px;
}
#P24FormArea {
border-radius: 0px;
background: #ffffff;
padding: 1.5em;
margin-bottom: 0.5em;
position: absolute;
}
#P24_cardHolder, #P24_cardNumber {
padding-left: 0.3em;
}
#P24FormContainer {
background-image: url(../images/logo_small.png);
background-repeat: no-repeat;
padding-top: 2em;
background-position: right 10px top;
background-size: 80px;
}
#P24FormContainer a {
border-top: 1px solid #a9a8a8;
padding-top: 1.5em;
display: block;
color: #000000;
-webkit-transition: color 0.25s;
-moz-transition: color 0.25s;
-ms-transition: color 0.25s;
-o-transition: color 0.25s;
transition: color 0.25s;
}
#P24FormContainer a:hover,
#P24FormContainer a:active,
#P24FormContainer a:focus {
color: #a9a8a8;
text-underline: none;
text-decoration: none;
}
#P24FormContainer #register-text {
cursor: pointer;
margin-top: 3px !important;
}
#P24FormContainer #P24_registerCard {
height: 15px;
width: 15px !important;
margin-top: 8px;
cursor: pointer;
}
#P24FormContainer form .loading {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 1000000;
background-color: #ffffff;
background-image: url('../images/loader.gif');
}
#p24-card-alert {
position: absolute;
top: 25%;
left: 30%;
right: 30%;
}
#P24FormContainer form button {
display: inline-block;
font-weight: 400;
line-height: 1.25;
text-align: center;
vertical-align: middle;
cursor: pointer;
user-select: none;
border: 1px solid transparent;
padding: .5rem 1rem;
font-size: 1rem;
border-radius: 0;
color: #fff;
background-color: #2fb5d2;
border-color: transparent;
width: 100%;
margin-top: 1.5em;
margin-left: 0px;
text-transform: uppercase;
}
#P24FormContainer form button:disabled {
cursor: default;
}
#P24FormContainer form button:hover {
color: #fff;
background-color: #2592a9;
border-color: transparent;
}
#P24FormContainer form label {
text-align: left;
margin-bottom: 0px;
width: 44%;
font-weight: 700;
text-transform: uppercase;
font-size: .700rem;
vertical-align: middle;
cursor: auto;
}
#P24FormContainer p input.P24_input_error {
border: 1px dashed #f03737;
}
#p24-card-loader {
width: 150px;
height: 150px;
background-color: #ffffff;
background-image: url('../images/loader.gif');
background-repeat: no-repeat;
background-position: center center;
float: none;
box-shadow: 0 0 40px #000;
margin: 0;
position: absolute;
top: 50%;
left: 50%;
margin-top: -75px;
margin-left: -75px;
z-index: 100;
}
#P24_cardNumber,
#P24_cardHolder {
max-width: 200px;
}
#P24_cardCVV {
max-width: 73px;
}
#P24FormContainer form p:not(:last-of-type) {
margin-bottom: 10px;
}
#P24FormContainer form p:last-of-type {
margin-bottom: 0px;
}
#P24FormContainer form p.italic {
color: #000000;
font-style: italic;
margin-bottom: 1.5em !important;
padding-left: 0px !important;
font-size: 1rem;
font-weight: 700;
border-bottom: 1px solid #a9a8a8;
padding-bottom: 1.5em;
}
#P24FormContainer form input {
padding-left: 10px;
padding-right: 20px;
color: #555555;
width: 56%;
font-size: 0.750rem;
background: #ffffff;
border: 1px dashed #afafaf;
}
#P24FormContainer form input:focus {
box-shadow: 0 0 5px #000;
border: 1px dashed transparent;
}
#P24FormContainer label {
cursor: none;
}
#P24FormContainer input {
border: none;
height: 23px;
}
#P24FormArea span.info {
margin: 3em 0;
display: block;
text-align: center;
}
.p24-register-card-wrapper, .p24-register-card-row {
position: relative;
min-height: 55px;
}
.p24-register-card-row form {
padding: 8px;
border-radius: 4px;
background: #fff;
}
.p24-register-card-form {
display: none;
}
.p24-register-card-row form label {
width: 100%;
text-align: left;
}
#P24_expMonth {
margin-right: 5px;
}
#P24_expYear {
margin-left: 5px;
}
.p24-register-card-row form #P24_cardCVV, #P24_expMonth, #P24_expYear {
max-width: 67px;
display: inline-block;
}
#uniform-p24_regulation_accept {
display: inline-block;
}
#przelewy24lastmethod_img.inactive, a.bank-box.inactive, .inactive {
opacity: 0.5;
-webkit-filter: grayscale(1);
-moz-filter: grayscale(1);
-ms-filter: grayscale(1);
-o-filter: grayscale(1);
filter: grayscale(1);
filter: gray;
}
label {
cursor: pointer;
cursor: hand;
}
a.bank-box.selected:before {
font-family: FontAwesome;
content: "\f00c";
font-size: 4em;
color: #db2032;
margin: -18px 0 0 30px;
position: absolute;
z-index: 2;
}
@font-face {
font-family: 'FontAwesome';
src: url("../fonts/fontawesome-webfont.eot?v=4.1.0");
src: url("../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0") format("embedded-opentype"),
url("../fonts/fontawesome-webfont.woff?v=4.1.0") format("woff"),
url("../fonts/fontawesome-webfont.ttf?v=4.1.0") format("truetype"),
url("../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular") format("svg");
font-weight: normal;
font-style: normal
}
.payMethodList li {
display: inline-block;
width: 49%;
}
.bank-box.recurring .bank-logo {
background: transparent url(../images/cc_empty.png) center 8px no-repeat;
}
.bank-box.recurring .bank-logo > span {
top: 27px;
position: relative;
background-color: #fff;
background-color: rgba(255, 255, 255, 0.5);
padding: 0 2px;
}
.bank-box.recurring .bank-logo-visa, .bank-box.recurring .bank-logo-93d207a5540aa38f404ae593385a7b64 { /* VISA */
background: transparent url(../images/cc_visa.png) center 2px no-repeat;
}
.bank-box.recurring .bank-logo-ecmc, .bank-box.recurring .bank-logo-b05c23fab98df11c755ba516f5df83c0 { /* ECMC */
background: transparent url(../images/cc_mastercard.png) center 2px no-repeat;
}
.bank-box.recurring .bank-logo-maestro, .bank-box.recurring .bank-logo-b4d6cac88f89a1862d9068f831eef183 { /* Maestro-Intl.*/
background: transparent url(../images/cc_maestro.png) center 2px no-repeat;
}
.bank-box.recurring .bank-logo-dc, .bank-box.recurring .bank-logo-8cf5364c4259be0f1a5010e052991c0e { /* Diners Club */
background: transparent url(../images/cc_dinersclub.png) center 2px no-repeat;
}
.moreStuff {
text-align: center;
border-bottom: 1px solid #ccc;
width: 100%;
max-width: 600px;
margin-bottom: 2em;
cursor: pointer;
cursor: hand;
}
.moreStuff:before {
font-family: FontAwesome;
content: "\f078 więcej metod płatności \f078";
text-align: center;
color: #fff;
border: 2px solid #ccc;
padding: 0.1em;
border-radius: 3px;
position: relative;
top: 8px;
cursor: pointer;
cursor: hand;
background: #ccc;
}
.moreStuff:hover {
border-color: #bbb;
}
.moreStuff:hover:before {
border-color: #bbb;
background: #bbb;
}
.bank-placeholder {
opacity: 0.6;
}
.sortable.available .bank-box:last-child {
clear: both;
}
.sortable.selected .bank-box {
position: relative;
z-index: 2;
}
.bank-box.ui-sortable-helper, .bank-box-extra.ui-sortable-helper {
transform: rotate(10deg);
box-shadow: 10px 10px 10px lightgray;
}
.ui-helper-unrotate {
transform: rotate(0deg) !important;
box-shadow: 0 0 0 lightgray !important;
}
.bank-box-extra{
box-shadow: 10px 10px 10px lightgray;
height: 150px;
width: 420px;
}
.bank-box {
transition: transform 0.2s ease, box-shadow 0.2s ease;
float: left;
width: 135px;
height: 71px;
margin-left: 4px;
margin-top: 5px;
padding: 0px 0;
text-align: center;
border: 1px solid #eee;
cursor: pointer;
cursor: hand;
background: white;
}
.bank-box:hover {
box-shadow: 0 0 2px rgba(0, 0, 0, 0.27);
text-decoration: none !important;
}
.bank-logo {
background-position: center center;
background-repeat: no-repeat;
background-size: 120px 35px;
width: 137px;
height: 50px;
font-size: 9px;
}
.bank-name {
color: gray;
height: 30px;
font-size: 9px;
}
.bank-box-extra {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
div .bank-box-extra {
text-align: center;
}
a.bank-box, a.bank-box-extra {
text-decoration: none;
}
a.bank-box {
text-decoration: none;
}
.removecc:before {
content: "\f014";
font-family: FontAwesome;
color: gray;
}
.bank-box.bank-item.recurring, .bank-box-extra.bank-item.recurring {
position: relative;
}
.bank-box.bank-item .removecc {
position: absolute;
right: 3px;
visibility: hidden;
}
.bank-box-extra.bank-item .removecc {
position: absolute;
right: 3px;
visibility: hidden;
}
.bank-box.bank-item.recurring:hover .removecc {
visibility: visible;
}
.bank-box-extra.bank-item.recurring:hover .removecc {
visibility: visible;
}
.input-box.bank-item .removecc {
margin-left: 0.5em;
cursor: pointer;
}
.mobile a.bank-box.selected:before {
margin-left: -15px;
}
.mobile a.bank-box-extra.selected:before {
margin-left: -15px;
}
.loading {
background: transparent url(../images/loadingAnimation.gif) center center no-repeat;
min-height: 60px;
}
.input-box.bank-item input {
margin: 0 0.5em 0 0;
display: inline-block;
}
.checkoutView.payMethodList {
display: inline-block;
width: 100%;
}
.payMethodList {
margin-bottom: 10px;
}
#my-stored-cards .ccbox {
background: #fbfbfb;
border: 1px solid #d6d4d4;
padding: 1em;
margin: 1em;
width: 40%;
display: inline-block;
}
#my-stored-cards .ccbox:nth-child(odd) {
margin-left: 1%;
}
#p24-blik-modal-background {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 10000;
}
#p24-blik-modal-background > #p24-blik-modal-holder {
display: flex;
height: 100%;
align-items: center;
justify-content: center;
}
#p24-blik-modal {
position: relative;
border-radius: 2em;
overflow: hidden;
background-color: white;
}
#p24-blik-modal.loading {
background-position: center center;
background-repeat: no-repeat;
}
#p24-blik-modal h1 {
font-weight: bold;
font-size: 2em;
text-transform: uppercase;
background-color: whitesmoke;
color: black;
margin: 0;
padding: .7em 2em;
text-align: center;
}
#p24-blik-modal .close-modal {
position: absolute;
font-size: 2em;
top: .5em;
right: .5em;
}
#p24-blik-modal.loading form > div {
visibility: hidden;
}
#p24-blik-modal p {
text-align: center;
margin: 1em;
}
#p24-blik-modal input[type="text"] {
border: solid 1px silver;
border-radius: .3em;
font-family: monospace;
font-weight: bold;
letter-spacing: .1em;
text-align: center;
font-size: 3em;
width: 7em;
padding: .4em 1em;
}
#p24-blik-modal button {
color: white;
background-color: dimgrey;
text-transform: uppercase;
font-size: 1.4em;
padding: .5em 1em;
border-style: none;
border-radius: 1em;
}
#p24-blik-modal .error {
display: none;
color: darkred;
}
.text-center {
text-align: center;
}
.align-center {
margin: 0 auto;
width: 50%;
}
.extra-promoted-box {
width: 50%;
margin: 0 auto;
transform: scale(1.2);
cursor: pointer;
box-shadow: 0 0 0 1px rgba(136, 136, 136, 0.2);
margin-bottom: 0.8em;
vertical-align: center;
}
.extra-promoted-box:hover {
cursor: pointer;
box-shadow: 0 0 0 2px rgba(136, 136, 136, 0.2);
}
.extra-promoted-box.selected::before {
font-family: FontAwesome;
content: "\f00c";
font-size: 4em;
color: #db2032;
margin: -18px 0 0 30px;
position: absolute;
z-index: 2;
}
.woocommerce-checkout-payment [class^="payment_method_przelewy24"] label img, .woocommerce-checkout-payment [class*=" payment_method_przelewy24"] label img {
max-height: 50px;
}

View File

@@ -0,0 +1,504 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
<font id="fontawesomeregular" horiz-adv-x="1536" >
<font-face units-per-em="1792" ascent="1536" descent="-256" />
<missing-glyph horiz-adv-x="448" />
<glyph unicode=" " horiz-adv-x="448" />
<glyph unicode="&#x09;" horiz-adv-x="448" />
<glyph unicode="&#xa0;" horiz-adv-x="448" />
<glyph unicode="&#xa8;" horiz-adv-x="1792" />
<glyph unicode="&#xa9;" horiz-adv-x="1792" />
<glyph unicode="&#xae;" horiz-adv-x="1792" />
<glyph unicode="&#xb4;" horiz-adv-x="1792" />
<glyph unicode="&#xc6;" horiz-adv-x="1792" />
<glyph unicode="&#xd8;" horiz-adv-x="1792" />
<glyph unicode="&#x2000;" horiz-adv-x="768" />
<glyph unicode="&#x2001;" horiz-adv-x="1537" />
<glyph unicode="&#x2002;" horiz-adv-x="768" />
<glyph unicode="&#x2003;" horiz-adv-x="1537" />
<glyph unicode="&#x2004;" horiz-adv-x="512" />
<glyph unicode="&#x2005;" horiz-adv-x="384" />
<glyph unicode="&#x2006;" horiz-adv-x="256" />
<glyph unicode="&#x2007;" horiz-adv-x="256" />
<glyph unicode="&#x2008;" horiz-adv-x="192" />
<glyph unicode="&#x2009;" horiz-adv-x="307" />
<glyph unicode="&#x200a;" horiz-adv-x="85" />
<glyph unicode="&#x202f;" horiz-adv-x="307" />
<glyph unicode="&#x205f;" horiz-adv-x="384" />
<glyph unicode="&#x2122;" horiz-adv-x="1792" />
<glyph unicode="&#x221e;" horiz-adv-x="1792" />
<glyph unicode="&#x2260;" horiz-adv-x="1792" />
<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
<glyph unicode="&#xf000;" horiz-adv-x="1792" d="M93 1350q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78z" />
<glyph unicode="&#xf001;" d="M0 -64q0 50 34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5 q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89z" />
<glyph unicode="&#xf002;" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
<glyph unicode="&#xf003;" horiz-adv-x="1792" d="M0 32v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5 t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768zM128 1120q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317 q54 43 100.5 115.5t46.5 131.5v11v13.5t-0.5 13t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5z" />
<glyph unicode="&#xf004;" horiz-adv-x="1792" d="M0 940q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138z " />
<glyph unicode="&#xf005;" horiz-adv-x="1664" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48z" />
<glyph unicode="&#xf006;" horiz-adv-x="1664" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354 q-25 27 -25 48zM221 829l306 -297l-73 -421l378 199l377 -199l-72 421l306 297l-422 62l-189 382l-189 -382z" />
<glyph unicode="&#xf007;" horiz-adv-x="1408" d="M0 131q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5q0 -120 -73 -189.5t-194 -69.5 h-874q-121 0 -194 69.5t-73 189.5zM320 1024q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5z" />
<glyph unicode="&#xf008;" horiz-adv-x="1920" d="M0 -96v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 64v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45zM128 320q0 -26 19 -45t45 -19h128 q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM128 704q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM128 1088q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19 h-128q-26 0 -45 -19t-19 -45v-128zM512 -64q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512zM512 704q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512zM1536 64 v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45zM1536 320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM1536 704q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM1536 1088q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128z" />
<glyph unicode="&#xf009;" horiz-adv-x="1664" d="M0 128v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM0 896v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM896 128v384q0 52 38 90t90 38h512q52 0 90 -38 t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM896 896v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90z" />
<glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M0 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68zM640 1120v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 608v192 q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 1120v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68z" />
<glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M0 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 96v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68zM640 608v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68zM640 1120v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68z" />
<glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M121 608q0 40 28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68t-28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68z" />
<glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M110 214q0 40 28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68t-28 -68l-294 -294l294 -294q28 -28 28 -68t-28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294 q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68z" />
<glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90t-37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM384 672v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224q13 0 22.5 -9.5t9.5 -22.5v-64 q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf010;" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90t-37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM384 672v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf011;" d="M0 640q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181 q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298zM640 768v640q0 52 38 90t90 38t90 -38t38 -90v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90z" />
<glyph unicode="&#xf012;" horiz-adv-x="1792" d="M0 -96v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM384 -96v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM768 -96v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576 q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1152 -96v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1536 -96v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf013;" d="M0 531v222q0 12 8 23t19 13l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10 q129 -119 165 -170q7 -8 7 -22q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108 q-44 -23 -91 -38q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5z M512 640q0 -106 75 -181t181 -75t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181z" />
<glyph unicode="&#xf014;" horiz-adv-x="1408" d="M0 1056v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23zM256 76q0 -22 7 -40.5 t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5v948h-896v-948zM384 224v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM640 224v576q0 14 9 23t23 9h64 q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23zM896 224v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf015;" horiz-adv-x="1664" d="M26 636.5q1 13.5 11 21.5l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5zM256 64 v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf016;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22 v-376z" />
<glyph unicode="&#xf017;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 544v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf018;" horiz-adv-x="1920" d="M50 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256 q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73zM809 540q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4z" />
<glyph unicode="&#xf019;" horiz-adv-x="1664" d="M0 96v320q0 40 28 68t68 28h465l135 -136q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68zM325 985q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39q17 -41 -14 -70 l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70zM1152 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM1408 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf01a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM418 620q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35z" />
<glyph unicode="&#xf01b;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM416 672q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf01c;" d="M0 64v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552q25 -61 25 -123v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM197 576h316l95 -192h320l95 192h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8 t-2.5 -8z" />
<glyph unicode="&#xf01d;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 320v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55t-32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56z" />
<glyph unicode="&#xf01e;" d="M0 640q0 156 61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5 t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298z" />
<glyph unicode="&#xf021;" d="M0 0v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129 q-19 -19 -45 -19t-45 19t-19 45zM18 800v7q65 268 270 434.5t480 166.5q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179 q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf022;" horiz-adv-x="1792" d="M0 160v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM128 160q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832z M256 288v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 544v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z M256 800v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 288v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5z M512 544v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5zM512 800v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5z " />
<glyph unicode="&#xf023;" horiz-adv-x="1152" d="M0 96v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68zM320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192z" />
<glyph unicode="&#xf024;" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110zM320 320v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19 q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf025;" horiz-adv-x="1664" d="M0 650q0 151 67 291t179 242.5t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32 q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32 q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314z" />
<glyph unicode="&#xf026;" horiz-adv-x="768" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf027;" horiz-adv-x="1152" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45zM908 464q0 21 12 35.5t29 25t34 23t29 35.5t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5 q15 0 25 -5q70 -27 112.5 -93t42.5 -142t-42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5z" />
<glyph unicode="&#xf028;" horiz-adv-x="1664" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45zM908 464q0 21 12 35.5t29 25t34 23t29 35.5t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5 q15 0 25 -5q70 -27 112.5 -93t42.5 -142t-42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5zM1008 228q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5 q140 -59 225 -188.5t85 -282.5t-85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45zM1109 -7q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19 q13 0 26 -5q211 -91 338 -283.5t127 -422.5t-127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf029;" horiz-adv-x="1408" d="M0 0v640h640v-640h-640zM0 768v640h640v-640h-640zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM256 256v128h128v-128h-128zM256 1024v128h128v-128h-128zM768 0v640h384v-128h128v128h128v-384h-384v128h-128v-384h-128zM768 768v640h640v-640h-640z M896 896h384v384h-384v-384zM1024 0v128h128v-128h-128zM1024 1024v128h128v-128h-128zM1280 0v128h128v-128h-128z" />
<glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M0 0v1408h63v-1408h-63zM94 1v1407h32v-1407h-32zM189 1v1407h31v-1407h-31zM346 1v1407h31v-1407h-31zM472 1v1407h62v-1407h-62zM629 1v1407h31v-1407h-31zM692 1v1407h31v-1407h-31zM755 1v1407h31v-1407h-31zM880 1v1407h63v-1407h-63zM1037 1v1407h63v-1407h-63z M1163 1v1407h63v-1407h-63zM1289 1v1407h63v-1407h-63zM1383 1v1407h63v-1407h-63zM1541 1v1407h94v-1407h-94zM1666 1v1407h32v-1407h-32zM1729 0v1408h63v-1408h-63z" />
<glyph unicode="&#xf02b;" d="M0 864v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117zM192 1088q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5z" />
<glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M0 864v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117zM192 1088q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5zM704 1408h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5z" />
<glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M10 184q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23 t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57 q38 -15 59 -43q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5zM575 1056 q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
<glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M0 7v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62z" />
<glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M0 160v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v160h-224 q-13 0 -22.5 9.5t-9.5 22.5zM384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1408 576q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf030;" horiz-adv-x="1920" d="M0 128v896q0 106 75 181t181 75h224l51 136q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181zM512 576q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM672 576q0 119 84.5 203.5t203.5 84.5t203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5z" />
<glyph unicode="&#xf031;" horiz-adv-x="1664" d="M0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8 t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27 q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14zM555 527q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452z" />
<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68.5 -0.5t67.5 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5 t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12zM533 1292q0 -50 4 -151t4 -152q0 -27 -0.5 -80 t-0.5 -79q0 -46 1 -69q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13zM538.5 165q0.5 -37 4.5 -83.5t12 -66.5q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25 t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5z" />
<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q6 2 81.5 21.5t111.5 37.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M0 1023v383l81 1l54 -27q12 -5 211 -5q44 0 132 2t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5 q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9 t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44zM1414 109.5q9 18.5 42 18.5h80v1024 h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5z" />
<glyph unicode="&#xf035;" d="M0 1023v383l81 1l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1 t-103 1t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29 t78 27q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44zM5 -64q0 28 26 49q4 3 36 30t59.5 49 t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5q12 0 42 -19.5t57.5 -41.5t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5 t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49z" />
<glyph unicode="&#xf036;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 448v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM0 832v128q0 26 19 45t45 19h1536 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM0 1216v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf037;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM128 832v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM384 448v128q0 26 19 45t45 19h896 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45zM512 1216v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf038;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM128 832v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM384 448v128q0 26 19 45t45 19h1280 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM512 1216v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf039;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 448v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 832v128q0 26 19 45t45 19h1664 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 1216v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5zM0 416v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 t-9.5 22.5zM0 800v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5zM0 1184v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192 q-13 0 -22.5 9.5t-9.5 22.5zM384 32v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 416v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 800v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 1184v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192 q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM0 1184v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5 t-9.5 22.5zM32 704q0 14 9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23zM640 416v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088 q-13 0 -22.5 9.5t-9.5 22.5zM640 800v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM0 416v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23t-9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5z M0 1184v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM640 416v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5 t-9.5 22.5zM640 800v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M0 288v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5q39 -17 39 -59v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5 t-84.5 203.5z" />
<glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216z M256 128v192l320 320l160 -160l512 512l416 -416v-448h-1408zM256 960q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136z" />
<glyph unicode="&#xf040;" d="M0 -128v416l832 832l416 -416l-832 -832h-416zM128 128h128v-128h107l91 91l-235 235l-91 -91v-107zM298 384q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17zM896 1184l166 165q36 38 90 38q53 0 91 -38l235 -234 q37 -39 37 -91q0 -53 -37 -90l-166 -166z" />
<glyph unicode="&#xf041;" horiz-adv-x="1024" d="M0 896q0 212 150 362t362 150t362 -150t150 -362q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179zM256 896q0 -106 75 -181t181 -75t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181z" />
<glyph unicode="&#xf042;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73v1088q-148 0 -273 -73t-198 -198t-73 -273z" />
<glyph unicode="&#xf043;" horiz-adv-x="1024" d="M0 512q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275q0 -212 -150 -362t-362 -150t-362 150t-150 362zM256 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69z" />
<glyph unicode="&#xf044;" horiz-adv-x="1792" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29v-190 q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM640 256v288l672 672l288 -288l-672 -672h-288zM736 448h96v-96h56l116 116l-152 152l-116 -116v-56zM944 688q16 -16 33 1l350 350q17 17 1 33t-33 -1l-350 -350q-17 -17 -1 -33zM1376 1280l92 92 q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68l-92 -92z" />
<glyph unicode="&#xf045;" horiz-adv-x="1664" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h255q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29v-259 q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM256 704q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45l-384 -384 q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5t-38.5 114t-17.5 122z" />
<glyph unicode="&#xf046;" horiz-adv-x="1664" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3 q20 -8 20 -29v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM257 768q0 33 24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110q24 -24 24 -57t-24 -57l-814 -814q-24 -24 -57 -24t-57 24l-430 430 q-24 24 -24 57z" />
<glyph unicode="&#xf047;" horiz-adv-x="1792" d="M0 640q0 26 19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45t-19 -45l-256 -256 q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45z" />
<glyph unicode="&#xf048;" horiz-adv-x="1024" d="M0 -64v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf049;" horiz-adv-x="1792" d="M0 -64v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710q19 19 32 13t13 -32v-710q4 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45 t-45 -19h-128q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M122 640q0 26 19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45z" />
<glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M0 -96v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31l-1328 -738q-23 -13 -39.5 -3t-16.5 36z" />
<glyph unicode="&#xf04c;" d="M0 -64v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45zM896 -64v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf04d;" d="M0 -64v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" />
<glyph unicode="&#xf050;" horiz-adv-x="1792" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32v710 q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" />
<glyph unicode="&#xf051;" horiz-adv-x="1024" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" />
<glyph unicode="&#xf052;" horiz-adv-x="1538" d="M1 64v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM1 525q-6 13 13 32l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13z" />
<glyph unicode="&#xf053;" horiz-adv-x="1280" d="M154 704q0 26 19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45z" />
<glyph unicode="&#xf054;" horiz-adv-x="1280" d="M90 128q0 26 19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45z" />
<glyph unicode="&#xf055;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 576q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19 t19 45v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128z" />
<glyph unicode="&#xf056;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 576q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19 t-19 -45v-128z" />
<glyph unicode="&#xf057;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM387 414q0 -27 19 -46l90 -90q19 -19 46 -19q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19 l90 90q19 19 19 46q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45z" />
<glyph unicode="&#xf058;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 621q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45q0 28 -18 46l-91 90 q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46z" />
<glyph unicode="&#xf059;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM417 939q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26 t37.5 -59q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213zM640 160q0 -14 9 -23t23 -9 h192q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192z" />
<glyph unicode="&#xf05a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM512 160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320 q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160zM640 1056q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160z" />
<glyph unicode="&#xf05b;" d="M0 576v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143 q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45zM339 512q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5h-109q-26 0 -45 19 t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109z" />
<glyph unicode="&#xf05c;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM429 480q0 13 10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23l-137 -137l137 -137q10 -10 10 -23t-10 -23l-146 -146q-10 -10 -23 -10t-23 10l-137 137 l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23z" />
<glyph unicode="&#xf05d;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM346 640q0 26 19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45z" />
<glyph unicode="&#xf05e;" d="M0 643q0 157 61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5t-61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61t-245 164t-163.5 246t-61 300zM224 643q0 -162 89 -299l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199 t-73 -274zM471 185q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5q0 161 -87 295z" />
<glyph unicode="&#xf060;" d="M64 576q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5t32.5 -90.5v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90 z" />
<glyph unicode="&#xf061;" d="M0 512v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5z" />
<glyph unicode="&#xf062;" horiz-adv-x="1664" d="M53 565q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651q37 -39 37 -91q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75 q-38 38 -38 90z" />
<glyph unicode="&#xf063;" horiz-adv-x="1664" d="M53 704q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90z" />
<glyph unicode="&#xf064;" horiz-adv-x="1792" d="M0 416q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45t-19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123 q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22t-13.5 30t-10.5 24q-127 285 -127 451z" />
<glyph unicode="&#xf065;" d="M0 -64v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23t-10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45zM781 800q0 13 10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448 q26 0 45 -19t19 -45v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23z" />
<glyph unicode="&#xf066;" d="M13 32q0 13 10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23zM768 704v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10 t23 -10l114 -114q10 -10 10 -23t-10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf067;" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68z" />
<glyph unicode="&#xf068;" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68z" />
<glyph unicode="&#xf069;" horiz-adv-x="1664" d="M122.5 408.5q13.5 51.5 59.5 77.5l266 154l-266 154q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5 l-266 -154l266 -154q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5z" />
<glyph unicode="&#xf06a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM624 1126l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5l18 621q0 12 -10 18 q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18zM640 161q0 -13 10 -23t23 -10h192q13 0 22 9.5t9 23.5v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190z" />
<glyph unicode="&#xf06b;" d="M0 544v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68 t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23zM376 1120q0 -40 28 -68t68 -28h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68zM608 180q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5v56v468v192h-320v-192v-468v-56zM870 1024h194q40 0 68 28 t28 68t-28 68t-68 28q-43 0 -69 -31z" />
<glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M0 121q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96 q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5zM384 448q0 -26 19 -45t45 -19q24 0 45 19 q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45t-19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45z" />
<glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M0 -160q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64zM256 640q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100 t113.5 -122.5t72.5 -150.5t27.5 -184q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184z" />
<glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M0 576q0 34 20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69t-20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69zM128 576q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5q-152 236 -381 353 q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353zM592 704q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34t-14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5z" />
<glyph unicode="&#xf070;" horiz-adv-x="1792" d="M0 576q0 38 20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5q16 -10 16 -27q0 -7 -1 -9q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87 q-143 65 -263.5 173t-208.5 245q-20 31 -20 69zM128 576q167 -258 427 -375l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353zM592 704q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34t-14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5zM896 0l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69t-20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95zM1056 286l280 502q8 -45 8 -84q0 -139 -79 -253.5t-209 -164.5z" />
<glyph unicode="&#xf071;" horiz-adv-x="1792" d="M16 61l768 1408q17 31 47 49t65 18t65 -18t47 -49l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126zM752 992l17 -457q0 -10 10 -16.5t24 -6.5h185q14 0 23.5 6.5t10.5 16.5l18 459q0 12 -10 19q-13 11 -24 11h-220 q-11 0 -24 -11q-10 -7 -10 -21zM768 161q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190z" />
<glyph unicode="&#xf072;" horiz-adv-x="1408" d="M0 477q-1 13 9 25l96 97q9 9 23 9q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16 l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23z" />
<glyph unicode="&#xf073;" horiz-adv-x="1664" d="M0 -128v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90zM128 -128h288v288h-288v-288zM128 224 h288v320h-288v-320zM128 608h288v288h-288v-288zM384 1088q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288zM480 -128h320v288h-320v-288zM480 224h320v320h-320v-320zM480 608h320v288h-320 v-288zM864 -128h320v288h-320v-288zM864 224h320v320h-320v-320zM864 608h320v288h-320v-288zM1152 1088q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288zM1248 -128h288v288h-288v-288z M1248 224h288v320h-288v-320zM1248 608h288v288h-288v-288z" />
<glyph unicode="&#xf074;" horiz-adv-x="1792" d="M0 160v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192 h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23zM0 1056v192q0 14 9 23t23 9h224q250 0 410 -225q-60 -92 -137 -273q-22 45 -37 72.5 t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23zM743 353q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192 q-32 0 -85 -0.5t-81 -1t-73 1t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5z" />
<glyph unicode="&#xf075;" horiz-adv-x="1792" d="M0 640q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5t-120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5 t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281z" />
<glyph unicode="&#xf076;" d="M0 576v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5 t-98.5 362zM0 960v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45zM1024 960v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf077;" horiz-adv-x="1792" d="M90 250.5q0 26.5 19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5z" />
<glyph unicode="&#xf078;" horiz-adv-x="1792" d="M90 773.5q0 26.5 19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5z" />
<glyph unicode="&#xf079;" horiz-adv-x="1920" d="M0 704q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45z M640 1120q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20z " />
<glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M0 1216q0 26 19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024 q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45zM384 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM1280 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5 t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
<glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158z" />
<glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5t-0.5 12.5zM73 56q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43 q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43z" />
<glyph unicode="&#xf07d;" horiz-adv-x="768" d="M64 64q0 26 19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45z" />
<glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M0 640q0 26 19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45z" />
<glyph unicode="&#xf080;" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216z M256 128v384h256v-384h-256zM640 128v896h256v-896h-256zM1024 128v640h256v-640h-256zM1408 128v1024h256v-1024h-256z" />
<glyph unicode="&#xf081;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 286q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109 q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4q21 -63 74.5 -104 t121.5 -42q-116 -90 -261 -90q-26 0 -50 3z" />
<glyph unicode="&#xf082;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-192v608h203l30 224h-233v143q0 54 28 83t96 29l132 1v207q-96 9 -180 9q-136 0 -218 -80.5t-82 -225.5v-166h-224v-224h224v-608h-544 q-119 0 -203.5 84.5t-84.5 203.5z" />
<glyph unicode="&#xf083;" horiz-adv-x="1792" d="M0 0v1280q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5zM128 0h1536v128h-1536v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM256 1216h384v128h-384v-128zM512 574 q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM640 574q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM736 576q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9 t9 23t-9 23t-23 9q-66 0 -113 -47t-47 -113z" />
<glyph unicode="&#xf084;" horiz-adv-x="1792" d="M0 752q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41q0 -17 -49 -66t-66 -49 q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5zM192 768q0 -80 56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56 t56 136t-56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136z" />
<glyph unicode="&#xf085;" horiz-adv-x="1920" d="M0 549v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8 q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90 q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5zM384 640q0 -106 75 -181t181 -75 t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181zM1152 58v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31 v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31zM1152 1082v140q0 16 149 31q13 29 30 52 q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71 q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31zM1408 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5q0 52 -38 90t-90 38t-90 -38t-38 -90zM1408 1152q0 -53 37.5 -90.5 t90.5 -37.5t90.5 37.5t37.5 90.5q0 52 -38 90t-90 38t-90 -38t-38 -90z" />
<glyph unicode="&#xf086;" horiz-adv-x="1792" d="M0 768q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257t-94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25 t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224zM616 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5 t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132z" />
<glyph unicode="&#xf087;" d="M0 128v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5zM128 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 128h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5 t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85 t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640z" />
<glyph unicode="&#xf088;" d="M0 512v640q0 53 37.5 90.5t90.5 37.5h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186 q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5zM128 1088q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 512h32q16 0 35.5 -9 t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5 t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640z" />
<glyph unicode="&#xf089;" horiz-adv-x="896" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48z" />
<glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M0 940q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138z M128 940q0 -168 187 -355l581 -560l580 559q188 188 188 356q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5 t-21.5 -143z" />
<glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M0 288v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5q0 -4 1 -20t0.5 -26.5t-3 -23.5 t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5zM384 448v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45t-19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf08c;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM223 1030q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86z M237 122h231v694h-231v-694zM595 122h231v388q0 38 7 56q15 35 45 59.5t74 24.5q116 0 116 -157v-371h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694z" />
<glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M0 320q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19 t-19 45zM416 672q0 -14 9 -23t23 -9t23 9t9 23v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448z" />
<glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832 q-119 0 -203.5 84.5t-84.5 203.5zM685 576q0 13 10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23z" />
<glyph unicode="&#xf090;" d="M0 448v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45t-19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45zM894.5 78.5q0.5 10.5 3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113 t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5q0 4 -1 20t-0.5 26.5z" />
<glyph unicode="&#xf091;" horiz-adv-x="1664" d="M0 928v128q0 40 28 68t68 28h288v96q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91t97.5 -37q75 0 133.5 -45.5 t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143zM128 928q0 -78 94.5 -162t235.5 -113q-74 162 -74 371 h-256v-96zM1206 653q141 29 235.5 113t94.5 162v96h-256q0 -209 -74 -371z" />
<glyph unicode="&#xf092;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204 q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52 t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5h-224q-119 0 -203.5 84.5t-84.5 203.5zM271 315q3 5 13 2 q10 -5 7 -12q-5 -7 -13 -2q-10 5 -7 12zM304 290q6 6 16 -3q9 -11 2 -16q-6 -7 -16 3q-9 11 -2 16zM335 233q-9 13 0 18q9 7 17 -6q9 -12 0 -19q-8 -6 -17 7zM370 206q8 9 20 -3q12 -11 4 -19q-8 -9 -20 3q-13 11 -4 19zM419 168q4 11 19 7q16 -5 13 -16q-4 -12 -19 -6 q-17 4 -13 15zM481 154q0 11 16 11q17 2 17 -11q0 -11 -16 -11q-17 -2 -17 11zM540 158q-2 12 14 15q16 2 18 -9q2 -10 -14 -14t-18 8z" />
<glyph unicode="&#xf093;" horiz-adv-x="1664" d="M0 -32v320q0 40 28 68t68 28h427q21 -56 70.5 -92t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68zM325 936q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69q-17 -40 -59 -40 h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40zM1152 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM1408 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf094;" d="M0 433q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5q0 -165 -70 -327.5 t-196 -288t-281 -180.5q-124 -44 -326 -44q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5zM128 434q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5 q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24 q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5z" />
<glyph unicode="&#xf095;" horiz-adv-x="1408" d="M0 1069q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235 t235 -174q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5 t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5z" />
<glyph unicode="&#xf096;" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832z" />
<glyph unicode="&#xf097;" horiz-adv-x="1280" d="M0 7v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62zM128 38l423 406l89 85l89 -85l423 -406 v1242h-1024v-1242z" />
<glyph unicode="&#xf098;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 905q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5 q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5 t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5z" />
<glyph unicode="&#xf099;" horiz-adv-x="1664" d="M44 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5 q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145z" />
<glyph unicode="&#xf09a;" horiz-adv-x="1024" d="M95 631v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255z" />
<glyph unicode="&#xf09b;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44 l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3 q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5z" />
<glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M0 96v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68z" />
<glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v608h-1664v-608zM128 1024h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600 q-13 0 -22.5 -9.5t-9.5 -22.5v-224zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
<glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M0 192q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 697v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5t259 -181.5q114 -113 181.5 -259t80.5 -306q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5 t-391.5 184.5q-25 2 -41.5 20t-16.5 43zM0 1201v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294q187 -186 294 -425.5t120 -501.5q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102 q-25 1 -42.5 19.5t-17.5 43.5z" />
<glyph unicode="&#xf0a0;" d="M0 160v320q0 25 16 75l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113zM128 160q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-1216 q-13 0 -22.5 -9.5t-9.5 -22.5v-320zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM880 320q0 33 23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5zM1136 320q0 33 23.5 56.5t56.5 23.5 t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5z" />
<glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M0 672v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50 t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113zM768 633q377 -42 768 -341v954q-394 -302 -768 -343v-270z" />
<glyph unicode="&#xf0a2;" horiz-adv-x="1664" d="M0 128q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38 t-38 90zM183 128h1298q-164 181 -246.5 411.5t-82.5 484.5q0 256 -320 256t-320 -256q0 -254 -82.5 -484.5t-246.5 -411.5zM656 0q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16z" />
<glyph unicode="&#xf0a3;" d="M2 435q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70l-53 -186l188 -48 q40 -10 52 -51q10 -42 -20 -70l-138 -135l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53 q-41 -12 -70 19q-31 29 -19 70l53 186l-188 48q-40 10 -52 51z" />
<glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M0 128v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179q0 -105 -75.5 -181 t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5zM128 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 128h32q72 0 167 -32 t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139 q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106q-69 -57 -140 -57h-32v-640z" />
<glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M0 769q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5v-640 q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181zM128 768q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119 q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5 t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5t-39 -89.5zM1536 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf0a6;" d="M0 640q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5t-90.5 -37.5h-640 q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5zM128 640q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140 v-32h640v32q0 72 32 167t64 193.5t32 179.5q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576q-20 0 -48.5 15t-55 33t-68 33t-84.5 15 q-67 0 -97.5 -44.5t-30.5 -115.5zM1152 -64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf0a7;" d="M0 640q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317q0 -142 -77.5 -230t-217.5 -87 l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5zM128 640q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33t55 33t48.5 15v-576q0 -50 38.5 -89 t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112 q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5zM1152 1344q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf0a8;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM251 640q0 -27 18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502 q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45z" />
<glyph unicode="&#xf0a9;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM256 576q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18 l362 362l91 91q18 18 18 45t-18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128z" />
<glyph unicode="&#xf0aa;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 641q0 -27 18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19 t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45t-18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45z" />
<glyph unicode="&#xf0ab;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 639q0 -27 18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45t-18 45l-91 91 q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45z" />
<glyph unicode="&#xf0ac;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM226 979q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18 q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13 q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5 t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13 q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25 t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5 t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4 q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5q15 10 -7 16q-17 5 -43 -12q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8 q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5 q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26 q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5 q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14 q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5 q-16 0 -22 -1q-146 -80 -235 -222zM877 26q0 -6 2 -16q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7 t-10 1.5t-11.5 -7q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5z" />
<glyph unicode="&#xf0ad;" horiz-adv-x="1664" d="M21 0q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90zM256 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM768 960q0 185 131.5 316.5t316.5 131.5q58 0 121.5 -16.5 t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25q0 -39 -23 -106q-47 -134 -164.5 -217.5t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5z" />
<glyph unicode="&#xf0ae;" horiz-adv-x="1792" d="M0 64v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 576v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 1088v256q0 26 19 45t45 19h1664 q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM640 640h1024v128h-1024v-128zM1024 128h640v128h-640v-128zM1280 1152h384v128h-384v-128z" />
<glyph unicode="&#xf0b0;" horiz-adv-x="1408" d="M5 1241q17 39 59 39h1280q42 0 59 -39q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70z" />
<glyph unicode="&#xf0b1;" horiz-adv-x="1792" d="M0 160v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM0 736v384q0 66 47 113t113 47h352v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113v-384h-1792z M640 1280h512v128h-512v-128zM768 512v128h256v-128h-256z" />
<glyph unicode="&#xf0b2;" d="M0 -64v448q0 42 40 59q39 17 69 -14l144 -144l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45 v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19l-144 144l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19 t-19 45z" />
<glyph unicode="&#xf0c0;" horiz-adv-x="1920" d="M0 671q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5zM128 1280q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM256 3q0 53 3.5 103.5 t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5 zM576 896q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5zM1280 1280q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM1327 640q81 117 81 256q0 29 -5 66q66 -23 133 -23 q59 0 119 21.5t97.5 42.5t43.5 21q124 0 124 -353q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128z" />
<glyph unicode="&#xf0c1;" horiz-adv-x="1664" d="M16 1088q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l206 -207q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204t-85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88 q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204zM208 1088q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15t21.5 -21.5t18.5 -19q33 31 33 73 q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67zM911 383q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26l147 146q28 28 28 67q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5 q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73z" />
<glyph unicode="&#xf0c2;" horiz-adv-x="1920" d="M0 448q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z" />
<glyph unicode="&#xf0c3;" horiz-adv-x="1664" d="M115.5 -64.5q-34.5 63.5 21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399l503 -793q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5zM476 384h712l-272 429l-20 31v37v399h-128v-399v-37 l-20 -31z" />
<glyph unicode="&#xf0c4;" horiz-adv-x="1792" d="M1 157q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148q4 -48 -10 -97q4 -1 12 -5 l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56l-507 -398l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207zM168 176q-25 -66 21 -108q39 -36 113 -36q100 0 192 59q81 51 106 117t-21 108q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117zM168 976q25 -66 106 -117q92 -59 192 -59q74 0 113 36q46 42 21 108t-106 117q-92 59 -192 59 q-74 0 -113 -36q-46 -42 -21 -108zM672 448l9 -8q2 -2 7 -6q4 -4 11 -12t11 -12l26 -26l160 96l96 -32l736 576l-128 64l-768 -431v-113zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 576q0 26 19 45t45 19t45 -19 t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1018 391l582 -327l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
<glyph unicode="&#xf0c5;" horiz-adv-x="1792" d="M0 224v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68zM128 256h512v256q0 40 20 88t48 76l316 316v416h-384 v-416q0 -40 -28 -68t-68 -28h-416v-640zM213 1024h299v299zM768 -128h896v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640zM853 640h299v299z" />
<glyph unicode="&#xf0c6;" horiz-adv-x="1408" d="M4 1023q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581 q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776 q-113 115 -113 271z" />
<glyph unicode="&#xf0c7;" d="M0 -32v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 0h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20 t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280zM384 0h768v384h-768v-384zM640 928q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320z" />
<glyph unicode="&#xf0c8;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5z" />
<glyph unicode="&#xf0c9;" d="M0 64v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM0 576v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM0 1088v128q0 26 19 45t45 19h1408 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf0ca;" horiz-adv-x="1792" d="M0 128q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 640q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 1152q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM512 32v192 q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 544v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z M512 1056v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf0cb;" horiz-adv-x="1792" d="M15 438q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105v-159h-362q-6 36 -6 54zM19 -190 l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66zM34 1400l136 127h106v-404h108v-99 h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54zM512 32v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 544v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5v-192 q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 1056v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf0cc;" horiz-adv-x="1792" d="M0 544v64q0 14 9 23t23 9h1728q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23zM384 972q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6l-14 2q-50 149 -103 205 q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743q-28 35 -51 80q-48 97 -48 188zM414 154q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22 q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156z" />
<glyph unicode="&#xf0cd;" d="M0 -32v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-1472q-14 0 -23 -9t-9 -23zM0 1405q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5 t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2 q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195 q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39q-37 2 -45 4z" />
<glyph unicode="&#xf0ce;" horiz-adv-x="1664" d="M0 160v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113zM128 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM128 544q0 -14 9 -23t23 -9h320 q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM128 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM640 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 t-9 -23v-192zM640 544q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM640 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23 v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 544q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192z" />
<glyph unicode="&#xf0d0;" horiz-adv-x="1664" d="M27 160q0 27 18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45t-18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45zM128 1408l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98zM320 1216l196 60l60 196l60 -196l196 -60l-196 -60 l-60 -196l-60 196zM768 1408l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98zM1083 1062l107 -107l293 293l-107 107zM1408 768l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98z" />
<glyph unicode="&#xf0d1;" horiz-adv-x="1792" d="M64 192q0 26 19 45t45 19v320q0 8 -0.5 35t0 38t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45v-1024q0 -15 -4 -26.5t-13.5 -18.5t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5 q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM384 128q0 -52 38 -90t90 -38 t90 38t38 90t-38 90t-90 38t-90 -38t-38 -90zM1280 128q0 -52 38 -90t90 -38t90 38t38 90t-38 90t-90 38t-90 -38t-38 -90z" />
<glyph unicode="&#xf0d2;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63 q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5 q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423z" />
<glyph unicode="&#xf0d3;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5 q-104 0 -194.5 -28.5t-153 -76.5t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118 q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5z" />
<glyph unicode="&#xf0d4;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM276 309q0 -43 18.5 -77.5t48.5 -56.5t69 -37t77.5 -21t76.5 -6q60 0 120.5 15.5t113.5 46t86 82.5t33 117 q0 49 -20 89.5t-49 66.5t-58 47.5t-49 44t-20 44.5t15.5 42.5t37.5 39.5t44 42t37.5 59.5t15.5 82.5q0 60 -22.5 99.5t-72.5 90.5h83l88 64h-265q-85 0 -161 -32t-127.5 -98t-51.5 -153q0 -93 64.5 -154.5t158.5 -61.5q22 0 43 3q-13 -29 -13 -54q0 -44 40 -94 q-175 -12 -257 -63q-47 -29 -75.5 -73t-28.5 -95zM395 338q0 46 25 80t65.5 51.5t82 25t84.5 7.5q20 0 31 -2q2 -1 23 -16.5t26 -19t23 -18t24.5 -22t19 -22.5t17 -26t9 -26.5t4.5 -31.5q0 -76 -58.5 -112.5t-139.5 -36.5q-41 0 -80.5 9.5t-75.5 28.5t-58 53t-22 78z M462 969q0 61 32 104t92 43q53 0 93.5 -45t58 -101t17.5 -107q0 -60 -33 -99.5t-92 -39.5q-53 0 -93 42.5t-57.5 96.5t-17.5 106zM960 672h128v-160h64v160h128v64h-128v128h-64v-128h-128v-64z" />
<glyph unicode="&#xf0d5;" horiz-adv-x="1664" d="M32 182q0 81 44.5 150t118.5 115q131 82 404 100q-32 42 -47.5 74t-15.5 73q0 36 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q77 66 182.5 98t217.5 32h418l-138 -88h-131q74 -63 112 -133t38 -160q0 -72 -24.5 -129.5t-59 -93t-69.5 -65 t-59.5 -61.5t-24.5 -66q0 -36 32 -70.5t77.5 -68t90.5 -73.5t77 -104t32 -142q0 -90 -48 -173q-72 -122 -211 -179.5t-298 -57.5q-132 0 -246.5 41.5t-171.5 137.5q-37 60 -37 131zM218 228q0 -70 35 -123.5t91.5 -83t119 -44t127.5 -14.5q58 0 111.5 13t99 39t73 73 t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -48 2q-53 0 -105 -7t-107.5 -25t-97 -46t-68.5 -74.5t-27 -105.5zM324 1222q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q38 0 78 16.5t66 43.5q53 57 53 159 q0 58 -17 125t-48.5 129.5t-84.5 103.5t-117 41q-42 0 -82.5 -19.5t-65.5 -52.5q-47 -59 -47 -160zM1084 731v108h212v217h105v-217h213v-108h-213v-219h-105v219h-212z" />
<glyph unicode="&#xf0d6;" horiz-adv-x="1920" d="M0 64v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45zM128 384q106 0 181 -75t75 -181h1152q0 106 75 181t181 75v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512zM640 640q0 70 21 142 t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142t-21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142zM762 791l77 -80q42 37 55 57h2v-288h-128v-96h384v96h-128v448h-114z" />
<glyph unicode="&#xf0d7;" horiz-adv-x="1024" d="M0 832q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45z" />
<glyph unicode="&#xf0d8;" horiz-adv-x="1024" d="M0 320q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf0d9;" horiz-adv-x="640" d="M64 640q0 26 19 45l448 448q19 19 45 19t45 -19t19 -45v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45z" />
<glyph unicode="&#xf0da;" horiz-adv-x="640" d="M0 192v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45z" />
<glyph unicode="&#xf0db;" horiz-adv-x="1664" d="M0 32v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h608v1152h-640v-1120zM896 0h608q13 0 22.5 9.5t9.5 22.5v1120h-640v-1152z" />
<glyph unicode="&#xf0dc;" horiz-adv-x="1024" d="M0 448q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45zM0 832q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf0dd;" horiz-adv-x="1024" d="M0 448q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45z" />
<glyph unicode="&#xf0de;" horiz-adv-x="1024" d="M0 832q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf0e0;" horiz-adv-x="1792" d="M0 32v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM0 1098q0 78 41.5 130t118.5 52h1472 q65 0 112.5 -47t47.5 -113q0 -79 -49 -151t-122 -123q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5z" />
<glyph unicode="&#xf0e1;" d="M0 1217q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122zM19 -80v991h330v-991h-330zM531 -80q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5v-568 h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329z" />
<glyph unicode="&#xf0e2;" d="M0 832v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298t-61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12 q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf0e3;" horiz-adv-x="1792" d="M40 736q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18 q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5 q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5 t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68z" />
<glyph unicode="&#xf0e4;" horiz-adv-x="1792" d="M0 384q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29q-141 221 -141 483zM128 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z M320 832q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM710 241q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91l101 382q6 26 -7.5 48.5t-38.5 29.5t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5 t-63 -98.5zM768 1024q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1216 832q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1408 384q0 -53 37.5 -90.5 t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" />
<glyph unicode="&#xf0e5;" horiz-adv-x="1792" d="M0 640q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5t-120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5 t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281zM128 640q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5t-381.5 -69.5 t-282 -187.5t-104.5 -255z" />
<glyph unicode="&#xf0e6;" horiz-adv-x="1792" d="M0 768q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257t-94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25 t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224zM128 768q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52t-286 -52t-211.5 -141t-78.5 -191zM616 132 q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22 t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132z" />
<glyph unicode="&#xf0e7;" horiz-adv-x="896" d="M1 551l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39z" />
<glyph unicode="&#xf0e8;" horiz-adv-x="1792" d="M0 -32v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68z" />
<glyph unicode="&#xf0e9;" horiz-adv-x="1664" d="M0 681q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17 q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5z M384 128q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180zM768 1310v98q0 26 19 45t45 19t45 -19t19 -45v-98q-42 2 -64 2t-64 -2z" />
<glyph unicode="&#xf0ea;" horiz-adv-x="1792" d="M0 96v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88v-672q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68zM256 1312q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5v64 q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64zM768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1280 640h299l-299 299v-299z" />
<glyph unicode="&#xf0eb;" horiz-adv-x="1024" d="M0 960q0 99 44.5 184.5t117 142t164 89t186.5 32.5t186.5 -32.5t164 -89t117 -142t44.5 -184.5q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47q0 -46 -31.5 -71t-77.5 -25 q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268zM128 960q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228 q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134zM480 1088q0 13 9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5 q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf0ec;" horiz-adv-x="1792" d="M0 256q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22zM0 800v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23 t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf0ed;" horiz-adv-x="1920" d="M0 448q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z M512 608q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5z" />
<glyph unicode="&#xf0ee;" horiz-adv-x="1920" d="M0 448q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z M512 672q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24z" />
<glyph unicode="&#xf0f0;" horiz-adv-x="1408" d="M0 131q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89 q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5 t81 -103t47.5 -132.5t24 -138t5.5 -131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190zM256 192q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM320 1024q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5 t-271.5 112.5t-112.5 271.5z" />
<glyph unicode="&#xf0f1;" horiz-adv-x="1408" d="M0 768v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48 q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5 t-131.5 271.5v132q-164 20 -274 128t-110 252zM1152 832q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf0f2;" horiz-adv-x="1792" d="M0 96v832q0 92 66 158t158 66h64v-1280h-64q-92 0 -158 66t-66 158zM384 -128v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128v-1280h-1024zM640 1152h512v128h-512v-128zM1504 -128v1280h64q92 0 158 -66t66 -158v-832q0 -92 -66 -158t-158 -66h-64z " />
<glyph unicode="&#xf0f3;" horiz-adv-x="1664" d="M0 128q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38 t-38 90zM656 0q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16z" />
<glyph unicode="&#xf0f4;" horiz-adv-x="1920" d="M0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM256 480v736q0 26 19 45t45 19h1152q159 0 271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158zM1408 704h64q80 0 136 56t56 136 t-56 136t-136 56h-64v-384z" />
<glyph unicode="&#xf0f5;" horiz-adv-x="1408" d="M0 832v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128 q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111zM768 416v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf0f6;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM384 160v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64 q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM384 416v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM384 672v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
<glyph unicode="&#xf0f7;" horiz-adv-x="1408" d="M0 -192v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM128 -128h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224h384v1536h-1152v-1536zM256 160v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 416v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 928v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 1184v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf0f8;" horiz-adv-x="1408" d="M0 -192v1280q0 26 19 45t45 19h320v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM128 -128h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224h384v1152h-256 v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152zM256 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64 q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 1056q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128 v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320zM768 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf0f9;" horiz-adv-x="1920" d="M64 192q0 26 19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128 q-26 0 -45 19t-19 45zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM384 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM896 800q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192 q14 0 23 9t9 23v224h224q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192zM1280 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" />
<glyph unicode="&#xf0fa;" horiz-adv-x="1792" d="M0 96v832q0 92 66 158t158 66h32v-1280h-32q-92 0 -158 66t-66 158zM352 -128v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160v-1280h-1088zM512 416q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23v192 q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192zM640 1152h512v128h-512v-128zM1536 -128v1280h32q92 0 158 -66t66 -158v-832q0 -92 -66 -158t-158 -66h-32z" />
<glyph unicode="&#xf0fb;" horiz-adv-x="1920" d="M0 512v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93l1 -3q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5 t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8z" />
<glyph unicode="&#xf0fc;" horiz-adv-x="1664" d="M64 1152l32 128h480l32 128h960l32 -192l-64 -32v-800l128 -192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320zM384 768q0 -53 37.5 -90.5t90.5 -37.5h128v384h-256v-256z" />
<glyph unicode="&#xf0fd;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 192q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896z" />
<glyph unicode="&#xf0fe;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 576q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45 v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128z" />
<glyph unicode="&#xf100;" horiz-adv-x="1024" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM429 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23 l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
<glyph unicode="&#xf101;" horiz-adv-x="1024" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM397 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10 l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
<glyph unicode="&#xf102;" horiz-adv-x="1152" d="M77 224q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM77 608q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23 l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
<glyph unicode="&#xf103;" horiz-adv-x="1152" d="M77 672q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM77 1056q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10 l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
<glyph unicode="&#xf104;" horiz-adv-x="640" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
<glyph unicode="&#xf105;" horiz-adv-x="640" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
<glyph unicode="&#xf106;" horiz-adv-x="1152" d="M77 352q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
<glyph unicode="&#xf107;" horiz-adv-x="1152" d="M77 800q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
<glyph unicode="&#xf108;" horiz-adv-x="1920" d="M0 288v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113zM128 544q0 -13 9.5 -22.5 t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832z" />
<glyph unicode="&#xf109;" horiz-adv-x="1920" d="M0 96v96h160h1600h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68zM256 416v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113zM384 416q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5 t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-704zM864 112q0 -16 16 -16h160q16 0 16 16t-16 16h-160q-16 0 -16 -16z" />
<glyph unicode="&#xf10a;" horiz-adv-x="1152" d="M0 160v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-832q-66 0 -113 47t-47 113zM128 288q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM512 128 q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf10b;" horiz-adv-x="768" d="M0 128v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM96 288q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704zM288 1136 q0 -16 16 -16h160q16 0 16 16t-16 16h-160q-16 0 -16 -16zM304 128q0 -33 23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5z" />
<glyph unicode="&#xf10c;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273z" />
<glyph unicode="&#xf10d;" horiz-adv-x="1664" d="M0 192v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136z M896 192v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136z" />
<glyph unicode="&#xf10e;" horiz-adv-x="1664" d="M0 832v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136zM896 832v384 q0 80 56 136t136 56h384q80 0 136 -56t56 -136v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136z" />
<glyph unicode="&#xf110;" horiz-adv-x="1568" d="M0 640q0 66 47 113t113 47t113 -47t47 -113t-47 -113t-113 -47t-113 47t-47 113zM176 1088q0 73 51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5t-51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5zM208 192q0 60 42 102t102 42q59 0 101.5 -42t42.5 -102t-42.5 -102 t-101.5 -42q-60 0 -102 42t-42 102zM608 1280q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM672 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM1136 192q0 46 33 79t79 33t79 -33t33 -79 t-33 -79t-79 -33t-79 33t-33 79zM1168 1088q0 33 23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5zM1344 640q0 40 28 68t68 28t68 -28t28 -68t-28 -68t-68 -28t-68 28t-28 68z" />
<glyph unicode="&#xf111;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5z" />
<glyph unicode="&#xf112;" horiz-adv-x="1792" d="M0 896q0 26 19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101 t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19l-512 512q-19 19 -19 45z" />
<glyph unicode="&#xf113;" horiz-adv-x="1664" d="M0 496q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218q0 -87 -27 -168q136 -160 136 -398q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86t-170 -47.5t-171.5 -22t-167 -4.5 q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331zM224 320q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11 q-152 21 -195 21q-118 0 -187 -84t-69 -204zM384 320q0 40 12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82t-12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82zM1024 320q0 40 12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82t-12.5 -82t-43 -76t-72.5 -34t-72.5 34 t-43 76t-12.5 82z" />
<glyph unicode="&#xf114;" horiz-adv-x="1664" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158zM128 224q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64 q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960z" />
<glyph unicode="&#xf115;" horiz-adv-x="1920" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158zM128 331l256 315q44 53 116 87.5 t140 34.5h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-853zM171 163q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40z " />
<glyph unicode="&#xf116;" horiz-adv-x="1792" />
<glyph unicode="&#xf117;" horiz-adv-x="1792" />
<glyph unicode="&#xf118;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM402 461q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38 q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5q-37 -121 -138 -195t-228 -74t-228 74t-138 195zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
<glyph unicode="&#xf119;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM402 307q37 121 138 195t228 74t228 -74t138 -195q8 -25 -4 -48.5 t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
<glyph unicode="&#xf11a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 448q0 26 19 45t45 19h640q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5 t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
<glyph unicode="&#xf11b;" horiz-adv-x="1920" d="M0 512q0 212 150 362t362 150h896q212 0 362 -150t150 -362t-150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150t-150 362zM192 448q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23v128 q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128zM1152 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1408 640q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" />
<glyph unicode="&#xf11c;" horiz-adv-x="1920" d="M0 128v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5zM128 128h1664v896h-1664v-896zM256 272v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM256 528v96 q0 16 16 16h224q16 0 16 -16v-96q0 -16 -16 -16h-224q-16 0 -16 16zM256 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM512 272v96q0 16 16 16h864q16 0 16 -16v-96q0 -16 -16 -16h-864q-16 0 -16 16zM512 784v96q0 16 16 16h96q16 0 16 -16v-96 q0 -16 -16 -16h-96q-16 0 -16 16zM640 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM768 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM896 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16z M1024 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1152 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1280 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1408 528v96q0 16 16 16h112v240 q0 16 16 16h96q16 0 16 -16v-352q0 -16 -16 -16h-224q-16 0 -16 16zM1536 272v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16z" />
<glyph unicode="&#xf11d;" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64zM320 320v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86 q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56zM448 426 q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599z" />
<glyph unicode="&#xf11e;" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64zM320 320v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86 q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56zM448 426 q205 96 384 110v192q-181 -16 -384 -117v-185zM448 836q215 111 384 118v197q-172 -8 -384 -126v-189zM832 730h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15 t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2q-23 0 -49 -3v-222zM1280 828q148 -42 384 90v189q-169 -91 -306 -91q-45 0 -78 8v-196z" />
<glyph unicode="&#xf120;" horiz-adv-x="1664" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM640 32v64q0 14 9 23t23 9h960q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-960 q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf121;" horiz-adv-x="1920" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM712 -52l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5 l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5zM1293 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
<glyph unicode="&#xf122;" horiz-adv-x="1792" d="M0 896q0 26 19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45l397 -397v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45zM384 896q0 26 19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221 q169 -173 169 -509q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45z" />
<glyph unicode="&#xf123;" horiz-adv-x="1664" d="M2 900.5q9 27.5 54 34.5l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5z M832 310l59 -31l318 -168l-60 355l-12 66l49 47l257 250l-356 52l-66 10l-30 60l-159 322v-963z" />
<glyph unicode="&#xf124;" horiz-adv-x="1408" d="M2 561q-5 22 4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5z" />
<glyph unicode="&#xf125;" horiz-adv-x="1664" d="M0 928v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864 q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23zM512 301l595 595h-595v-595zM557 256h595v595z" />
<glyph unicode="&#xf126;" horiz-adv-x="1024" d="M0 64q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136 q0 -52 -26 -96.5t-70 -69.5q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136zM96 64q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68zM96 1216q0 -40 28 -68 t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68zM736 1088q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68z" />
<glyph unicode="&#xf127;" horiz-adv-x="1664" d="M0 448q0 14 9 23t23 9h320q14 0 23 -9t9 -23t-9 -23t-23 -9h-320q-14 0 -23 9t-9 23zM16 1088q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56l-239 -18l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68 l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204zM128 32q0 13 9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23zM544 -96v320q0 14 9 23t23 9t23 -9t9 -23v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23zM633 364 l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56zM1056 1184v320q0 14 9 23t23 9t23 -9t9 -23v-320 q0 -14 -9 -23t-23 -9t-23 9t-9 23zM1216 1120q0 13 9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23zM1280 960q0 14 9 23t23 9h320q14 0 23 -9t9 -23t-9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf128;" horiz-adv-x="1024" d="M96.5 986q-2.5 15 5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5t-10.5 37.5v45q0 83 65 156.5 t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25zM384 40v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28z" />
<glyph unicode="&#xf129;" horiz-adv-x="640" d="M0 64v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45zM128 1152v192q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-192 q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf12a;" horiz-adv-x="640" d="M98 1344q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45zM128 64v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf12b;" d="M5 0v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258zM1013 713q0 64 26 117t65 86.5 t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80h126v-206h-514l-3 27q-4 28 -4 46z " />
<glyph unicode="&#xf12c;" d="M5 0v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258zM1015 -183q0 64 26 117t65 86.5 t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126v-206h-514l-4 27q-3 45 -3 46z" />
<glyph unicode="&#xf12d;" horiz-adv-x="1920" d="M1.5 146.5q5.5 37.5 30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5zM128 128h768l336 384h-768z" />
<glyph unicode="&#xf12e;" horiz-adv-x="1664" d="M0 0v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5 q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124 q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89 q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1z" />
<glyph unicode="&#xf130;" horiz-adv-x="1152" d="M0 704v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45 t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5zM256 704v512q0 132 94 226t226 94t226 -94t94 -226v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226z" />
<glyph unicode="&#xf131;" horiz-adv-x="1408" d="M13 64q0 13 10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23t-10 -23l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -221 -147.5 -384.5 t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23zM128 704v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113l-101 -101 q-42 103 -42 214zM384 704v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
<glyph unicode="&#xf132;" horiz-adv-x="1280" d="M0 576v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150t-33.5 170.5zM640 79 q119 63 213 137q235 184 235 360v640h-448v-1137z" />
<glyph unicode="&#xf133;" horiz-adv-x="1664" d="M0 -128v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90zM128 -128h1408v1024h-1408v-1024z M384 1088q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288zM1152 1088q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288z" />
<glyph unicode="&#xf134;" horiz-adv-x="1408" d="M3.5 940q-8.5 25 3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96 q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37 zM384 1344q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf135;" horiz-adv-x="1664" d="M36 464l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85 q-3 -1 -9 -1q-14 0 -23 9l-64 64q-17 19 -5 39zM1248 1088q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68z" />
<glyph unicode="&#xf136;" horiz-adv-x="1792" d="M0 0l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334z" />
<glyph unicode="&#xf137;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM346 640q0 -26 19 -45l454 -454q19 -19 45 -19t45 19l102 102q19 19 19 45t-19 45l-307 307l307 307 q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45z" />
<glyph unicode="&#xf138;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM506 288q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l454 454q19 19 19 45t-19 45l-454 454 q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45z" />
<glyph unicode="&#xf139;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM250 544q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19l102 102 q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45z" />
<glyph unicode="&#xf13a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM250 736q0 -26 19 -45l454 -454q19 -19 45 -19t45 19l454 454q19 19 19 45t-19 45l-102 102 q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45z" />
<glyph unicode="&#xf13b;" horiz-adv-x="1408" d="M0 1408h1408l-128 -1438l-578 -162l-574 162zM262 1114l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674l16 175h-884z" />
<glyph unicode="&#xf13c;" horiz-adv-x="1792" d="M12 75l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208l59 297h1505l-266 -1333l-804 -267z" />
<glyph unicode="&#xf13d;" horiz-adv-x="1792" d="M0 0v352q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5 l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30zM832 1280q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
<glyph unicode="&#xf13e;" horiz-adv-x="1152" d="M0 96v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181v-320h736q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28 t-28 68z" />
<glyph unicode="&#xf140;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM256 640q0 212 150 362t362 150t362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362zM384 640q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM512 640q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181z" />
<glyph unicode="&#xf141;" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM512 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM1024 608v192q0 40 28 68t68 28h192 q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68z" />
<glyph unicode="&#xf142;" horiz-adv-x="384" d="M0 96v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h192q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68z" />
<glyph unicode="&#xf143;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 256q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z M256 575q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10t9 24q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128zM256 959q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128 q13 0 23 10q11 9 9 23q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128z" />
<glyph unicode="&#xf144;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM512 320q0 -37 32 -56q16 -8 32 -8q17 0 32 9l544 320q32 18 32 55t-32 55l-544 320q-31 19 -64 1 q-32 -19 -32 -56v-640z" />
<glyph unicode="&#xf145;" horiz-adv-x="1792" d="M54 448.5q0 53.5 37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136t-136 56t-136 -56l-125 126q-37 37 -37 90.5z M342 512q0 -26 19 -45l362 -362q18 -18 45 -18t45 18l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45zM452 512l572 572l316 -316l-572 -572z" />
<glyph unicode="&#xf146;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 576q0 -26 19 -45t45 -19h896q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128 z" />
<glyph unicode="&#xf147;" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832zM256 672v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf148;" horiz-adv-x="1024" d="M3 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18z" />
<glyph unicode="&#xf149;" horiz-adv-x="1024" d="M3 1261q9 19 29 19h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34z" />
<glyph unicode="&#xf14a;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM218 640q0 -26 19 -45l358 -358q19 -19 45 -19t45 19l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19 t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45z" />
<glyph unicode="&#xf14b;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 128h288l544 544l-288 288l-544 -544v-288zM352 320v56l52 52l152 -152l-52 -52h-56v96h-96zM494 494 q-14 13 3 30l291 291q17 17 30 3q14 -13 -3 -30l-291 -291q-17 -17 -30 -3zM864 1024l288 -288l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28z" />
<glyph unicode="&#xf14c;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM282 320q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59 v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45z" />
<glyph unicode="&#xf14d;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 448q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5t224 23.5v-160 q0 -42 40 -59q12 -5 24 -5q26 0 45 19l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5z" />
<glyph unicode="&#xf14e;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 241v542l512 256v-542zM640 448l256 128l-256 128v-256z" />
<glyph unicode="&#xf150;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM391 861q17 35 57 35h640q40 0 57 -35q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66z" />
<glyph unicode="&#xf151;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM391 419q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66q-17 -35 -57 -35h-640q-40 0 -57 35z" />
<glyph unicode="&#xf152;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -14 9 -23t23 -9h960q14 0 23 9t9 23v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960z M512 320v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52t-27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57z" />
<glyph unicode="&#xf153;" horiz-adv-x="1024" d="M0 514v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5 t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5 l12 3l5 2q13 5 26 -2q12 -7 15 -21l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf154;" horiz-adv-x="1024" d="M0 32v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215 h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf155;" horiz-adv-x="1024" d="M52 171l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242 t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48 t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50t53 -63.5t31.5 -76.5t13 -94q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5 t-17.5 18q-17 21 -2 41z" />
<glyph unicode="&#xf156;" horiz-adv-x="898" d="M0 605v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171 q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22z" />
<glyph unicode="&#xf157;" horiz-adv-x="1027" d="M4 1360q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103 q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214z" />
<glyph unicode="&#xf158;" horiz-adv-x="1280" d="M0 256v128q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315t-126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9 h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23zM487 747h320q106 0 171 62t65 162t-65 162t-171 62h-320v-448z" />
<glyph unicode="&#xf159;" horiz-adv-x="1792" d="M0 672v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111 q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23z M373 896l32 -128h225l35 128h-292zM436 640l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5l81 299h-159zM822 768h139l-35 128h-70zM1118 896l34 -128h230l33 128h-297zM1187 640l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3l78 300h-162z" />
<glyph unicode="&#xf15a;" horiz-adv-x="1280" d="M56 0l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89 t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200zM522 182q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30t24.5 40t9.5 51q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1 t-47.5 -1v-338zM522 674q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307z" />
<glyph unicode="&#xf15b;" d="M0 -160v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472z" />
<glyph unicode="&#xf15c;" d="M0 -160v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM384 160q0 -14 9 -23t23 -9h704q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM384 416q0 -14 9 -23t23 -9h704 q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM384 672q0 -14 9 -23t23 -9h704q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472z" />
<glyph unicode="&#xf15d;" horiz-adv-x="1664" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM899 768v106h70l230 662h162l230 -662h70v-106h-288v106h75l-47 144h-243l-47 -144h75v-106 h-287zM988 -166l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121v-233h-584v90zM1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18 t-7.5 -29z" />
<glyph unicode="&#xf15e;" horiz-adv-x="1664" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM899 -150h70l230 662h162l230 -662h70v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287 v106zM988 768v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248v119h121v-233h-584zM1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29 z" />
<glyph unicode="&#xf160;" horiz-adv-x="1792" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM896 -32q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9 t-9 23v192zM896 288v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23zM896 800v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23zM896 1312v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23 v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf161;" horiz-adv-x="1792" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM896 -32q0 14 9 23t23 9h256q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9 t-9 23v192zM896 288v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23zM896 800v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23zM896 1312v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23 v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf162;" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM946 261q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5q0 -62 -13 -121.5t-41 -114 t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5zM976 1351l192 185h123v-654h165v-114h-469v114h167v432q0 7 0.5 19t0.5 17 v16h-2l-7 -12q-8 -13 -26 -31l-62 -58zM1085 261q0 -57 36.5 -95t104.5 -38q50 0 85 27t35 68q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94z" />
<glyph unicode="&#xf163;" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM946 1285q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5q0 -62 -13 -121.5t-41 -114 t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5zM976 327l192 185h123v-654h165v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16 h-2l-7 -12q-8 -13 -26 -31l-62 -58zM1085 1285q0 -57 36.5 -95t104.5 -38q50 0 85 27t35 68q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94z" />
<glyph unicode="&#xf164;" horiz-adv-x="1664" d="M0 64v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45zM128 192q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45zM480 64v641q0 25 18 43.5t43 20.5q24 2 76 59 t101 121q68 87 101 120q18 18 31 48t17.5 48.5t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135 q0 -86 -55 -149q15 -44 15 -76q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5z" />
<glyph unicode="&#xf165;" horiz-adv-x="1664" d="M0 448q0 -26 19 -45t45 -19h288q26 0 45 19t19 45v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640zM128 960q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45zM480 447v641q0 26 19 44.5t45 19.5q35 1 158 44 q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76q55 -61 55 -149q-1 -78 -57.5 -135t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39 t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121t-76 59q-25 2 -43 20.5t-18 43.5z" />
<glyph unicode="&#xf166;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM218 366q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73 q20 84 20 260q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5q-20 -87 -20 -260zM300 551v70h232v-70h-80v-423h-74v423h-78zM396 1313l24 -69t23 -69q35 -103 46 -158v-201h74v201l90 296h-75l-51 -195l-53 195 h-78zM542 205v290h66v-270q0 -24 1 -26q1 -15 15 -15q20 0 42 31v280h67v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54zM654 936q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38q-21 -29 -21 -87v-130zM721 923 v156q0 52 32 52t32 -52v-156q0 -51 -32 -51t-32 51zM790 128v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67zM857 200q16 -16 33 -16q29 0 29 49v157q0 50 -29 50q-17 0 -33 -16v-224zM907 893q0 -37 6 -55 q11 -27 43 -27q36 0 77 45v-40h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293zM1037 247v129q0 59 20 86q29 38 80 38t78 -38q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68v-9q0 -29 -2 -43q-3 -22 -15 -40 q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86zM1103 355h66v34q0 51 -33 51t-33 -51v-34z" />
<glyph unicode="&#xf167;" d="M27 260q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99q-26 112 -26 350zM138 509h105v-569h100v569h107v94h-312 v-94zM266 1536h106l71 -263l68 263h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187zM463 43q0 -49 8 -73q12 -37 58 -37q48 0 102 61v-54h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391zM614 1028v175q0 80 28 117q38 51 105 51 q69 0 106 -51q28 -37 28 -117v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51q-28 38 -28 118zM704 1011q0 -70 43 -70t43 70v210q0 69 -43 69t-43 -69v-210zM798 -60h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89 v-663zM887 36v301q22 22 45 22q39 0 39 -67v-211q0 -67 -39 -67q-23 0 -45 22zM955 971v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75zM1130 100q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54 q2 9 2 58v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51q-28 -37 -28 -116v-173zM1219 245v46q0 68 45 68t45 -68v-46h-90z" />
<glyph unicode="&#xf168;" horiz-adv-x="1408" d="M5 384q-10 17 0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45l164 -286q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17zM536 539q18 32 531 942q25 45 64 45h241q22 0 31 -15q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37 q-10 -15 -32 -15h-239q-42 0 -66 45z" />
<glyph unicode="&#xf169;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM227 396q8 -13 24 -13h185q31 0 50 36l199 352q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29 l125 -216v-1l-196 -346q-9 -14 0 -28zM638 516q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1l409 723q8 16 0 28q-7 12 -24 12h-187q-30 0 -49 -35z" />
<glyph unicode="&#xf16a;" horiz-adv-x="1792" d="M0 640q0 96 1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150t-1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58 t-69.5 123q-14 65 -21.5 147.5t-8.5 136.5t-1 150zM640 320q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54t-30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640z" />
<glyph unicode="&#xf16b;" horiz-adv-x="1792" d="M64 558l338 271l494 -305l-342 -285zM64 1099l490 319l342 -285l-494 -304zM407 166v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284l147 96v-108l-490 -293v-1l-1 1l-1 -1v1zM896 524l494 305l338 -271l-489 -319zM896 1133l343 285l489 -319l-338 -270z" />
<glyph unicode="&#xf16c;" horiz-adv-x="1408" d="M0 -255v736h121v-618h928v618h120v-701l-1 -35v-1h-1132l-35 1h-1zM221 -17v151l707 1v-151zM227 243l14 150l704 -65l-13 -150zM270 563l39 146l683 -183l-39 -146zM395 928l77 130l609 -360l-77 -130zM707 1303l125 86l398 -585l-124 -85zM1136 1510l149 26l121 -697 l-149 -26z" />
<glyph unicode="&#xf16d;" d="M0 69v1142q0 81 58 139t139 58h1142q81 0 139 -58t58 -139v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139zM171 110q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62 q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648zM461 643q0 -124 90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5t-90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5zM1050 1003q0 -29 20 -49t49 -20h174q29 0 49 20t20 49v165q0 28 -20 48.5 t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165z" />
<glyph unicode="&#xf16e;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM274 640q0 -88 62 -150t150 -62t150 62t62 150t-62 150t-150 62t-150 -62t-62 -150zM838 640q0 -88 62 -150 t150 -62t150 62t62 150t-62 150t-150 62t-150 -62t-62 -150z" />
<glyph unicode="&#xf170;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM309 384h94l104 160h522l104 -160h94l-459 691zM567 608l201 306l201 -306h-402z" />
<glyph unicode="&#xf171;" horiz-adv-x="1408" d="M0 1222q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34 t-6 39.5t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158zM173 285l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18t-76.5 27 t-73 43.5t-52 61.5q-25 96 -57 292zM243 1240q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5q-20 27 -56 44.5t-58 22t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43zM481 657q4 -91 77.5 -155t165.5 -56q91 8 152 84 t50 168q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5zM599 710q14 41 52 58q36 18 72.5 12t64 -35.5t27.5 -67.5q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82z" />
<glyph unicode="&#xf172;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM260 1060q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63 q24 13 39.5 23t31 29t19.5 40q48 267 80 473q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54zM385 384q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71q0 7 5.5 26.5t3 32 t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6zM436 1073q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5t-52.5 16t-54.5 32.5zM607 653q-2 49 25.5 93t72.5 64 q70 31 141.5 -10t81.5 -118q8 -66 -36 -121t-110 -61t-119 40t-56 113zM687.5 660.5q0.5 -52.5 43.5 -70.5q39 -23 81 4t36 72q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5z" />
<glyph unicode="&#xf173;" horiz-adv-x="1024" d="M78 779v217q91 30 155 84q64 55 103 132q39 78 54 196h219v-388h364v-241h-364v-394q0 -136 14 -172q13 -37 52 -60q50 -31 117 -31q117 0 232 76v-242q-102 -48 -178 -65q-77 -19 -173 -19q-105 0 -186 27q-78 25 -138 75q-58 51 -79 105q-22 54 -22 161v539h-170z" />
<glyph unicode="&#xf174;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM413 744h127v-404q0 -78 17 -121q17 -42 59 -78q43 -37 104 -57q62 -20 140 -20q67 0 129 14q57 13 134 49v181 q-88 -56 -174 -56q-51 0 -88 23q-29 17 -39 45q-11 30 -11 129v295h274v181h-274v291h-164q-11 -90 -40 -147t-78 -99q-48 -40 -116 -63v-163z" />
<glyph unicode="&#xf175;" horiz-adv-x="768" d="M3 237q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19t-5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35z" />
<glyph unicode="&#xf176;" horiz-adv-x="768" d="M3 1043q-8 19 5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19z" />
<glyph unicode="&#xf177;" horiz-adv-x="1792" d="M64 637q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23z" />
<glyph unicode="&#xf178;" horiz-adv-x="1792" d="M0 544v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf179;" horiz-adv-x="1408" d="M0 634q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32 q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503zM683 1131q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17z" />
<glyph unicode="&#xf17a;" horiz-adv-x="1664" d="M0 -27v557h682v-651zM0 614v565l682 94v-659h-682zM757 -131v661h907v-786zM757 614v669l907 125v-794h-907z" />
<glyph unicode="&#xf17b;" horiz-adv-x="1408" d="M0 337v430q0 42 30 72t73 30q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30t-73 30t-30 73zM241 886q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20l-71 -131q107 -55 171 -153.5t64 -215.5 h-925zM245 184v666h918v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78zM455 1092q0 -16 11 -27.5t27 -11.5t27.5 11.5t11.5 27.5t-11.5 27.5 t-27.5 11.5t-27 -11.5t-11 -27.5zM876 1092q0 -16 11.5 -27.5t27.5 -11.5t27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5zM1203 337v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73z" />
<glyph unicode="&#xf17c;" d="M11 -115q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5 t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195q-12 112 -16 310q-2 90 24 151.5 t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5 t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13 t16.5 -9.5q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5 q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5zM321 495q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54 t7 -70.5q46 24 7 92q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5 t60 -22.5q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18zM372 630q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12zM603 1190q2 -5 5 -6 q10 0 7 -15q-3 -20 8 -20q3 0 3 3q3 17 -2.5 30t-11.5 15q-9 2 -9 -7zM634 1110q0 12 19 15h10q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5zM721 1122q24 11 32 -2q3 -6 -3 -9q-4 -1 -11.5 6.5t-17.5 4.5zM835 1196l4 -2q14 -4 18 -31q0 -3 8 2l2 3q0 11 -5 19.5t-11 12.5 t-9 3q-14 -1 -7 -7zM851 1381.5q-1 -2.5 3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9zM981 1002q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20q-2 8 -6.5 11.5t-13 5 t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5z" />
<glyph unicode="&#xf17d;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM112 640q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81t99.5 48l37 13 q4 1 13 3.5t13 4.5q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21zM126 775q302 0 606 80q-120 213 -244 378q-138 -65 -234 -186t-128 -272zM350 134q184 -150 418 -150q132 0 256 52q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5 t-103 -148zM609 1276q1 1 2 1q-1 0 -2 -1zM613 1277q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5l12.5 17.5q-185 164 -433 164q-76 0 -155 -19zM909 797q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5 t36.5 -6t25 -4.5l10 -2q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5zM1007 565q87 -239 128 -469q111 75 185 189.5t96 250.5q-210 60 -409 29z" />
<glyph unicode="&#xf17e;" d="M0 1024q0 159 112.5 271.5t271.5 112.5q130 0 234 -80q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225 t-55.5 273.5q0 73 16 150q-80 104 -80 234zM376 399q0 -92 122 -157.5t291 -65.5q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12 t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5 q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75z" />
<glyph unicode="&#xf180;" horiz-adv-x="1664" d="M0 640q0 75 53 128l587 587q53 53 128 53t128 -53l265 -265l-398 -399l-188 188q-42 42 -99 42q-59 0 -100 -41l-120 -121q-42 -40 -42 -99q0 -58 42 -100l406 -408q30 -28 67 -37l6 -4h28q60 0 99 41l619 619l2 -3q53 -53 53 -128t-53 -128l-587 -587 q-52 -53 -127.5 -53t-128.5 53l-587 587q-53 53 -53 128zM302 660q0 21 14 35l121 120q13 15 35 15t36 -15l252 -252l574 575q15 15 36 15t36 -15l120 -120q14 -15 14 -36t-14 -36l-730 -730q-17 -15 -37 -15q-4 0 -6 1q-18 2 -30 14l-407 408q-14 15 -14 36z" />
<glyph unicode="&#xf181;" d="M0 -64v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM160 192q0 -14 9 -23t23 -9h480q14 0 23 9t9 23v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024zM832 576q0 -14 9 -23t23 -9h480q14 0 23 9t9 23 v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640z" />
<glyph unicode="&#xf182;" horiz-adv-x="1280" d="M0 480q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192 q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43q-40 0 -68 28t-28 68zM416 1280q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" />
<glyph unicode="&#xf183;" horiz-adv-x="1024" d="M0 416v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68z M288 1280q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" />
<glyph unicode="&#xf184;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM399.5 766q8.5 -37 24.5 -59l349 -473l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5 t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85z" />
<glyph unicode="&#xf185;" horiz-adv-x="1792" d="M44 363q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29q-4 -15 -20 -20 l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20zM320 640q0 -117 45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5 t-45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5z" />
<glyph unicode="&#xf186;" d="M0 640q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384z" />
<glyph unicode="&#xf187;" horiz-adv-x="1792" d="M64 1088v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM128 -64v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM704 704q0 -26 19 -45t45 -19h256 q26 0 45 19t19 45t-19 45t-45 19h-256q-26 0 -45 -19t-19 -45z" />
<glyph unicode="&#xf188;" horiz-adv-x="1664" d="M32 576q0 26 19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19t19 -45t-19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19 t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45z M512 1152q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5h-640z" />
<glyph unicode="&#xf189;" horiz-adv-x="1920" d="M-1 1004q0 11 3 16l4 6q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24 q17 19 38 30q53 26 239 24q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5 t13 3t20 0.5l288 2q39 5 64 -2.5t31 -16.5l6 -10q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12 q-30 21 -70 64t-68.5 77.5t-61 58t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211 t-130.5 272q-6 16 -6 27z" />
<glyph unicode="&#xf18a;" horiz-adv-x="1792" d="M0 391q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5q0 -68 -37 -139.5 t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5zM181 320q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5zM413.5 230.5 q-40.5 92.5 6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5q-45 -102 -158 -150t-224 -12q-107 34 -147.5 126.5zM495 257.5q9 -34.5 43 -50.5t74.5 -2.5t62.5 47.5q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5zM705 399 q-17 -31 13 -45q14 -5 29 0.5t22 18.5q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5zM1165 1274q-6 28 9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158 q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5zM1224 1047q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5t54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37z" />
<glyph unicode="&#xf18b;" d="M0 638q0 187 83.5 349.5t229.5 269.5t325 137v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495zM398 -34q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211q-171 -94 -368 -94q-196 0 -367 94zM898 909v485q179 -30 325 -137t229.5 -269.5 t83.5 -349.5q0 -280 -181 -495q-204 99 -330.5 306.5t-126.5 459.5z" />
<glyph unicode="&#xf18c;" horiz-adv-x="1408" d="M0 -211q0 19 13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23 t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89 t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283 q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32z" />
<glyph unicode="&#xf18d;" horiz-adv-x="1280" d="M21 217v66h1238v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5zM21 354v255h1238v-255h-1238zM21 682v255h1238v-255h-1238zM21 1010v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5v-67h-1238z" />
<glyph unicode="&#xf18e;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM384 544v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5z" />
<glyph unicode="&#xf190;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM384 640q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23z" />
<glyph unicode="&#xf191;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM448 640q0 33 27 52l448 320q17 12 37 12q26 0 45 -19t19 -45v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52z" />
<glyph unicode="&#xf192;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 640q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181z" />
<glyph unicode="&#xf193;" horiz-adv-x="1664" d="M0 320q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5zM416 1348q-2 16 6 42 q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455l198 99l58 -114l-256 -128q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5z" />
<glyph unicode="&#xf194;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 806q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5 q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237q104 139 172.5 292.5t82.5 226.5q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143 q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7z" />
<glyph unicode="&#xf195;" horiz-adv-x="1152" d="M0 608v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31 l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26z" />
<glyph unicode="&#xf196;" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832zM256 672v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf197;" horiz-adv-x="2176" d="M0 576q0 12 38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113q-110 -64 -268 -64h-128v64 h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5zM323 336h29q157 0 273 64h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96zM323 816l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5 t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64h-29zM1739 484l81 -30q68 48 68 122t-68 122l-81 -30q53 -36 53 -92t-53 -92z" />
<glyph unicode="&#xf198;" horiz-adv-x="1664" d="M0 796q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5 t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72 l-55 163l-153 -53q-29 -9 -50 -9q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5zM620 811l105 -313l310 105l-105 315z" />
<glyph unicode="&#xf199;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 352q0 -40 28 -68t68 -28h832q40 0 68 28t28 68v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99 q-98 -69 -164 -69t-164 69q-46 32 -141.5 92.5t-142.5 92.5q-12 8 -33 27t-31 27v-436zM256 928q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13 t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68z" />
<glyph unicode="&#xf19a;" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM41 640q0 -173 68 -331.5t182.5 -273t273 -182.5t331.5 -68t331.5 68t273 182.5t182.5 273t68 331.5 t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5zM127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM254 1062q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5 q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21t14.5 -24t14 -23q63 -107 63 -212q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15 t-1.5 -18.5t9 -16.5t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5zM679 -97l230 670l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1282 -24l235 678q59 169 59 276q0 42 -6 79 q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5z" />
<glyph unicode="&#xf19b;" horiz-adv-x="1792" d="M0 455q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360l272 133v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5zM1134 860v172q277 -33 481 -157l140 79l37 -390l-525 114l147 83 q-119 70 -280 99z" />
<glyph unicode="&#xf19c;" horiz-adv-x="2048" d="M0 -128q0 26 20.5 45t48.5 19h1782q28 0 48.5 -19t20.5 -45v-128h-1920v128zM0 1024v128l960 384l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128zM128 0v64q0 26 20.5 45t48.5 19h59v768h256v-768h128v768h256v-768h128v768h256 v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664z" />
<glyph unicode="&#xf19d;" horiz-adv-x="2304" d="M0 1024q0 23 22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31t-22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433 q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31zM512 384l18 316l574 -181q22 -7 48 -7t48 7l574 181l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128z" />
<glyph unicode="&#xf19e;" d="M109 1536q58 -15 108 -15q43 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610l13 -707q-62 11 -105 11 q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287z" />
<glyph unicode="&#xf1a0;" horiz-adv-x="1280" d="M111 182q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5t-15.5 73.5q0 40 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q76 66 182 98t218 32h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5t-59.5 -93 t-69.5 -65t-59 -61.5t-24.5 -66q0 -36 32 -70.5t77 -68t90.5 -73.5t77.5 -104t32 -142q0 -91 -49 -173q-71 -122 -209.5 -179.5t-298.5 -57.5q-132 0 -246.5 41.5t-172.5 137.5q-36 59 -36 131zM297 228q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13 t99 39t73 73t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -49 2q-53 0 -104.5 -7t-107 -25t-97 -46t-68.5 -74.5t-27 -105.5zM403 1222q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5 q53 56 53 159q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160z" />
<glyph unicode="&#xf1a1;" horiz-adv-x="1984" d="M0 722q0 94 66 160t160 66q83 0 148 -55q248 158 592 164l134 423q4 14 17.5 21.5t28.5 4.5l347 -82q22 50 68.5 81t102.5 31q77 0 131.5 -54.5t54.5 -131.5t-54.5 -132t-131.5 -55q-76 0 -130.5 54t-55.5 131l-315 74l-116 -366q327 -14 560 -166q64 58 151 58 q94 0 160 -66t66 -160q0 -62 -31 -114t-83 -82q5 -33 5 -61q0 -121 -68.5 -230.5t-197.5 -193.5q-125 -82 -285.5 -125.5t-335.5 -43.5q-176 0 -336.5 43.5t-284.5 125.5q-129 84 -197.5 193t-68.5 231q0 29 5 66q-48 31 -77 81.5t-29 109.5zM77 722q0 -67 51 -111 q49 131 180 235q-36 25 -82 25q-62 0 -105.5 -43.5t-43.5 -105.5zM178 465q0 -101 59.5 -194t171.5 -166q116 -75 265.5 -115.5t313.5 -40.5t313.5 40.5t265.5 115.5q112 73 171.5 166t59.5 194t-59.5 193.5t-171.5 165.5q-116 75 -265.5 115.5t-313.5 40.5t-313.5 -40.5 t-265.5 -115.5q-112 -73 -171.5 -165.5t-59.5 -193.5zM555 572q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96zM661 209.5q0 16.5 11 27.5t27 11t27 -11q77 -77 265 -77h2q188 0 265 77q11 11 27 11t27 -11t11 -27.5t-11 -27.5 q-99 -99 -319 -99h-2q-220 0 -319 99q-11 11 -11 27.5zM1153 572q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96zM1555 1350q0 -45 32 -77t77 -32t77 32t32 77t-32 77t-77 32t-77 -32t-32 -77zM1672 843q131 -105 178 -238 q57 46 57 117q0 62 -43.5 105.5t-105.5 43.5q-49 0 -86 -28z" />
<glyph unicode="&#xf1a2;" d="M0 193v894q0 133 94 227t226 94h896q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227zM155 709q0 -37 19.5 -67.5t52.5 -45.5q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54 q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48q-151 107 -375 115l83 265l206 -49q1 -50 36.5 -85t84.5 -35q50 0 86 35.5t36 85.5t-36 86t-86 36q-36 0 -66 -20.5t-45 -53.5l-227 54q-9 2 -17.5 -2.5t-11.5 -14.5l-95 -302q-224 -4 -381 -113q-36 43 -93 43 q-51 0 -87 -36.5t-36 -87.5zM493 613q0 37 26 63t63 26t63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64zM560 375q0 11 8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18z M882 613q0 37 26 63t63 26t63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64zM1143 1120q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21q-29 0 -50 21t-21 50z" />
<glyph unicode="&#xf1a3;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 502q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14 q19 0 32.5 -14t13.5 -33v-54l60 -28l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122zM806 500q0 -80 58 -137t139 -57t138.5 57t57.5 139v122h-150v-126q0 -20 -13.5 -33.5t-33.5 -13.5 q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123z" />
<glyph unicode="&#xf1a4;" horiz-adv-x="1920" d="M0 336v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58l-131 61v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5zM1062 332 v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275h328v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5z" />
<glyph unicode="&#xf1a5;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM64 640h704v-704h480q93 0 158.5 65.5t65.5 158.5v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480z " />
<glyph unicode="&#xf1a6;" horiz-adv-x="2048" d="M0 271v697h328v286h204v-983h-532zM205 435h123v369h-123v-369zM614 271h205v697h-205v-697zM614 1050h205v204h-205v-204zM901 26v163h328v82h-328v697h533v-942h-533zM1106 435h123v369h-123v-369zM1516 26v163h327v82h-327v697h532v-942h-532zM1720 435h123v369h-123 v-369z" />
<glyph unicode="&#xf1a7;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM293 388l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229t-88.5 229t-213.5 95q-74 0 -141 -36h-186v-840z M504 804v277q28 17 70 17q53 0 91 -45t38 -109t-38 -109.5t-91 -45.5q-43 0 -70 15zM636 -39l211 41v206q51 -19 117 -19q125 0 213 95t88 229t-88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101v-636zM847 377v277q28 17 70 17q53 0 91 -45.5t38 -109.5 t-38 -109t-91 -45q-43 0 -70 15z" />
<glyph unicode="&#xf1a8;" horiz-adv-x="2038" d="M41 455q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80 t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5l1 -21q75 3 143.5 -20.5 t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14q6 -5 28 -23.5t25.5 -22t19 -18 t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63 t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27zM764 676q10 1 32.5 7t34.5 6q19 0 35 -10l-96 -20zM822 568l48 12l109 -177l-73 -48zM859 884q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1 v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5 t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43zM1061 45h31l10 -83l-41 -12v95zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM1116 29 q21 2 60.5 8.5t72 10t60.5 3.5h14q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13t-54 -9.5t-53.5 -7.5t-32 -4.5zM1947 1528l1 3l2 4l-1 -5zM1950 1535v1v-1zM1950 1535l1 1z" />
<glyph unicode="&#xf1a9;" d="M0 520q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5 t19.5 -177.5q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302zM333 256q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14 t55.5 63q28 41 42.5 101t14.5 106q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5zM685.5 -76q-0.5 -10 7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5 q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16zM852 31q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5 t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10q-29 -12 -78 -56q-26 -24 -12 -44z" />
<glyph unicode="&#xf1aa;" d="M0 78q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160l151 -152l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5 t-60 145.5zM2 1202q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5t149.5 -87.5l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5 q-70 15 -115 71t-45 129zM446 803l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126t135.5 51q85 0 145 -60.5t60 -145.5q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152 l-160 -160zM776 793l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5q76 -11 126.5 -68.5t50.5 -134.5q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30 l-152 152z" />
<glyph unicode="&#xf1ab;" d="M0 -16v1078q3 9 4 10q5 6 20 11q106 35 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5q20 0 20 -21v-418l147 -47v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3zM39 15l694 232v1032l-694 -233v-1031zM147 293q6 4 82 92 q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8 t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110 q-4 -2 -19.5 -4t-18.5 0zM268 933l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41zM310 -116q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11q73 -37 159.5 -61.5t157.5 -24.5 q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5l-43 73l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16zM777 1294l573 -184v380zM885 453l102 -31l45 110l211 -65l37 -135l102 -31l-181 657l-100 31z M1071 630l76 185l63 -227z" />
<glyph unicode="&#xf1ac;" horiz-adv-x="1792" d="M0 -96v1088q0 66 47 113t113 47h128q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113zM512 -96v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-163q58 -34 93 -93t35 -128v-768q0 -106 -75 -181 t-181 -75h-864q-66 0 -113 47t-47 113zM640 896h896v256h-160q-40 0 -68 28t-28 68v160h-640v-512zM736 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM736 256q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9 h-128q-14 0 -23 -9t-9 -23v-128zM736 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 256q0 -14 9 -23t23 -9h128 q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM1248 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23 v-128zM1248 256q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM1248 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128z" />
<glyph unicode="&#xf1ad;" d="M0 -192v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM256 160q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 1184q0 -14 9 -23 t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 96v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23zM512 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64zM512 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 928q0 -14 9 -23 t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 160q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64zM1024 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64z" />
<glyph unicode="&#xf1ae;" horiz-adv-x="1280" d="M64 1056q0 40 28 68t68 28t68 -28l228 -228h368l228 228q28 28 68 28t68 -28t28 -68t-28 -68l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68zM416 1152q0 93 65.5 158.5t158.5 65.5 t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" />
<glyph unicode="&#xf1b0;" horiz-adv-x="1664" d="M0 724q0 80 42 139.5t119 59.5q76 0 141.5 -55.5t100.5 -134t35 -152.5q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152zM256 19q0 86 56 191.5t139.5 192.5t187.5 146t193 59q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45 t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146zM333 1163q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151zM884 1064 q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5q-61 0 -105 39t-63 92.5t-19 113.5zM1226 581q0 74 35 152.5t100.5 134t141.5 55.5q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5 q-77 0 -119 59t-42 139z" />
<glyph unicode="&#xf1b1;" horiz-adv-x="768" d="M64 1008q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5z" />
<glyph unicode="&#xf1b2;" horiz-adv-x="1792" d="M0 256v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65zM134 1026l698 -254l698 254l-698 254zM896 -93l640 349v636l-640 -233v-752z" />
<glyph unicode="&#xf1b3;" horiz-adv-x="2304" d="M0 96v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70v-400l434 -186q36 -16 57 -48t21 -70v-416q0 -36 -19 -67t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-5 2 -7 4q-2 -2 -7 -4 l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67zM172 531l404 -173l404 173l-404 173zM640 -96l384 192v314l-384 -164v-342zM647 1219l441 -189l441 189l-441 189zM1152 651l384 165v266l-384 -164v-267zM1196 531l404 -173l404 173l-404 173zM1664 -96 l384 192v314l-384 -164v-342z" />
<glyph unicode="&#xf1b4;" horiz-adv-x="2048" d="M0 22v1260h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5 t45.5 113.5q0 144 -190 144h-260v-294zM1137 477q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658q0 -111 57.5 -171.5t166.5 -60.5q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347zM1337 1073h511v124 h-511v-124zM1388 576h408q-18 195 -200 195q-90 0 -146 -52.5t-62 -142.5z" />
<glyph unicode="&#xf1b5;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 254h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5t-56.5 60.5t-79 29.5 t-97 8.5h-371v-787zM301 388v217h189q124 0 124 -113q0 -104 -128 -104h-185zM301 723v184h163q119 0 119 -90q0 -94 -106 -94h-176zM838 538q0 -135 79 -217t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20q-68 0 -104 38t-36 107h411q1 10 1 30 q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216zM964 911v77h319v-77h-319zM996 600q4 56 39 89t91 33q113 0 124 -122h-254z" />
<glyph unicode="&#xf1b6;" horiz-adv-x="2048" d="M0 764q0 86 61 146.5t146 60.5q73 0 130 -46t73 -117l783 -315q49 29 106 29q14 0 21 -1l173 248q1 114 82 194.5t195 80.5q115 0 196.5 -81t81.5 -196t-81.5 -196.5t-196.5 -81.5l-265 -194q-8 -80 -67.5 -133.5t-138.5 -53.5q-73 0 -130 46t-73 117l-783 315 q-51 -30 -106 -30q-85 0 -146 61t-61 147zM55 764q0 -64 44.5 -108.5t107.5 -44.5q11 0 33 4l-64 26q-33 14 -52.5 44.5t-19.5 66.5q0 50 35.5 85.5t85.5 35.5q20 0 41 -8v1l76 -31q-20 37 -56.5 59t-78.5 22q-63 0 -107.5 -44.5t-44.5 -107.5zM1164 244q19 -37 55.5 -59 t79.5 -22q63 0 107.5 44.5t44.5 107.5t-44.5 108t-107.5 45q-13 0 -33 -4q2 -1 20 -8t21.5 -8.5t18.5 -8.5t19 -10t16 -11t15.5 -13.5t11 -14.5t10 -18t5 -21t2.5 -25q0 -50 -35.5 -85.5t-85.5 -35.5q-14 0 -31.5 4.5t-29 9t-31.5 13.5t-28 12zM1584 767q0 -77 54.5 -131.5 t131.5 -54.5t132 54.5t55 131.5t-55 131.5t-132 54.5q-76 0 -131 -54.5t-55 -131.5zM1623 767q0 62 43.5 105.5t104.5 43.5t105 -44t44 -105t-43.5 -104.5t-105.5 -43.5q-61 0 -104.5 43.5t-43.5 104.5z" />
<glyph unicode="&#xf1b7;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 693q0 -53 38 -91t92 -38q36 0 66 18l489 -197q10 -44 45.5 -73t81.5 -29q50 0 86.5 34t41.5 83l167 122 q71 0 122 50.5t51 122.5t-51 123t-122 51q-72 0 -122.5 -50.5t-51.5 -121.5l-108 -155q-2 0 -6.5 0.5t-6.5 0.5q-35 0 -67 -19l-489 197q-10 44 -45.5 73t-80.5 29q-54 0 -92 -38t-38 -92zM162 693q0 40 28 68t68 28q27 0 49.5 -14t34.5 -37l-48 19q-29 11 -56.5 -2 t-38.5 -41q-12 -29 -0.5 -57t39.5 -40v-1l40 -16q-14 -2 -20 -2q-40 0 -68 27.5t-28 67.5zM855 369q5 -2 47 -19q29 -12 58 0.5t41 41.5q11 29 -1 57.5t-41 40.5l-40 16q14 2 21 2q39 0 67 -27.5t28 -67.5t-28 -67.5t-67 -27.5q-59 0 -85 51zM1118 695q0 48 34 82t83 34 q48 0 82 -34t34 -82t-34 -82t-82 -34q-49 0 -83 34t-34 82zM1142 696q0 -39 27.5 -66t65.5 -27t65.5 27t27.5 66q0 38 -27.5 65.5t-65.5 27.5t-65.5 -27.5t-27.5 -65.5z" />
<glyph unicode="&#xf1b8;" horiz-adv-x="1792" d="M16 970l433 -17l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188zM270.5 158q-3.5 28 4 65t12 55t21.5 64t19 53q78 -12 509 -28l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5 q-11 27 -14.5 55zM294 1124l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5t36 -39.5t32 -35q-47 -63 -265 -435l-317 187zM782 1524l405 -1q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190l142 83l-220 -373l-419 20l151 86q-34 89 -75 166 t-75.5 123.5t-64.5 80t-47 46.5zM953 197l211 362l7 -173q170 -16 283 -5t170 33l56 22l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164zM1218 847l313 195l19 11l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22 t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436z" />
<glyph unicode="&#xf1b9;" horiz-adv-x="1984" d="M0 160v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h704q98 0 179 -63.5t104 -157.5l105 -419h28q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-128v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-928v-128q0 -80 -56 -136 t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23zM160 448q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113zM516 768h952l-89 357q-2 8 -14 17.5t-21 9.5h-704q-9 0 -21 -9.5t-14 -17.5zM1472 448q0 -66 47 -113t113 -47t113 47t47 113 t-47 113t-113 47t-113 -47t-47 -113z" />
<glyph unicode="&#xf1ba;" horiz-adv-x="1984" d="M0 32v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h64q98 0 179 -63.5t104 -157.5l105 -419h28q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-128v-64q0 -80 -56 -136t-136 -56 t-136 56t-56 136v64h-928v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23zM160 320q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113zM516 640h952l-89 357q-2 8 -14 17.5t-21 9.5h-704q-9 0 -21 -9.5t-14 -17.5zM1472 320 q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113z" />
<glyph unicode="&#xf1bb;" d="M32 64q0 26 19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45t-19 -45t-45 -19 h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45z" />
<glyph unicode="&#xf1bc;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM237 886q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37q159 0 309.5 -34t253.5 -95q21 -12 40 -12 q29 0 50.5 20.5t21.5 51.5q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5zM289 637q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5q0 40 -35 61 q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64zM321 406q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52z" />
<glyph unicode="&#xf1bd;" d="M0 11v1258q0 58 40.5 98.5t98.5 40.5h1258q58 0 98.5 -40.5t40.5 -98.5v-1258q0 -58 -40.5 -98.5t-98.5 -40.5h-1258q-58 0 -98.5 40.5t-40.5 98.5zM71 11q0 -28 20 -48t48 -20h1258q28 0 48 20t20 48v1258q0 28 -20 48t-48 20h-1258q-28 0 -48 -20t-20 -48v-1258z M121 11v141l711 195l-212 439q4 1 12 2.5t12 1.5q170 32 303.5 21.5t221 -46t143.5 -94.5q27 -28 -25 -42q-64 -16 -256 -62l-97 198q-111 7 -240 -16l188 -387l533 145v-496q0 -7 -5.5 -12.5t-12.5 -5.5h-1258q-7 0 -12.5 5.5t-5.5 12.5zM121 709v560q0 7 5.5 12.5 t12.5 5.5h1258q7 0 12.5 -5.5t5.5 -12.5v-428q-85 30 -188 52q-294 64 -645 12l-18 -3l-65 134h-233l85 -190q-132 -51 -230 -137zM246 413q-24 203 166 305l129 -270l-255 -61q-14 -3 -26 4.5t-14 21.5z" />
<glyph unicode="&#xf1be;" horiz-adv-x="2304" d="M0 405l17 128q2 9 9 9t9 -9l20 -128l-20 -126q-2 -9 -9 -9t-9 9zM79 405l23 207q0 9 9 9q8 0 10 -9l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10zM169 405l21 245q2 12 12 12q11 0 11 -12l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11zM259 405l21 252q0 13 13 13 q12 0 14 -13l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13zM350 405l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5zM401 159zM442 405l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5l21 -380l-21 -246q0 -7 -5 -12.5 t-12 -5.5q-16 0 -18 18zM534 403l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19zM628 405l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5l18 -506l-18 -242q-2 -21 -22 -21q-19 0 -21 21zM723 405l14 -241 q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17zM784 164zM817 405l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18zM913 404l12 492q1 12 9 20t19 8t18.5 -8 t8.5 -20l14 -492l-14 -236q0 -11 -8 -19t-19 -8t-19 8t-9 19zM1010 405q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11q11 0 20 9q9 7 9 20l1 24l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6zM1079 169zM1103 404l12 636v3q2 15 12 24q9 7 20 7 q8 0 15 -5q14 -8 16 -26l14 -639l-14 -231q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114zM1204 174v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201q0 -117 -83 -199.5t-200 -82.5h-786q-13 2 -22 11t-9 22z" />
<glyph unicode="&#xf1c0;" d="M0 0v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 384v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 768 v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 1152v128q0 69 103 128t280 93.5t385 34.5t385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 t-103 128z" />
<glyph unicode="&#xf1c1;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM257 60q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4 q52 85 107 197q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38 q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83z M714 842q1 7 7 44q0 3 7 43q1 4 4 8q-1 1 -1 2t-0.5 1.5t-0.5 1.5q-1 22 -13 36q0 -1 -1 -2v-2q-15 -42 -2 -132zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1098 353q76 -28 124 -28q14 0 18 1q0 1 -2 3q-24 24 -140 24z" />
<glyph unicode="&#xf1c2;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM233 661h70l164 -661h159l128 485q7 20 10 46q2 16 2 24 h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4l-3 21q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300v-107zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
<glyph unicode="&#xf1c3;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM429 0h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4 h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107h-290v-107h68l189 -272l-194 -283h-68v-106zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
<glyph unicode="&#xf1c4;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM416 0h327v106h-93v167h137q76 0 118 15q67 23 106.5 87 t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92v-106zM650 386v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15h-119zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
<glyph unicode="&#xf1c5;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 0v192l192 192l128 -128l384 384l320 -320v-320 h-1024zM256 704q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
<glyph unicode="&#xf1c6;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536zM384 192q0 25 8 52q21 63 120 396 v128h128v-128h79q22 0 39 -13t23 -34l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5zM512 192q0 -26 37.5 -45t90.5 -19t90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45zM512 896h128v128h-128v-128zM512 1152h128v128h-128v-128 zM640 768h128v128h-128v-128zM640 1024h128v128h-128v-128zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
<glyph unicode="&#xf1c7;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 288v192q0 14 9 23t23 9h131l166 167q16 15 35 7 q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23zM762 206.5q1 -26.5 20 -44.5q20 -17 44 -17q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5z M973.5 54.5q2.5 -26.5 23.5 -42.5q18 -15 40 -15q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
<glyph unicode="&#xf1c8;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 256v384q0 52 38 90t90 38h384q52 0 90 -38t38 -90 v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90zM960 403v90l265 266q9 9 23 9q4 0 12 -2q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
<glyph unicode="&#xf1c9;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM254 429q-14 19 0 38l226 301q8 11 21 12.5t24 -6.5 l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5zM636 43l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5l-63 10q-13 2 -20.5 13t-5.5 24zM947.5 181 q-1.5 13 6.5 24l182 243l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5l226 -301q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
<glyph unicode="&#xf1ca;" d="M39 1286h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132 t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390z" />
<glyph unicode="&#xf1cb;" horiz-adv-x="1792" d="M0 367v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64v-546q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64zM154 511l193 129l-193 129v-258zM216 367l603 -402v359l-334 223zM216 913l269 -180l334 223v359zM624 640 l272 -182l272 182l-272 182zM973 -35l603 402l-269 180l-334 -223v-359zM973 956l334 -223l269 180l-603 402v-359zM1445 640l193 -129v258z" />
<glyph unicode="&#xf1cc;" horiz-adv-x="2048" d="M0 407q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5 h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55t121.5 -21 q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97q14 -16 29.5 -34t34.5 -40t29 -34q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z " />
<glyph unicode="&#xf1cd;" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM128 640q0 -190 90 -361l194 194q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361zM512 640 q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM535 -38q171 -90 361 -90t361 90l-194 194q-82 -28 -167 -28t-167 28zM535 1318l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90t-361 -90z M1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" />
<glyph unicode="&#xf1ce;" horiz-adv-x="1792" d="M0 640q0 222 101 414.5t276.5 317t390.5 155.5v-260q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v260q215 -31 390.5 -155.5t276.5 -317t101 -414.5 q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348z" />
<glyph unicode="&#xf1d0;" horiz-adv-x="1792" d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41 t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170 t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136 q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" />
<glyph unicode="&#xf1d1;" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM44 640q0 -173 67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331 t-67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331zM87 640q0 205 98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385zM206 217l58 34q29 -49 73 -99 l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13v-66q-208 6 -385 109.5t-283 275.5zM207 1063q106 172 282 275.5t385 109.5v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98zM415 805q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10 t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162q-67 77 -98 169l232 80q-14 42 -14 85t14 85zM918 -102 q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99l58 -34q-106 -172 -283 -275.5t-385 -109.5v66zM918 1382v66q209 -6 385 -109.5t282 -275.5l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13zM1516 428q36 103 36 212q0 112 -35 212l82 28 q-19 56 -49 112l57 33q98 -180 98 -385t-98 -385l-57 33q27 52 49 112z" />
<glyph unicode="&#xf1d2;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 218q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5 t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85q0 -53 41 -77v-3q-113 -37 -113 -139zM382 225q0 64 98 64q102 0 102 -61q0 -66 -93 -66 q-107 0 -107 63zM395 693q0 90 77 90q36 0 55 -25.5t19 -63.5q0 -85 -74 -85q-77 0 -77 84zM755 1072q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392q0 -50 -3 -75z M966 771q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117z" />
<glyph unicode="&#xf1d3;" horiz-adv-x="1792" d="M68 7q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47q98 0 218 47v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58q0 -31 22.5 -51.5t58 -32 t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5zM272 18q0 -101 172 -101q151 0 151 105q0 100 -165 100q-158 0 -158 -104zM293 775q0 -135 124 -135q119 0 119 137q0 61 -30 102t-89 41 q-124 0 -124 -145zM875 1389q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5t-39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5zM901 220q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134h-222zM1217 901v190h96v76q0 54 -6 89h227q-6 -41 -6 -165 h171v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6z" />
<glyph unicode="&#xf1d4;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM368 1135l323 -589v-435h134v436l343 588h-150q-21 -39 -63.5 -118.5t-68 -128.5t-59.5 -118.5t-60 -128.5h-3 q-21 48 -44.5 97t-52 105.5t-46.5 92t-54 104.5t-49 95h-150z" />
<glyph unicode="&#xf1d5;" horiz-adv-x="1280" d="M57 953q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5t-78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153 t-153 102t-186 38t-186 -38t-153 -102t-102 -153t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265zM113.5 38.5q10.5 121.5 29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5t136.5 -56.5 t56.5 -136.5t-57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5z" />
<glyph unicode="&#xf1d6;" horiz-adv-x="1792" d="M18 264q0 275 252 466q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5 t3.5 -5t2 -3.5q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9 t-98 20t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20 q-18 -41 -54.5 -74.5t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100z" />
<glyph unicode="&#xf1d7;" horiz-adv-x="2048" d="M0 858q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490z M380 1075q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5t-25 66t-66 25q-43 0 -76 -25.5t-33 -65.5zM816 404q0 143 81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109q-150 -37 -218 -37 q-169 0 -311 70.5t-223.5 191.5t-81.5 264zM888 1075q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5t-24.5 66t-65.5 25q-43 0 -76 -25.5t-33 -65.5zM1160 568q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5 t-22.5 -49.5zM1559 568q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5z" />
<glyph unicode="&#xf1d8;" horiz-adv-x="1792" d="M0 508q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55z" />
<glyph unicode="&#xf1d9;" horiz-adv-x="1792" d="M0 508q-3 39 32 59l1664 960q35 21 68 -2q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55zM209 522l336 -137l863 639l-478 -797l492 -201 l221 1323z" />
<glyph unicode="&#xf1da;" d="M0 832v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298t-61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12 q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45zM512 480v64q0 14 9 23t23 9h224v352 q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf1db;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5z" />
<glyph unicode="&#xf1dc;" horiz-adv-x="1792" d="M62 1338q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160 q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5 q0 -26 -12 -48t-36 -22q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5 t45 -15t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18 q-15 10 -45 12t-53 2t-41 14t-18 45z" />
<glyph unicode="&#xf1dd;" horiz-adv-x="1280" d="M24 926q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108 q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179q-64 117 -64 259z" />
<glyph unicode="&#xf1de;" d="M0 736v64q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM128 -96v672h256v-672q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM128 960v416q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-416h-256zM512 224v64q0 40 28 68 t68 28h320q40 0 68 -28t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 64h256v-160q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v160zM640 448v928q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-928h-256zM1024 992v64q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1152 -96v928h256v-928q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1152 1216v160q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-160h-256z" />
<glyph unicode="&#xf1e0;" d="M0 640q0 133 93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86q133 0 226.5 -93.5t93.5 -226.5 t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5z" />
<glyph unicode="&#xf1e1;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 640q0 -88 62.5 -150.5t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5 t150.5 62.5t62.5 150.5t-62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5z" />
<glyph unicode="&#xf1e2;" horiz-adv-x="1792" d="M0 448q0 143 55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68l243 244l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5 t-225 150t-150 225t-55.5 273.5zM170 615q10 -24 35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49t-34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49zM1376 1472q0 13 9 23q10 9 23 9t23 -9l90 -91q10 -9 10 -22.5t-10 -22.5 q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23zM1536 1408v96q0 14 9 23t23 9t23 -9t9 -23v-96q0 -14 -9 -23t-23 -9t-23 9t-9 23zM1605 1242.5q0 13.5 10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5z M1605 1381.5q0 13.5 10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5zM1632 1312q0 14 9 23t23 9h96q14 0 23 -9t9 -23t-9 -23t-23 -9h-96q-14 0 -23 9t-9 23z" />
<glyph unicode="&#xf1e3;" horiz-adv-x="1792" />
<glyph unicode="&#xf1e4;" horiz-adv-x="1792" />
<glyph unicode="&#xf1e5;" horiz-adv-x="1792" />
<glyph unicode="&#xf1e6;" horiz-adv-x="1792" />
<glyph unicode="&#xf1e7;" horiz-adv-x="1792" />
<glyph unicode="&#xf1e8;" horiz-adv-x="1792" />
<glyph unicode="&#xf1e9;" horiz-adv-x="1792" />
<glyph unicode="&#xf1ea;" horiz-adv-x="1792" />
<glyph unicode="&#xf1eb;" horiz-adv-x="1792" />
<glyph unicode="&#xf1ec;" horiz-adv-x="1792" />
<glyph unicode="&#xf1ed;" horiz-adv-x="1792" />
<glyph unicode="&#xf1ee;" horiz-adv-x="1792" />
<glyph unicode="&#xf500;" horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
<glyph horiz-adv-x="1792" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,359 @@
jQuery(document).ready(function ($) {
var $superFirstInput = $('#woocommerce_przelewy24_p24_paymethods_super_first');
function getBanksList() {
var banksList = [];
$('#woocommerce_przelewy24_p24_paymethods_all option').each(function () {
if (parseInt($(this).val()) > 0) {
banksList.push({id: $(this).val(), name: $(this).text()});
}
});
if (banksList.length == 0) {
banksList.push({id: 25, name: ""});
banksList.push({id: 31, name: ""});
banksList.push({id: 112, name: ""});
banksList.push({id: 20, name: ""});
banksList.push({id: 65, name: ""});
}
return banksList;
}
var getStyleForBank = function(id) {
var $row = $('#p24-hidden-bank-icon-list tr.js-bank-id-' + id);
var css = '';
if ($row.length) {
var url = $row.find('td.js-icon-type-mobile').text();
css = 'style="background-image: url(' + url + ')"';
}
return css;
};
function getSuperBankBox(id, name) {
if (name == undefined) name = '';
var css = getStyleForBank(id);
return '<a id="p24-admin-super-bank-' + id + '" class="bank-box" data-super-id="' + id + '"><div class="bank-logo" ' + css + '></div><div class="bank-name">' + name + '</div></a>';
}
function getBankBox(id, name) {
if (name == undefined) name = '';
var css = getStyleForBank(id);
return '<a class="bank-box" data-id="' + id + '"><div class="bank-logo" ' + css + '></div><div class="bank-name">' + name + '</div></a>';
}
function toggleSomething(toggle, selector) {
if (toggle) {
$(selector).show();
} else {
$(selector).hide();
}
}
function updateSuperPaymethods() {
var set = [];
$('.paymethod .super-selected a.bank-box').each(function () {
set.push($(this).attr('data-super-id'));
});
$superFirstInput.val(set.join(','));
}
function updatePaymethods() {
$('.bank-box').removeClass('ui-helper-unrotate');
var maxNo = parseInt($('.paymethod .selected').attr('data-max'));
if (maxNo > 0) {
if ($('.paymethod .selected a[data-id]').length > maxNo) {
var i = 0;
$('.paymethod .selected a[data-id]').each(function () {
i++;
if (i > maxNo) {
$('.paymethod .available')
.prepend($(this))
.append($('#clear'));
}
});
}
}
$('#woocommerce_przelewy24_p24_paymethods_first').val('');
$('.paymethod .selected a[data-id]').each(function () {
$('#woocommerce_przelewy24_p24_paymethods_first').val(
$('#woocommerce_przelewy24_p24_paymethods_first').val() +
($('#woocommerce_przelewy24_p24_paymethods_first').val().length ? ',' : '') +
$(this).attr('data-id')
);
});
$('#woocommerce_przelewy24_p24_paymethods_second').val('');
$('.paymethod .available a[data-id]').each(function () {
$('#woocommerce_przelewy24_p24_paymethods_second').val(
$('#woocommerce_przelewy24_p24_paymethods_second').val() +
($('#woocommerce_przelewy24_p24_paymethods_second').val().length ? ',' : '') +
$(this).attr('data-id')
);
});
}
$(document).ready(function () {
$superFirstInput.hide();
$('#woocommerce_przelewy24_p24_paymethods_first').hide();
$('#woocommerce_przelewy24_p24_paymethods_second').closest('tr').hide();
$('#woocommerce_przelewy24_p24_paymethods_all').closest('tr').hide();
if ($('#woocommerce_przelewy24_p24_paymethods_all option[value=266]').length) {
$('#woocommerce_przelewy24_p24_add_to_alternative_method').closest('tr').show();
$('#woocommerce_przelewy24_p24_custom_promote_p24').closest('tr').show();
} else {
$('#woocommerce_przelewy24_p24_add_to_alternative_method').closest('tr').hide();
$('#woocommerce_przelewy24_p24_custom_promote_p24').closest('tr').hide();
}
$superFirstInput.closest('td').append(
'<div class="paymethod" id="p24-admin-config-methods-checkout">' +
'<div style="margin: 0.5em 0">' + p24_payment_script_vars.php_msg3 + '</div>' +
'<div class="sortable super-selected" style="width: 730px; border: 5px dashed lightgray; height: 80px; padding: 0.5em; overflow: hidden;"></div>' +
'<div style="clear:both"></div>' +
'<div style="margin: 0.5em 0">' + p24_payment_script_vars.php_msg4 + '</div>' +
'<div class="sortable super-available"></div>' +
'</div>' +
''
);
var $superSelected = $('.paymethod .super-selected');
var $superAvailable = $('.paymethod .super-available');
$('#woocommerce_przelewy24_p24_paymethods_first').closest('td').append(
'<div class="paymethod" id="p24-admin-config-methods-confirmation">' +
'<div style="margin: 0.5em 0">' + p24_payment_script_vars.php_msg1 + '</div>' +
'<div class="sortable selected" data-max="5" style="width: 730px; border: 5px dashed lightgray; height: 80px; padding: 0.5em; overflow: hidden;"></div>' +
'<div style="clear:both"></div>' +
'<div style="margin: 0.5em 0">' + p24_payment_script_vars.php_msg2 + '</div>' +
'<div class="sortable available"></div>' +
'</div>' +
''
);
$('#woocommerce_przelewy24_p24_show_methods_checkout').change(function () {
var showed = $(this).is(':checked');
toggleSomething(showed, $('#p24-admin-config-methods-checkout').closest('tr'));
}).trigger('change');
$('#woocommerce_przelewy24_p24_show_methods_confirmation').change(function () {
var showed = $(this).is(':checked');
toggleSomething(showed, $('#p24-admin-config-methods-confirmation').closest('tr'));
toggleSomething(showed, $('#woocommerce_przelewy24_p24_graphics').closest('tr'));
toggleSomething(showed, $('#woocommerce_przelewy24_p24_acceptinshop').closest('tr'));
}).trigger('change');
$.each(getBanksList(), function () {
$superAvailable.append(getSuperBankBox(this.id, this.name));
$('.sortable.available').append(getBankBox(this.id, this.name));
});
$superAvailable.append('<div style="clear:both" id="clear"></div>');
$('.sortable.available').append('<div style="clear:both" id="clear"></div>');
$superFirstInput.val().split(',').forEach(function (val) {
$('#p24-admin-super-bank-' + val).appendTo($superSelected);
});
if ($('#woocommerce_przelewy24_p24_paymethods_first').val().length > 0) {
$.each($('#woocommerce_przelewy24_p24_paymethods_first').val().split(','), function (i, v) {
$('.bank-box[data-id=' + v + ']').appendTo('.paymethod .selected');
});
}
if ($('#woocommerce_przelewy24_p24_paymethods_second').val().length > 0) {
$.each($('#woocommerce_przelewy24_p24_paymethods_second').val().split(',').reverse(), function (i, v) {
$('.bank-box[data-id=' + v + ']').prependTo('.paymethod .available');
});
}
updateSuperPaymethods();
updatePaymethods();
var selectorForSuperFirst = $('.paymethod .super-selected, .paymethod .super-available');
$(selectorForSuperFirst).sortable({
connectWith: selectorForSuperFirst,
placeholder: "bank-box bank-placeholder",
stop: function () {
updateSuperPaymethods();
updateIfP24NOW();
},
revert: true,
start: function (e, ui) {
window.setTimeout(function () {
$('.bank-box.ui-sortable-helper').on('mouseup', function () {
$(this).addClass('ui-helper-unrotate');
});
}, 100);
},
}).disableSelection();
$(".sortable.selected,.sortable.available").sortable({
connectWith: ".sortable.selected,.sortable.available",
placeholder: "bank-box bank-placeholder",
stop: function () {
updatePaymethods();
},
revert: true,
start: function (e, ui) {
window.setTimeout(function () {
$('.bank-box.ui-sortable-helper').on('mouseup', function () {
$(this).addClass('ui-helper-unrotate');
});
}, 100);
},
}).disableSelection();
if ($('#p24_no_api_key_provided').length) {
$('#woocommerce_przelewy24_p24_oneclick,#woocommerce_przelewy24_p24_payinshop,#woocommerce_przelewy24_p24_acceptinshop,#woocommerce_przelewy24_p24_paymethods,#woocommerce_przelewy24_p24_graphics,#woocommerce_przelewy24_p24_paymethods_first,#woocommerce_przelewy24_p24_paymethods_second').closest('tr').hide();
}
});
});
(function( $ ) {
/* Activate automatic admin change currency selector. */
$( function () {
$( '.js_currency_admin_selector' ).on( 'change', function () {
var val, data, nonce;
val = $( this ).val();
nonce = $( '#p24_nonce' ).val();
if ( ! nonce ) {
/* Fallback for situations the id cannot be set. */
nonce = $( '.js-p24-alt-nonce' ).val();
}
data = {
action: 'p24_change_currency',
p24_action_type_field: 'change_currency',
p24_nonce: nonce,
p24_currency: val
};
$.post( ajaxurl, data, function () {
$('form').each(function (idx, form) {
form.reset();
});
location.reload() ;
});
});
});
})( jQuery );
(function( $ ) {
$( function () {
var $cb = $('#woocommerce_przelewy24_p24_use_special_status');
var $sPending = $('#woocommerce_przelewy24_p24_custom_pending_status');
var $o1stPenging = $sPending.find('option').first();
var $sProcessing = $('#woocommerce_przelewy24_p24_custom_processing_status');
var $o1stProcessing = $sProcessing.find('option').first();
var labelProcessingEnOrg = 'Processing';
var labelProcessingEnP24 = 'Paid by P24';
var labelProcessingPlOrg = 'W trakcie realizacji';
var labelProcessingPlP24 = 'Opłacone przez P24';
var addSuffix = function($opt) {
var existing = $opt.text();
if (labelProcessingEnOrg === existing) {
$opt.text(labelProcessingEnP24);
} else if (labelProcessingPlOrg === existing) {
$opt.text(labelProcessingPlP24);
} else {
$opt.text($opt.text() + ' P24');
}
};
var dropSuffix = function($opt) {
var existing = $opt.text();
console.log(existing);
if (labelProcessingEnP24 === existing) {
$opt.text(labelProcessingEnOrg);
} else if (labelProcessingPlP24 === existing) {
$opt.text(labelProcessingPlOrg);
} else {
var rx = /(.+)\sP24/;
$opt.text(rx.test(existing) ? rx.exec(existing)[1] : existing);
}
};
$cb.on('change', function () {
if ($cb.prop('checked')) {
$sProcessing.prop('disabled', false);
addSuffix($o1stProcessing);
$sPending.prop('disabled', false);
addSuffix($o1stPenging);
} else {
$sProcessing.val('').prop('disabled', true);
dropSuffix($o1stProcessing);
$sPending.val('').prop('disabled', true);
dropSuffix($o1stPenging);
}
});
$cb.trigger('change');
});
})( jQuery );
// --- changes below associated with p24 now
/**
* Update sortable based on checkbox
*/
function togglePromotedP24NOW() {
$p24nowBox = jQuery("#p24-admin-super-bank-266");
$p24nowBox.remove();
$idValuesHolder = jQuery("#woocommerce_przelewy24_p24_paymethods_super_first");
if (jQuery("#woocommerce_przelewy24_p24_add_to_alternative_method").is(':checked')) {
jQuery(".super-selected").append($p24nowBox);
addP24ToPromoted();
} else if(jQuery("#woocommerce_przelewy24_p24_add_to_alternative_method").is(':not(:checked)')){
jQuery(".super-available").append($p24nowBox);
removeP24FromPromoted()
}
jQuery('.paymethod .super-selected, .paymethod .super-available').sortable( "refreshPositions" );
}
/* promote if added to be */
jQuery(document).ready(function () {
jQuery("#woocommerce_przelewy24_p24_add_to_alternative_method").click(togglePromotedP24NOW);
});
// /* promote if added */
jQuery(document).ready(function () {
jQuery("#woocommerce_przelewy24_p24_paymethods_super_first").change(function () {
console.log('woocommerce_przelewy24_p24_paymethods_super_first changed');
if(jQuery('.super-selected').find("#p24-admin-super-bank-266").length > 0){
jQuery("#woocommerce_przelewy24_p24_add_to_alternative_method").prop('checked', true);
}else if(jQuery('.super-selected').find("#p24-admin-super-bank-266").length === 0){
jQuery("#woocommerce_przelewy24_p24_add_to_alternative_method").prop('checked', false);
}
});
});
/**
* Check checkbox based on sortable change
*/
function updateIfP24NOW() {
jQuery("#woocommerce_przelewy24_p24_add_to_alternative_method")
.prop('checked', (jQuery('.super-selected').find("#p24-admin-super-bank-266").length > 0));
}
function addP24ToPromoted(){
jQuery('#woocommerce_przelewy24_p24_paymethods_super_first').val(function () {
let values = jQuery('#woocommerce_przelewy24_p24_paymethods_super_first')
.val()
.split(',');
values.push('266');
return values.join(',');
});
}
function removeP24FromPromoted(){
jQuery('#woocommerce_przelewy24_p24_paymethods_super_first').val(function () {
let values = jQuery('#woocommerce_przelewy24_p24_paymethods_super_first')
.val()
.split(',');
const index = values.indexOf('266');
if (index > -1) {
values.splice(index, 1);
}
return values.join(',');
});
}

View File

@@ -0,0 +1,40 @@
(function( $ ) {
/* Additional code for multipliers form. */
(function () {
var $adderBox, $select, $btn, armRemoveBtn;
$adderBox = $( '.js-currency-adder' );
if ( $adderBox.length ) {
$select = $adderBox.find( 'select' );
$btn = $adderBox.find( 'input' );
armRemoveBtn = function ( $btn ) {
$btn.on( 'click', function () {
$btn.parents( '.js-p24-multiplier-box' ).remove();
});
return $btn;
};
$( '.js-p24-multiplier-box input[type=button]' ).each( function ( idx, elm ) {
armRemoveBtn( $( elm ) );
});
$btn.on( 'click', function () {
var $lastInputBox, name, selectVal, $newInputBox, removeBtn;
/* Use last input as template and insert a new one. */
$lastInputBox = $( '.js-p24-multiplier-box' ).last();
name = $lastInputBox.find( 'input[type=number]' ).attr( 'name' );
selectVal = $select.val();
name = name.replace( /\[[^\]]*\]$/, '[' + selectVal + ']' );
$newInputBox = $lastInputBox.clone();
$newInputBox
.find( 'input[type=number]' )
.attr( 'name', name )
.val( 1 )
.prop( 'disabled', false );
removeBtn = $newInputBox.find( 'input[type=button]' );
removeBtn.css( 'display', 'unset' );
armRemoveBtn( removeBtn ) ;
$newInputBox.find( 'label' ).text( selectVal );
$lastInputBox.after( $newInputBox );
});
}
})();
})( jQuery );

View File

@@ -0,0 +1,479 @@
function onResize() {
if (jQuery(window).width() <= 640) {
jQuery('.payMethodList').addClass('mobile');
} else {
jQuery('.payMethodList').removeClass('mobile');
}
}
onResize();
jQuery(window).resize(function () {
onResize();
});
function setP24method(method) {
method = parseInt(method);
jQuery('input[name=p24_method]').val(method > 0 ? method : "");
}
function choosePaymentMethod() {
var checkedPayment = false;
var setP24channel = function (paymentIdRaw) {
var paymentId = Number(paymentIdRaw);
if (266 === paymentId) {
jQuery('input[name=p24_channel]').val('2048');
} else {
jQuery('input[name=p24_channel]').val('');
}
};
jQuery('.bank-box').click(function () {
jQuery('.bank-box').removeClass('selected').addClass('inactive');
jQuery(this).addClass('selected').removeClass('inactive');
jQuery('.extra-promoted-box').removeClass('selected').addClass('inactive');
if (jQuery(this).parents('.payMethodList').hasClass('checkoutView')) {
var inputs = jQuery(this).parents('.checkoutView').find('input[type="checkbox"]');
jQuery(inputs).removeAttr('checked');
jQuery(inputs).prop('checked', false);
var input = jQuery(this).find('input[type="checkbox"]');
jQuery(input).attr('checked', 'checked');
jQuery(input).prop('checked', true);
checkedPayment = true;
jQuery('#payment_method_przelewy24_payment').trigger('change');
}
setP24method(jQuery(this).attr('data-id'));
setP24channel(jQuery(this).data('id'));
setP24recurringId(jQuery(this).attr('data-cc'));
});
jQuery('.bank-item input').change(function () {
setP24method(jQuery(this).closest('.bank-item').attr('data-id'));
setP24recurringId(jQuery(this).attr('data-cc'));
});
jQuery('#payment_method_przelewy24_payment').trigger('change');
jQuery('input[name=payment_method_id]:checked:first').closest('.input-box.bank-item').each(function () {
setP24method(jQuery(this).attr('data-id'));
});
jQuery(".box-wrapper").click(function () {
const $thisElement = jQuery(this);
if($thisElement.hasClass('selected')){
jQuery('input[name=p24_channel]').val('');
}else{
jQuery('.bank-box').removeClass('selected').addClass('inactive');
jQuery("#p24-now-box").addClass('selected').removeClass('inactive');
jQuery('input[name=p24_channel]').val('2048');
setP24method(jQuery(this).data('id'));
setP24channel(jQuery(this).data('id'));
setP24recurringId('');
}
});
}
jQuery('<style>.moreStuff.translated:before{content:"' + p24_payment_php_vars.payments_msg4js + '"} </style>').appendTo('head');
jQuery('.moreStuff').toggleClass('translated');
var sessionId = false;
var sign = false;
function requestJsAjaxCard() {
var getForm = function () {
var formHtml = '<form id="przelewy24RPCCardForm"><p id="przelewy24RPCCardFormDescription" class="italic"></p>'+
'<p><label for="P24_cardHolder"></label><input name="P24_cardHolder" id="P24_cardHolder"/></p>'+
'<p><label for="P24_cardNumber"></label><input name="P24_cardNumber" id="P24_cardNumber"/></p>'+
'<p><label for="P24_cardCVV"></label><input name="P24_cardCVV" id="P24_cardCVV" size="3" maxlength="4"/></p>'+
'<p><label for="P24_expMonth"></label><input name="P24_expMonth" id="P24_expMonth" size="2" maxlength="2" placeholder="mm"/>'+
'/<input name="P24_expYear" id="P24_expYear" size="2" maxlength="2" placeholder="yy"/></p>'+
'<p><input type="checkbox" id="P24_registerCard" name="P24_registerCard"/>'+
'<label for="P24_registerCard" id="register-text"></label></p><button type="submit" ></button></form>'
var dict = JSON.parse(jQuery('#p24_dictionary').val());
var $formHtml = jQuery(formHtml);
$formHtml.find('label[for=P24_registerCard]').text(dict['registerCardLabel']);
$formHtml.find('label[for=P24_cardHolder]').text(dict['cardHolderLabel']);
$formHtml.find('label[for=P24_cardNumber]').text(dict['cardNumberLabel']);
$formHtml.find('label[for=P24_cardCVV]').text(dict['cvvLabel']);
$formHtml.find('label[for=P24_expMonth]').text(dict['expDateLabel']);
$formHtml.find('#przelewy24RPCCardFormDescription').text(dict['description']);
$formHtml.find('button').text(dict['payButtonCaption']);
return $formHtml;
};
jQuery('#P24FormArea').html("");
var $formContainer = jQuery("<div></div>");
$formContainer
.attr('id', 'P24FormContainer')
.appendTo('#P24FormArea')
.parent().slideDown()
;
$formContainer.append(getForm());
var $form = jQuery('#przelewy24RPCCardForm');
$form.on('submit', function (e) {
e.preventDefault();
if ($form.find('button').attr('disabled')) {
return;
}
$form.find('button').attr('disabled', 'disabled');
jQuery.ajax(jQuery('#p24_ajax_url').val(), {
method: 'POST', type: 'POST',
data: {
action: 'cardPay',
p24sessionId: jQuery('[name=p24_session_id]').val(),
orderId: jQuery('#p24_woo_order_id').val(),
cardNumber: jQuery('#P24_cardNumber').val(),
cvv: jQuery('#P24_cardCVV').val(),
cardMonth: jQuery('#P24_expMonth').val(),
cardYear: jQuery('#P24_expYear').val(),
clientName: jQuery('#P24_cardHolder').val()
},
success: function (resultJson) {
let result = jQuery.parseJSON(resultJson);
if (result.success && result.redirect && result.redirectUrl) {
setTimeout(function () {
window.location.href = result.redirectUrl;
}, 1000);
} else if (result.success) {
setTimeout(function () {
window.location.href = jQuery('[name=p24_url_return]').val();
}, 1000);
} else {
hidePayJsPopup();
}
},
done: function () {
$form.find('button').removeAttr('disabled');
}
});
})
}
function showPayJsPopup() {
$termsAcceptanceCheckbox = jQuery('[name="p24_regulation_accept"]');
if (0 !== $termsAcceptanceCheckbox.length && !jQuery('[name="p24_regulation_accept"]').is(':checked')) {
jQuery('#place_order').click();
return;
}
if (jQuery('#P24FormAreaHolder:visible').length == 0) {
setP24method("");
jQuery('#P24FormAreaHolder').appendTo('body');
jQuery('#proceedPaymentLink').closest('a').fadeOut();
jQuery('#P24FormAreaHolder').fadeIn();
if (typeof P24_Transaction != 'object') {
requestJsAjaxCard();
}
}
}
function hidePayJsPopup() {
jQuery('#P24FormAreaHolder').fadeOut();
jQuery('#proceedPaymentLink:not(:visible)').closest('a').fadeIn();
}
function payInShopSuccess(orderId, oneclickOrderId) {
jQuery.ajax(jQuery('#p24_ajax_url').val(), {
method: 'POST', type: 'POST',
data: {
action: 'rememberOrderId',
sessionId: jQuery('[name=p24_session_id]').val(),
orderId: orderId,
oneclickOrderId: oneclickOrderId,
sign: jQuery('[name=p24_sign]').val()
}
});
window.setTimeout(function () {
window.location = jQuery('[name=p24_url_return]').val();
}, 1000);
}
function setP24recurringId(id,name) {
id = parseInt(id);
if (name == undefined) name = jQuery('[data-cc='+id+'] .bank-name').text().trim() + ' - ' + jQuery('[data-cc='+id+'] .bank-logo span').text().trim();
jQuery('input[name=p24_cc]').val( id > 0 ? id : "" );
if (id > 0) setP24method(0);
}
function p24_processPayment() {
console.log('processPayment');
var ccid = parseInt(jQuery('input[name=p24_cc]').val());
if (isNaN(ccid) || ccid == 0) {
var myform = document.getElementById("przelewy_payment_form");
var fd = new FormData(myform );
jQuery("#przelewy_payment_form :input").prop("disabled", true);
jQuery.ajax({
url: jQuery("#przelewy_payment_form").attr('action'),
data: fd,
cache: false,
processData: false,
contentType: false,
type: 'POST',
success: function(data) {
window.location.replace(data.url);
},
error: function () {
alert('internal error');
}
});
}
// recuring
if (ccid > 0) {
var ra = jQuery('#przelewy_payment_form [name=p24_regulation_accept]').prop('checked') ? '1' : '';
jQuery('#przelewy24FormRecuring [name=p24_regulation_accept]').val(ra);
jQuery('#przelewy24FormRecuring').submit();
}
return false;
}
function removecc(ccid) {
jQuery('form#cardrm input[name=cardrm]').val(ccid).closest('form').submit();
}
// payinshop
function payInShopFailure() {
//wyświetlamy odpowiedź
jQuery('#P24FormArea').html("<span class='info'>" + p24_payment_php_vars.error_msg4js + "</span>"); //'Wystąpił błąd. Spróbuj ponownie lub wybierz inną metodę płatności.'
P24_Transaction = undefined;
window.location = jQuery('[name=p24_url_return]').val();
}
var selector = '#P24_registerCard';
var waitForEl = function(selector, callback) {
if (jQuery(selector).length) {
jQuery('#P24_registerCard').prop('checked', (p24_payment_php_vars.forget_card == 1 ? false : true));
if (!parseInt(p24_payment_php_vars.show_save_card)) {
jQuery(jQuery(selector).parents('p')).hide();
}
jQuery(selector).on('change', function () {
var payload = jQuery(this).prop('checked') ? 0 : 1;
var url = jQuery('#p24-link-to-my-account').data('link');
jQuery.ajax({
method: 'POST',
url: url,
data: {
act: 'cc_forget',
cc_forget: payload
}
});
})
} else {
setTimeout(function() {
waitForEl(selector, callback);
}, 100);
}
};
waitForEl(selector, function() {
});
var tryArmBlikBox = function() {
var $additional_order_data = jQuery('#p24-additional-order-data')
var $termsAcceptanceCheckbox = jQuery('[name="p24_regulation_accept"]');
var url = jQuery('#p24_ajax_url').val();
if (!url) {
url = $additional_order_data.data('ajax-url');
}
var blikModalError = function() {
var $modal = jQuery('#p24-blik-modal');
$modal.removeClass('loading');
$modal.find('.error').show();
};
var executePaymentByBlikCode = function(trnData, blikCode, onError) {
jQuery.ajax({
url: url,
method: 'POST', type: 'POST',
dataType: 'json',
data: {
'action': 'executePaymentByBlikCode',
'token': trnData.token,
'blikCode': blikCode
}
}).success(function (response) {
if (response.success) {
setTimeout(function () {
location = jQuery('#przelewy_payment_form input[name=p24_url_return]').val();
}, 3000 /* Few seconds to accept transaction. */ );
} else {
onError();
}
}).error(onError);
};
var prepareModal = function ( onClose ) {
var $modal = jQuery('#p24-blik-modal');
if (!$modal.length) {
return false;
}
$modal.addClass('loading');
$modalBg = jQuery('#p24-blik-modal-background');
if ( onClose ) {
$modal.find('.close-modal').on('click', function (e) {
e.preventDefault();
onClose();
});
}
$modalBg.show();
return true;
};
var displayModal = function (nextSteep) {
var $modal = jQuery('#p24-blik-modal');
$modal.removeClass('loading');
var $button = $modal.find('button');
$button.on('click', function (e) {
e.preventDefault();
var $codeInput = $modal.find('input[type=text]');
var code = $codeInput.val();
var $acceptedInput = $modal.find('input[type=checkbox]');
if ($acceptedInput.length && !$acceptedInput.prop('checked')) {
$modal.find('.error-terms').show();
} else if (/^\d{6}$/.test(code)) {
$modal.addClass('loading');
nextSteep(code);
} else {
$modal.find('.error-common').show();
}
});
};
var trnRegisterPromise = function () {
var p24_session_id = jQuery('[name=p24_session_id]').val();
var order_id = jQuery('#p24_woo_order_id').val();
if (!order_id) {
order_id = $additional_order_data.data('order-id');
}
return jQuery.ajax({
url: url,
method: 'POST', type: 'POST',
dataType: 'json',
data: {
action: 'trnRegister',
p24_session_id: p24_session_id,
order_id: order_id
}
});
};
var trnRegisterLong = function () {
trnRegisterPromise().fail(payInShopFailure).done(function (data) {
var nextSteep = function (code) {
executePaymentByBlikCode(data, code, blikModalError);
};
displayModal(nextSteep)
});
};
var trnRegisterIfTerms = function() {
if ($termsAcceptanceCheckbox.attr('type') === 'checkbox' && !$termsAcceptanceCheckbox.is(':checked')) {
jQuery('#place_order').click();
return;
}
var hasModal = prepareModal(false);
if (hasModal) {
trnRegisterLong();
}
};
var tryArmBlikBoxConfirmation = function () {
/* Tile mode. */
var $logoBox = jQuery('#p24-bank-grid a.bank-box[data-id=181]');
if ($logoBox.length) {
$logoBox.on('click', function (e) {
e.preventDefault();
trnRegisterIfTerms();
});
}
/* Text mode. */
var $ourRadioInput = jQuery('#przelewy_method_id_181-');
if ($ourRadioInput.length) {
$ourRadioInput.on('change', function (e) {
if (!$ourRadioInput.prop('checked')) {
/* Nothing to do. */
return;
}
trnRegisterIfTerms();
});
}
/* There is a lot of magic in WooCommerce JavaScript. */
var $radioBox = jQuery('#payment_method_przelewy24_extra_181');
if ($radioBox.length) {
$radioBox.prop('checked', false);
jQuery("body").on("change", ".wc_payment_methods input[name='payment_method']", function () {
var $elm = jQuery(this);
if ($elm.prop('checked') && $elm.val() === 'przelewy24_extra_181') {
var hasModal = jQuery('#p24-blik-modal').length;
if (hasModal) {
var $checkoutButton = jQuery('.woocommerce-checkout');
var $terms = jQuery('#terms');
if ($terms.length && !$terms.prop('checked')) {
$checkoutButton.submit();
$elm.prop('checked', false)
} else {
var nextSteep = function (code) {
jQuery('#p24-blik-code-input').val(code);
$checkoutButton.submit();
}
prepareModal(false);
displayModal(nextSteep);
}
}
}
});
}
};
var tryExecuteBlik = function () {
var $input = jQuery('#przelewy_payment_form input[name=p24_provided_blik_code]');
if ($input.length) {
var code = $input.val();
if (code) {
var onError = function () {
var href = jQuery('#przelewy_payment_form a.button.cancel').attr('href');
location = href;
};
var hasModal = prepareModal(onError);
if (hasModal) {
if ($termsAcceptanceCheckbox.attr('type') === 'checkbox') {
/* We assume the the terms has been accepted on screen before. */
$termsAcceptanceCheckbox.prop('checked', true);
}
trnRegisterPromise().fail(onError).done(function (data) {
executePaymentByBlikCode(data, code, onError);
});
}
}
}
};
tryArmBlikBoxConfirmation();
tryExecuteBlik();
};
jQuery(document).ready(function () {
choosePaymentMethod();
jQuery('body').on('change', '[name="p24_regulation_accept"]:checked', function() {
var $selectedCreditCardPayment = jQuery('.bank-box.bank-item.selected[onclick^="showPayJsPopup"]');
if ($selectedCreditCardPayment.length) {
$selectedCreditCardPayment.click();
}
});
tryArmBlikBox();
});

View File

@@ -0,0 +1,91 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
<p><?php echo __('Zamówienie nr', 'przelewy24') . ' ' . $order->get_order_number() . ' ' . __('nie zostało opłacone.', 'przelewy24') . ' ' . __('Kliknij w poniższy link aby dokończyć płatność przez Przelewy24', 'przelewy24') ?></p>
<div style="text-align:center; font-size:200%; margin-bottom:5%"><a href="<?php echo filter_var( $order->get_checkout_payment_url( true ), FILTER_SANITIZE_URL ); ?>"><?php echo __('Zapłać z Przelewy24', 'przelewy24')?></a></div>
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$text_align = is_rtl() ? 'right' : 'left';
?>
<h2>
<?php
if ( $sent_to_admin ) {
$before = '<a class="link" href="' . esc_url( $order->get_edit_order_url() ) . '">';
$after = '</a>';
} else {
$before = '';
$after = '';
}
/* translators: %s: Order ID. */
echo wp_kses_post( $before . sprintf( __( 'Zamówienie', 'przelewy24' ) . $after . ' (<time datetime="%s">%s</time>)', $order->get_order_number(), $order->get_date_created()->format( 'c' ), wc_format_datetime( $order->get_date_created() ) ) );
?>
</h2>
<div style="margin-bottom: 40px;">
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
<thead>
<tr>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Produkt', 'przelewy24' ); ?></th>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Ilość', 'przelewy24' ); ?></th>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Cena', 'przelewy24' ); ?></th>
</tr>
</thead>
<tbody>
<?php
echo wc_get_email_order_items( $order, array( // WPCS: XSS ok.
'show_sku' => $sent_to_admin,
'show_image' => false,
'image_size' => array( 32, 32 ),
'plain_text' => $plain_text,
'sent_to_admin' => $sent_to_admin,
) );
?>
</tbody>
<tfoot>
<?php
$totals = $order->get_order_item_totals();
if ( $totals ) {
$i = 0;
foreach ( $totals as $total ) {
$i++;
?>
<tr>
<th class="td" scope="row" colspan="2" style="text-align:<?php echo esc_attr( $text_align ); ?>; <?php echo ( 1 === $i ) ? 'border-top-width: 4px;' : ''; ?>"><?php echo wp_kses_post( $total['label'] ); ?></th>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>; <?php echo ( 1 === $i ) ? 'border-top-width: 4px;' : ''; ?>"><?php echo wp_kses_post( $total['value'] ); ?></td>
</tr>
<?php
}
}
if ( $order->get_customer_note() ) {
?>
<tr>
<th class="td" scope="row" colspan="2" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Komentarz:', 'przelewy24' ); ?></th>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php echo wp_kses_post( wptexturize( $order->get_customer_note() ) ); ?></td>
</tr>
<?php
}
?>
</tfoot>
</table>
</div>
<?php
do_action( 'woocommerce_email_after_order_table', $order, $sent_to_admin, $plain_text, $email );
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
do_action( 'woocommerce_email_footer', $email );

View File

@@ -0,0 +1,85 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
<?php
$text_align = is_rtl() ? 'right' : 'left';
?>
<h2>
<?php
if ( $sent_to_admin ) {
$before = '<a class="link" href="' . esc_url( $order->get_edit_order_url() ) . '">';
$after = '</a>';
} else {
$before = '';
$after = '';
}
/* translators: %s: Order ID. */
echo wp_kses_post( $before . sprintf( __( 'Zamówienie', 'przelewy24' ) . $after . ' (<time datetime="%s">%s</time>)', $order->get_order_number(), $order->get_date_created()->format( 'c' ), wc_format_datetime( $order->get_date_created() ) ) );
?>
</h2>
<div style="margin-bottom: 40px;">
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
<thead>
<tr>
<th class="td" scope="col" style="text-align: <?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Produkt', 'przelewy24' ); ?></th>
<th class="td" scope="col" style="text-align: <?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Ilość', 'przelewy24' ); ?></th>
<th class="td" scope="col" style="text-align: <?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Cena', 'przelewy24' ); ?></th>
</tr>
</thead>
<tbody>
<?php
echo wc_get_email_order_items( $order, array( // WPCS: XSS ok.
'show_sku' => $sent_to_admin,
'show_image' => false,
'image_size' => array( 32, 32 ),
'plain_text' => $plain_text,
'sent_to_admin' => $sent_to_admin,
) );
?>
</tbody>
<tfoot>
<?php
$totals = $order->get_order_item_totals();
if ( $totals ) {
$i = 0;
foreach ( $totals as $total ) {
$i++;
?>
<tr>
<th class="td" scope="row" colspan="2" style="text-align: <?php echo esc_attr( $text_align ); ?>; <?php echo ( 1 === $i ) ? 'border-top-width: 4px;' : ''; ?>"><?php echo wp_kses_post( $total['label'] ); ?></th>
<td class="td" style="text-align: <?php echo esc_attr( $text_align ); ?>; <?php echo ( 1 === $i ) ? 'border-top-width: 4px;' : ''; ?>"><?php echo wp_kses_post( $total['value'] ); ?></td>
</tr>
<?php
}
}
if ( $order->get_customer_note() ) {
?>
<tr>
<th class="td" scope="row" colspan="2" style="text-align: <?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Komentarz:', 'przelewy24' ); ?></th>
<td class="td" style="text-align: <?php echo esc_attr( $text_align ); ?>;"><?php echo wp_kses_post( wptexturize( $order->get_customer_note() ) ); ?></td>
</tr>
<?php
}
?>
</tfoot>
</table>
</div>
<?php
do_action( 'woocommerce_email_after_order_table', $order, $sent_to_admin, $plain_text, $email );
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
do_action( 'woocommerce_email_footer', $email );

View File

@@ -0,0 +1,48 @@
<?php
/**
* Template for email about subscription cancelation.
*
* @package Przelewy24
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! isset( $email_heading ) ) {
throw new LogicException( 'The variable $email_heading is not set.' );
}
if ( ! isset( $email ) ) {
throw new LogicException( 'The variable $email is not set.' );
}
if ( ! isset( $subscription_title ) ) {
throw new LogicException( 'The variable $subscription_title is not set.' );
}
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
<?php
$text_align = is_rtl() ? 'right' : 'left';
?>
<h2>
<?php echo esc_html( __( 'Anulowanie subskrypcji' ) ); ?>
<?php echo wp_kses_post( $subscription_title ); ?>
</h2>
<div style="margin-bottom: 40px;">
<?php echo esc_html( __( 'Twoja subskrypcja została anulowana.' ) ); ?>
<dl>
<dt><?php echo esc_html( __( 'Nazwa subskrypcji:' ) ); ?></dt>
<dd><?php echo wp_kses_post( $subscription_title ); ?></dd>
</dl>
<?php echo esc_html( __( 'W celu uzyskania szczegułów, prosimy skontaktować się z obsługą sklepu.' ) ); ?>
</div>
<?php
do_action( 'woocommerce_email_footer', $email );

View File

@@ -0,0 +1,236 @@
<?php
class Przelewy24Generator
{
const P24NOW = 266;
/**
* @var WC_Gateway_Przelewy24
*/
private $gateway;
/**
* Przelewy24Generator constructor.
*
* @param WC_Gateway_Przelewy24 $gateway The class that provide configuration.
*/
public function __construct(WC_Gateway_Przelewy24 $gateway) {
$this->gateway = $gateway;
}
/**
* Generate przelewy24 button link
*
* @param WC_Order $order
* @param string|null $transaction_id
* @return array|false
* @throws Exception
*/
public function generate_fields_array($order, $transaction_id = null)
{
if (!$order) return false;
global $locale;
$localization = !empty($locale) ? explode("_", $locale) : 'pl';
/* We need raw order id integer to generate transaction and get metadata. */
$order_id = (int) $order->get_id();
if (is_null($transaction_id)) {
$transaction_id = $order_id . "_" . uniqid(md5($order_id . '_' . date("ymds")), true);
}
$description_order_id = $order->get_order_number();
// modifies order number if Sequential Order Numbers Pro plugin is installed
if (class_exists('WC_Seq_Order_Number_Pro')) {
$seq = new WC_Seq_Order_Number_Pro();
$description_order_id = $seq->get_order_number($description_order_id, $order);
} else if (class_exists('WC_Seq_Order_Number')) {
$seq = new WC_Seq_Order_Number();
$description_order_id = $seq->get_order_number($description_order_id, $order);
}
$config = $this->gateway->load_settings_from_db_formatted( $order->get_currency() );
$config->access_mode_to_strict();
//p24_opis depend of test mode
$desc = ($config->is_p24_operation_mode( 'sandbox' ) ? __('Transakcja testowa', 'przelewy24') . ', ' : '') .
__('Zamówienie nr', 'przelewy24') . ': ' . $description_order_id . ', ' . $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() . ', ' . date('Ymdhi');
$status_page = add_query_arg(array('wc-api' => 'WC_Gateway_Przelewy24'), home_url('/'));
/*Form send to przelewy24*/
$amount = $order->get_total() * 100;
$amount = number_format($amount, 0, "", "");
$currency = strtoupper($order->get_currency());
$przelewy24_arg = array(
'p24_session_id' => addslashes($transaction_id),
'p24_merchant_id' => (int) $config->get_merchant_id(),
'p24_pos_id' => (int) $config->get_shop_id(),
'p24_email' => filter_var($order->get_billing_email(), FILTER_SANITIZE_EMAIL),
'p24_amount' => (int)$amount,
'p24_currency' => filter_var($currency, FILTER_SANITIZE_STRING),
'p24_description' => addslashes($desc),
'p24_language' => filter_var($localization[0], FILTER_SANITIZE_STRING),
'p24_client' => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
'p24_address' => $order->get_billing_address_1(),
'p24_city' => $order->get_billing_city(),
'p24_zip' => $order->get_billing_postcode(),
'p24_country' => $order->get_billing_country(),
'p24_encoding' => 'UTF-8',
'p24_url_status' => filter_var($status_page, FILTER_SANITIZE_URL),
'p24_url_return' => filter_var(WC_Gateway_Przelewy24::getReturnUrlStatic($order), FILTER_SANITIZE_URL),
'p24_api_version' => P24_VERSION,
'p24_ecommerce' => 'woocommerce_' . WOOCOMMERCE_VERSION,
'p24_ecommerce2' => '1.0.0',
'p24_method' => (int)get_post_meta($order_id, 'p24_method', true),
'p24_shipping' => number_format($order->get_shipping_total() * 100, 0, '', ''),
'p24_wait_for_result' => (int) $config->get_p24_wait_for_result(),
'p24_provided_blik_code' => $order->get_meta(P24_Extra_Gateway::BLIK_CODE_META_KEY),
'p24_channel' => '',
);
if ($this->activateChannel2ki($przelewy24_arg)) {
$przelewy24_arg['p24_channel'] = 2048;
}
$productsInfo = array();
foreach ($order->get_items() as $product) {
$productsInfo[] = array(
'name' => filter_var($product['name'], FILTER_SANITIZE_STRING),
'description' => strip_tags(get_post($product['product_id'])->post_content),
'quantity' => (int)$product['qty'],
'price' => ($product['line_total'] / $product['qty']) * 100,
'number' => (int)$product['product_id'],
);
}
$shipping = number_format($order->get_shipping_total() * 100, 0, '', '');
$translations = array(
'virtual_product_name' => __('Dodatkowe kwoty [VAT, rabaty]', 'przelewy24'),
'cart_as_product' => __('Twoje zamówienie', 'przelewy24'),
);
$p24Product = new Przelewy24Product($translations);
$p24ProductItems = $p24Product->prepareCartItems($amount, $productsInfo, $shipping);
$przelewy24_arg = array_merge($przelewy24_arg, $p24ProductItems);
Przelewy24Class::checkMandatoryFieldsForAction($przelewy24_arg);
return $przelewy24_arg;
}
/**
* Generate payload for REST transaction.
*
* @param WC_Order $order
* @param null|string $transaction_id
* @param null|int $method
* @return array
* @throws Exception
*/
public function generate_payload_for_rest( $order, $transaction_id = null, $method = null ) {
$args = $this->generate_fields_array( $order, $transaction_id );
$status_page = add_query_arg(array('wc-api' => 'WC_Gateway_Przelewy24', 'status' => 'REST'), home_url('/'));
return array(
"merchantId" => (int)$args['p24_merchant_id'],
"posId" => (int)$args['p24_pos_id'],
"sessionId" => (string)$args["p24_session_id"],
"amount" => (int)$args["p24_amount"],
"currency" => (string)$args["p24_currency"],
"description" => (string)$args["p24_description"],
"email" => (string)$args["p24_email"],
"client" => (string)$args["p24_client"],
"address" => (string)$args["p24_address"],
"zip" => (string)$args["p24_zip"],
"city" => (string)$args["p24_city"],
"country" => (string)$args["p24_country"],
"language" => (string)$args["p24_language"],
"urlReturn" => (string)$args["p24_url_return"],
"urlStatus" => (string)filter_var($status_page, FILTER_SANITIZE_URL),
"shipping" => (int)$args["p24_shipping"],
"encoding" => (string)$args["p24_encoding"],
"method" => ($method||$args["p24_method"])?($method?:$args["p24_method"]):null
);
}
/**
* @param WC_Order $order
* @param bool $autoSubmit
* @param bool $makeRecurringForm
* @return string
* @throws Exception
*/
public function generate_przelewy24_form($order, $autoSubmit = true, $makeRecurringForm = false)
{
$przelewy24_arg = $this->generate_fields_array($order);
$config = $this->gateway->load_settings_from_db_formatted( $order->get_currency() );
$strict_config = clone $config;
$strict_config->access_mode_to_strict();
$blik_code = '';
if ($strict_config->get_p24_payinshop()) {
$blik_code .= '<input type="hidden" name="p24_url_return" value="' . $przelewy24_arg['p24_url_return'] . '" />'."\n";
}
if ((int)$przelewy24_arg['p24_method'] === (int)P24_Extra_Gateway::BLIK_METHOD && $przelewy24_arg['p24_provided_blik_code']) {
$blik_code .= '<input type="hidden" name="p24_provided_blik_code" value="' . $przelewy24_arg['p24_provided_blik_code'] . '" />'."\n";
}
$accept_in_shop = '';
if ( $config->get_p24_acceptinshop() === 'yes' && $config->get_p24_show_methods_confirmation() === 'yes' ) {
$accept_in_shop = '<p><label><input type="checkbox" required="required" name="p24_regulation_accept" value="1" />'. __('Tak, przeczytałem i akceptuję regulamin Przelewy24.', 'przelewy24') .'</label></p>';
}
$return = '<div id="payment" style="background: none"> ' .
'<form action="'.get_rest_url(null,'/przelewy24/v1/create-payment').'" method="post" id="przelewy_payment_form"'.
($autoSubmit ? '' : ' onSubmit="return p24_processPayment()" ') .
'><input type="hidden" name="order_id" value="'.((int) $order->get_id()).'"> ' .
"<input type=\"hidden\" name=\"p24_session_id\" value=\"{$przelewy24_arg['p24_session_id']}\" />".
"<input type=\"hidden\" name=\"p24_method\" />".
$blik_code .
$accept_in_shop .
'<input type="submit" class="button alt" id="place_order" value="' . __('Potwierdzam zamówienie', 'przelewy24') . '" /> ' .
'<p style="text-align:right; float:right; width:100%; font-size:12px;">' . __('Złożenie zamówienia wiąże się z obowiązkiem zapłaty', 'przelewy24') . '</p>' .
'<a class="button cancel" href="' . $order->get_cancel_order_url() . '">' . __('Anuluj zamówienie', 'przelewy24') . '</a>' .
($autoSubmit ?
'<script type="text/javascript">jQuery(function(){jQuery("body").block({message: "' .
__('Dziękujemy za złożenie zamówienia. Za chwilę nastąpi przekierowanie na stronę przelewy24.pl', 'przelewy24') .
'",overlayCSS: {background: "#fff",opacity: 0.6},css: {padding:20,textAlign:"center",color:"#555",border:"2px solid #AF2325",backgroundColor:"#fff",cursor:"wait",lineHeight:"32px"}});' .
'jQuery("#przelewy_payment_form input[name=p24_regulation_accept]").prop("required", false);' .
'p24_processPayment(); });' .
'</script>' : '') .
'</form>' .
'</div>' .
'';
if (!!$makeRecurringForm) {
$return .= <<<FORMRECURING
<form method="post" id="przelewy24FormRecuring" name="przelewy24FormRecuring" accept-charset="utf-8">
<input type="hidden" name="p24_session_id" value="{$przelewy24_arg['p24_session_id']}" />
<input type="hidden" name="p24_regulation_accept" />
<input type="hidden" name="p24_cc" />
</form>
FORMRECURING;
}
return $return;
}
/**
* Check if activate channel 2024.
*
* @param array $przelewy24_arg
*
* @return bool
*/
private function activateChannel2ki(array $przelewy24_arg)
{
$hasP24NowSelected = self::P24NOW === $przelewy24_arg['p24_method'];
/* The p24_amount is PLN * 100. */
$isAmount = (int)$przelewy24_arg['p24_amount'] < (100 * 10000) && (int)$przelewy24_arg['p24_amount'] > 0;
$isCurrency = $przelewy24_arg['p24_currency'] == "PLN";
return $isCurrency && $isAmount && $hasP24NowSelected;
}
}

View File

@@ -0,0 +1,95 @@
<?php
class Przelewy24Helpers
{
public static function getBankTxt(&$checkedCounter, $bank_id, $bank_name, $text = '', $cc_id = '', $class = '', $onclick = '')
{
$checkedCounter++;
$bank_id = sanitize_text_field($bank_id);
$bank_name = sanitize_text_field($bank_name);
$text = sanitize_text_field($text);
$cc_id = sanitize_text_field($cc_id);
$class = sanitize_text_field($class);
$onclick = sanitize_text_field($onclick);
return
'
<li onclick="' . $onclick . '">' .
'<div class="input-box bank-item" data-id="' . (int)$bank_id . '" data-cc="' . $cc_id . '" data-text="' . $text . '" >' .
'<label for="przelewy_method_id_' . $bank_id . '-' . $cc_id . '">' .
'<input id="przelewy_method_id_' . $bank_id . '-' . $cc_id . '" name="payment_method_id" ' .
' class="radio" type="radio" ' . ($checkedCounter == 1 ? 'checked="checked"' : '') . ' />' .
'<span>' . $bank_name . '</span></label>' .
(empty($cc_id) ? '' : '<span class="removecc" ' .
' title="' . __('Usuń zapamiętaną kartę', 'przelewy24') . ' ' . $bank_name . ' ' . $text . '" ' .
' onclick="arguments[0].stopPropagation(); if (confirm(\'' . __('Czy na pewno?', 'przelewy24') . '\')) removecc(' . $cc_id . ')"></span>') .
'</div></li>
';
}
public static function getExtraPromotedTxt(&$checkedCounter, $bank_id, $bank_name, $text = '', $cc_id = '', $class = '', $onclick = '')
{
$checkedCounter++;
$bank_id = sanitize_text_field($bank_id);
$bank_name = sanitize_text_field($bank_name);
$text = sanitize_text_field($text);
$cc_id = sanitize_text_field($cc_id);
$class = sanitize_text_field($class);
$onclick = sanitize_text_field($onclick);
return
'
<li onclick="' . $onclick . '">' .
'<div class="input-box bank-box bank-item" data-id="' . (int)$bank_id . '" data-cc="' . $cc_id . '" data-text="' . $text . '" >' .
'<label for="przelewy_method_id_' . $bank_id . '-' . $cc_id . '">' .
'<input id="przelewy_method_id_' . $bank_id . '-' . $cc_id . '" name="payment_method_id" ' .
' class="radio" type="radio" ' . ($checkedCounter == 1 ? 'checked="checked"' : '') . ' />' .
'<span>' . $bank_name . '</span></label>' .
(empty($cc_id) ? '' : '<span class="removecc" ' .
' title="' . __('Usuń zapamiętaną kartę', 'przelewy24') . ' ' . $bank_name . ' ' . $text . '" ' .
' onclick="arguments[0].stopPropagation(); if (confirm(\'' . __('Czy na pewno?', 'przelewy24') . '\')) removecc(' . $cc_id . ')"></span>') .
'</div></li>
';
}
public static function checkoutOrderProcessed($order_id, $posted)
{
if (empty($_POST) || empty($_POST['selected_banks']) || !is_array($_POST['selected_banks'])) {
return false;
}
return false;
}
/**
* Set custom data.
*
* @param string $data_type Data type.
* @param int $data_id Data id.
* @param string $key Key.
* @param string|object|array $value Value.
* @return bool True on success.
*/
public static function setCustomData($data_type, $data_id, $key, $value)
{
global $wpdb;
$table_name = $wpdb->prefix . 'woocommerce_p24_data';
if ($key != 'oneclick') {
$wpdb->delete($table_name, ['data_type' => $data_type, 'data_id' => $data_id, 'custom_key' => $key], ['%s', '%d', '%s']);
}
if (empty($value)) return false;
if (is_object($value) || is_array($value)) $value = json_encode($value);
return (bool) $wpdb->insert($table_name, array(
'data_type' => $data_type,
'data_id' => $data_id,
'custom_key' => $key,
'custom_value' => $value,
), array('%s', '%d', '%s', '%s'));
}
}

View File

@@ -0,0 +1,103 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit;
/**
* Class Przelewy24Mailer
*/
class Przelewy24Mailer {
/**
* Function to find gateway that can provide configuration.
*
* @return null|WC_Gateway_Przelewy24 The class that can provide configuration.
*/
private function find_p24_gateway() {
$gateways = WC()->payment_gateways()->payment_gateways;
foreach ($gateways as $gateway) {
if ($gateway instanceof WC_Gateway_Przelewy24) {
return $gateway;
}
}
return null;
}
/**
* Send amil.
*
* @param WC_Order|null $order Order that need an mail.
*/
public function trigger( $order ) {
if ( !$order )
return;
if($order->is_paid() || $order->get_payment_method() !== 'przelewy24')
return;
$subject = __('Dziękujemy za złożenie zamówienia', 'przelewy24');
$this->send_email( $order, $subject, '/emails/notification_email.php' );
}
/**
* Send order summary email.
*
* @param WC_Order|null $order Order that need an mail.
*/
public function send_order_summary_mail( $order )
{
if (
! $order ||
$order->get_payment_method() !== WC_Gateway_Przelewy24::PAYMENT_METHOD ||
! get_przelewy24_plugin_instance()->should_activate_order_created_notification()
) {
return;
}
$subject = __('Dziękujemy za złożenie zamówienia', 'przelewy24');
$this->send_email( $order, $subject, '/emails/order_summary.php' );
}
/**
* Get email content
*
* @param string $template
* @param WC_Order $order
* @param bool $heading
* @param WC_Emails $mailer
*
* @return string
*/
function get_content( $template, $order, $heading = false, $mailer ) {
return wc_get_template_html( $template, array(
'order' => $order,
'email_heading' => $heading,
'sent_to_admin' => false,
'plain_text' => false,
'email' => $mailer,
), '', PRZELEWY24_PATH );
}
/**
* Perform sending email
*
* @param WC_Order $order
* @param string $subject
* @param string $template
*/
private function send_email( $order, $subject, $template )
{
$recipient = $order->get_billing_email();
$mailer = WC()->mailer();
$content = $this->get_content( $template, $order, $subject, $mailer );
$headers = 'Content-Type: text/html';
$mailer->send( $recipient, $subject, $content, $headers );
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
<?php
/**
* File that define P24_Soap_Blik_Html.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class P24_Soap_Blik_Html
*/
class P24_Blik_Html {
/**
* Plugin core.
*
* @var P24_Core The plugin core.
*/
private $core;
/**
* P24_Blik_Html constructor.
*
* @param P24_Core $core The plugin core.
*/
public function __construct( $core ) {
$this->core = $core;
add_action( 'woocommerce_checkout_after_order_review', array( $this, 'extend_checkout_page_form' ) );
add_action( 'woocommerce_after_checkout_form', array( $this, 'extend_checkout_page_bottom' ) );
}
/**
* Get additional HTML code for checkout form.
*/
public function extend_checkout_page_form() {
echo '<input type="hidden" id="p24-blik-code-input" name="p24-blik-code">';
}
/**
* Extend_checkout_page_bottom.
*
* Check and embed code for modal if needed on checkout page.
*/
public function extend_checkout_page_bottom() {
$config = $this->core->get_config_for_currency();
$config->access_mode_to_strict();
if ( $config->get_p24_payinshop() ) {
$display_terms = $config->get_p24_acceptinshop();
self::echo_modal_html( $display_terms );
}
}
/**
* Get HTML code for modal
*
* @param bool $need_terms If checkbox to show terms is needed. Default to false.
*
* @return string
*/
public static function get_modal_html( $need_terms = false ) {
$header = esc_html( __( 'Wprowadź kod BLIK', 'przelewy24' ) );
$label = esc_html( __( 'Wprowadź 6-cyfrowy kod BLIK pobrany z aplikacji bankowej.', 'przelewy24' ) );
$error = esc_html( __( 'Niepoprawny kod BLIK.', 'przelewy24' ) );
$unccepted = esc_html( __( 'Brak zaakceptowanego regulaminu Przelewy24.', 'przelewy24' ) );
$button = esc_html( __( 'Zapłać', 'przelewy24' ) );
$terms = esc_html( __( 'Tak, przeczytałem i akceptuję regulamin Przelewy24.', 'przelewy24' ) );
if ( $need_terms ) {
$terms_input = <<<TERMS
<p>
<label>
<input type="checkbox" name="terms">
$terms
</label>
</p>
<p class="error error-terms">$unccepted</p>
TERMS;
} else {
$terms_input = "\n";
}
return <<<MODAL
<div id="p24-blik-modal-background">
<div id="p24-blik-modal-holder">
<div id="p24-blik-modal">
<h1>$header</h1>
<a href="" class="close-modal">✖</a>
<form>
<div>
<p>$label</p>
<p>
<input type="text" name="blik" placeholder="______" pattern="^\d{6}$" maxlength="6">
</p>
<p class="error error-common">$error</p>
$terms_input
<p>
<button>$button</button>
</p>
</div>
</form>
</div>
</div>
</div>
MODAL;
}
/**
* Echo HTML code for modal
*
* @param bool $need_terms If checkbox to show terms is needed. Default to false.
*/
public static function echo_modal_html( $need_terms = false ) {
echo self::get_modal_html( $need_terms ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}

View File

@@ -0,0 +1,146 @@
<?php
/**
* File that define P24_Communication_Parser class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class to parse input from Przelewy24 backend.
*/
class P24_Communication_Parser {
/**
* Set for true if response is from Przelewy24.
*
* @var bool
*/
private $is_przelewy24_response = false;
/**
* Set for true if CRC is valid.
*
* @var bool
*/
private $is_crc_valid = false;
/**
* The currency of response.
*
* @var null|string
*/
private $currency;
/**
* The response from Przelewy24.
*
* @var null|array
*/
private $response;
/**
* Class to validate messages.
*
* @var P24_Message_Validator
*/
private $message_validator;
/**
* P24_Communication_Parser constructor.
*
* @param P24_Message_Validator $message_validator P24_Message_Validator instance.
*/
public function __construct( P24_Message_Validator $message_validator ) {
$this->message_validator = $message_validator;
}
/**
* Return request.
*
* @return array
*/
private function get_post_data() {
wp_verify_nonce( null ); /* There is no nonce in request. */
if ( is_array( $_POST ) ) {
return $_POST;
} else {
return array();
}
}
/**
* Parse and validate POST response data from Przelewy24.
*
* @param WC_Gateway_Przelewy24 $gateway The gateway.
* @return bool True on success, false otherwise.
*/
public function parse_status_response( WC_Gateway_Przelewy24 $gateway ) {
$this->is_przelewy24_response = false;
$this->is_crc_valid = false;
$this->currency = null;
$this->response = null;
$data = $this->get_post_data();
if ( ! isset( $data['p24_session_id'], $data['p24_order_id'], $data['p24_merchant_id'], $data['p24_pos_id'], $data['p24_amount'], $data['p24_currency'], $data['p24_method'], $data['p24_sign'] ) ) {
/* Early exit. */
return false;
}
$this->is_przelewy24_response = true;
$session_id = $this->message_validator->filter_value( 'p24_session_id', $data['p24_session_id'] );
$merchant_id = $this->message_validator->filter_value( 'p24_merchant_id', $data['p24_merchant_id'] );
$pos_id = $this->message_validator->filter_value( 'p24_pos_id', $data['p24_pos_id'] );
$order_id = $this->message_validator->filter_value( 'p24_order_id', $data['p24_order_id'] );
$amount = $this->message_validator->filter_value( 'p24_amount', $data['p24_amount'] );
$currency = $this->message_validator->filter_value( 'p24_currency', $data['p24_currency'] );
$method = $this->message_validator->filter_value( 'p24_method', $data['p24_method'] );
$sign = $this->message_validator->filter_value( 'p24_sign', $data['p24_sign'] );
$this->currency = $currency;
$config = $gateway->load_settings_from_db_formatted( $currency );
$expected_sign = md5( $session_id . '|' . $order_id . '|' . $amount . '|' . $currency . '|' . $config->get_salt() );
if ( $merchant_id === $config->get_merchant_id()
&& $pos_id === $config->get_shop_id()
&& $sign === $expected_sign
) {
$this->is_crc_valid = true;
$this->response = array(
'p24_session_id' => $session_id,
'p24_order_id' => $order_id,
'p24_amount' => $amount,
'p24_currency' => $currency,
'p24_method' => $method,
);
return true;
} else {
return false;
}
}
/**
* Return if request was valid.
*
* @return bool
*/
public function is_valid() {
return $this->is_crc_valid;
}
/**
* Get currency.
*
* @return string
* @throws LogicException If request is not validated.
*/
public function get_currency() {
if ( $this->currency ) {
return $this->currency;
} else {
$msg = 'You have to validate request first.';
throw new LogicException( $msg );
}
}
}

View File

@@ -0,0 +1,703 @@
<?php
/**
* File that define P24_Config_Accessor class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Accessor for P24_Config_Holder.
*
* This class know active currency and style of booleans.
* These two properties are unknown to P24_Config_Holder.
*/
class P24_Config_Accessor {
const AM_STRICT = 'am_strict';
const AM_WORDPRESS = 'am_wordpress';
/**
* Name of currency that is described by config.
*
* @var string
*/
private $currency;
/**
* The object holding config.
*
* @var P24_Config_Holder
*/
private $config;
/**
* The style of accessor.
*
* The booleans may be expected to be in form yes/no.
*
* @var string
*/
private $access_mode;
/**
* Array holding translation of bool representations.
*
* @var array
*/
private $bool_translation_table;
/**
* The constructor.
*
* The default boolean mode is yes/no.
*
* @param string $currency Name of currency.
* @param P24_Config_Holder $config The config.
*/
public function __construct( $currency, P24_Config_Holder $config ) {
$this->currency = (string) $currency;
$this->config = $config;
$this->access_mode_to_wordpress();
$this->bool_translation_table = array(
self::AM_STRICT => array( false, true ),
self::AM_WORDPRESS => array( 'no', 'yes' ),
);
$this->fix_booleans();
}
/**
* Convert variable to selected bool representation.
*
* @param bool $input The input variable to be converted.
* @return bool|string
* @throws InvalidArgumentException If conversion cannot be made.
*/
public function to_selected_bool( $input ) {
if ( false === $input ) {
return $this->bool_translation_table[ $this->access_mode ][0];
} elseif ( true === $input ) {
return $this->bool_translation_table[ $this->access_mode ][1];
} else {
throw new InvalidArgumentException( 'Wrong input type, it has to be bool.' );
}
}
/**
* Convert variable from selected bool representation.
*
* @param bool|string $input The input variable to be converted.
* @return bool
* @throws InvalidArgumentException If conversion cannot be made.
*/
public function from_selected_bool( $input ) {
$row = $this->bool_translation_table[ $this->access_mode ];
$key = array_search( $input, $row, true );
if ( 0 === $key ) {
return false;
} elseif ( 1 === $key ) {
return true;
} else {
throw new InvalidArgumentException( 'Wrong input, it cannot be converted to bool.' );
}
}
/**
* Convert all booleans in config to PHP representation.
*/
private function fix_booleans() {
$to_fix = array(
'p24_oneclick',
'p24_payinshop',
'p24_acceptinshop',
'p24_show_methods_checkout',
'p24_show_methods_confirmation',
'p24_graphics',
'p24_wait_for_result',
'p24_use_special_status',
'sub_enabled',
);
foreach ( $to_fix as $one ) {
if ( null === $this->config->{$one} ) {
$this->config->{$one} = false;
} elseif ( ! is_bool( $this->config->{$one} ) ) {
$this->config->{$one} = self::from_selected_bool( $this->config->{$one} );
}
}
}
/**
* The cloner.
*/
public function __clone() {
$this->config = clone $this->config;
}
/**
* Set access mode for booleans to PHP types.
*
* @return $this
*/
public function access_mode_to_strict() {
$this->access_mode = self::AM_STRICT;
return $this;
}
/**
* Set access mode for booleans to strings yes and no.
*
* @return $this
*/
public function access_mode_to_wordpress() {
$this->access_mode = self::AM_WORDPRESS;
return $this;
}
/**
* Get currency.
*
* @return string
*/
public function get_currency() {
return (string) $this->currency;
}
/**
* Get title from config.
*
* @return string
*/
public function get_title() {
return (string) $this->config->title;
}
/**
* Set title in config.
*
* @param string $title The new title.
* @return P24_Config_Accessor
*/
public function set_title( $title ) {
$this->config->title = (string) $title;
return $this;
}
/**
* Get merchant_id from config.
*
* @return string
*/
public function get_merchant_id() {
return (string) $this->config->merchant_id;
}
/**
* Set merchant_id in config.
*
* @param string $merchant_id The new merchant_id.
* @return P24_Config_Accessor
*/
public function set_merchant_id( $merchant_id ) {
$this->config->merchant_id = (string) $merchant_id;
return $this;
}
/**
* Get shop_id form config.
*
* @return string
*/
public function get_shop_id() {
return (string) $this->config->shop_id;
}
/**
* Set shop_id in config.
*
* @param string $shop_id The new shop_id.
* @return P24_Config_Accessor
*/
public function set_shop_id( $shop_id ) {
$this->config->shop_id = (string) $shop_id;
return $this;
}
/**
* Get salt from config.
*
* @return string
*/
public function get_salt() {
return (string) $this->config->salt;
}
/**
* Set salt in config.
*
* @param string $salt The new salt.
* @return P24_Config_Accessor
*/
public function set_salt( $salt ) {
$this->config->salt = (string) $salt;
return $this;
}
/**
* Get operation mode from config.
*
* @return string The new p24_operation_mode
*/
public function get_p24_operation_mode() {
return (string) $this->config->p24_operation_mode;
}
/**
* Set operation mode in config.
*
* @param string $p24_operation_mode The new p24_operation_mode.
* @return P24_Config_Accessor
*/
public function set_p24_operation_mode( $p24_operation_mode ) {
$this->config->p24_operation_mode = (string) $p24_operation_mode;
return $this;
}
/**
* Compare modes and return bool.
*
* @param string $checked The value to compare mode with.
* @return bool|string
*/
public function is_p24_operation_mode( $checked ) {
$mode = $this->get_p24_operation_mode();
$is_mode = $checked === $mode;
return $this->to_selected_bool( $is_mode );
}
/**
* Get description from config.
*
* @return string
*/
public function get_description() {
return (string) $this->config->description;
}
/**
* Set description in config.
*
* @param string $description The new description.
* @return P24_Config_Accessor
*/
public function set_description( $description ) {
$this->config->description = (string) $description;
return $this;
}
/**
* Get p24_api from config.
*
* @return string
*/
public function get_p24_api() {
return (string) $this->config->p24_api;
}
/**
* Set p24_api in config.
*
* @param string $p24_api The new p24_api.
* @return P24_Config_Accessor
*/
public function set_p24_api( $p24_api ) {
$this->config->p24_api = (string) $p24_api;
return $this;
}
/**
* Get p24_paymethods_super_first from config.
*
* @return string
*/
public function get_p24_paymethods_super_first() {
return (string) $this->config->p24_paymethods_super_first;
}
/**
* Set p24_paymethods_super_first in config.
*
* @param string $p24_paymethods_super_first The new p24_paymethods_first.
* @return P24_Config_Accessor
*/
public function set_p24_paymethods_super_first( $p24_paymethods_super_first ) {
$this->config->p24_paymethods_super_first = (string) $p24_paymethods_super_first;
return $this;
}
/**
* Return p24_oneclick from config.
*
* The value is converted to selected representation.
*
* @return bool|string
* @throws LogicException If the internal representation of value is broken.
*/
public function get_p24_oneclick() {
try {
$p24_oneclick = $this->config->p24_oneclick;
return $this->to_selected_bool( $p24_oneclick );
} catch ( InvalidArgumentException $ex ) {
$msg = 'The internal representation of p24_oneclick is invalid.';
throw new LogicException( $msg, 0, $ex );
}
}
/**
* Set p24_oneclick in config.
*
* The input is expected to be in selected representation.
*
* @param bool|string $p24_oneclick The new p24_oneclick.
* @return P24_Config_Accessor
* @throws InvalidArgumentException If input is in wrong representation.
*/
public function set_p24_oneclick( $p24_oneclick ) {
$this->config->p24_oneclick = $this->from_selected_bool( $p24_oneclick );
return $this;
}
/**
* Return p24_payinshop from config.
*
* The value is converted to selected representation.
*
* @return bool|string
* @throws LogicException If the internal representation of value is broken.
*/
public function get_p24_payinshop() {
try {
$p24_payinshop = $this->config->p24_payinshop;
return $this->to_selected_bool( $p24_payinshop );
} catch ( InvalidArgumentException $ex ) {
$msg = 'The internal representation of p24_payinshop is invalid.';
throw new LogicException( $msg, 0, $ex );
}
}
/**
* Set p24_acceptinshop in config.
*
* The input is expected to be in selected representation.
*
* @param bool|string $p24_acceptinshop The new p24_oneclick.
* @return P24_Config_Accessor
* @throws InvalidArgumentException If input is in wrong representation.
*/
public function set_p24_acceptinshop( $p24_acceptinshop ) {
$this->config->p24_acceptinshop = $this->from_selected_bool( $p24_acceptinshop );
return $this;
}
/**
* Return p24_acceptinshop from config.
*
* The value is converted to selected representation.
*
* @return bool|string
* @throws LogicException If the internal representation of value is broken.
*/
public function get_p24_acceptinshop() {
try {
$p24_acceptinshop = $this->config->p24_acceptinshop;
return $this->to_selected_bool( $p24_acceptinshop );
} catch ( InvalidArgumentException $ex ) {
$msg = 'The internal representation of p24_acceptinshop is invalid.';
throw new LogicException( $msg, 0, $ex );
}
}
/**
* Set p24_payinshop in config.
*
* The input is expected to be in selected representation.
*
* @param bool|string $p24_payinshop The new p24_payinshop.
* @return P24_Config_Accessor
* @throws InvalidArgumentException If input is in wrong representation.
*/
public function set_p24_payinshop( $p24_payinshop ) {
$this->config->p24_payinshop = $this->from_selected_bool( $p24_payinshop );
return $this;
}
/**
* Return p24_show_methods_checkout from config.
*
* The value is converted to selected representation.
*
* @return bool|string
* @throws LogicException If the internal representation of value is broken.
*/
public function get_p24_show_methods_checkout() {
try {
$p24_show_methods_checkout = $this->config->p24_show_methods_checkout;
return $this->to_selected_bool( $p24_show_methods_checkout );
} catch ( InvalidArgumentException $ex ) {
$msg = 'The internal representation of p24_show_methods_checkout is invalid.';
throw new LogicException( $msg, 0, $ex );
}
}
/**
* Set p24_show_methods_checkout in config.
*
* The input is expected to be in selected representation.
*
* @param bool|string $p24_show_methods_checkout The new p24_show_methods_checkout.
* @return P24_Config_Accessor
* @throws InvalidArgumentException If input is in wrong representation.
*/
public function set_p24_show_methods_checkout( $p24_show_methods_checkout ) {
$this->config->p24_show_methods_checkout = $this->from_selected_bool( $p24_show_methods_checkout );
return $this;
}
/**
* Return p24_show_methods_confirmation from config.
*
* The value is converted to selected representation.
*
* @return bool|string
* @throws LogicException If the internal representation of value is broken.
*/
public function get_p24_show_methods_confirmation() {
try {
$p24_show_methods_confirmation = $this->config->p24_show_methods_confirmation;
return $this->to_selected_bool( $p24_show_methods_confirmation );
} catch ( InvalidArgumentException $ex ) {
$msg = 'The internal representation of p24_show_methods_confirmation is invalid.';
throw new LogicException( $msg, 0, $ex );
}
}
/**
* Set p24_show_methods_confirmation in config.
*
* The input is expected to be in selected representation.
*
* @param bool|string $p24_show_methods_confirmation The new p24_show_methods_confirmation.
* @return P24_Config_Accessor
* @throws InvalidArgumentException If input is in wrong representation.
*/
public function set_p24_show_methods_confirmation( $p24_show_methods_confirmation ) {
$this->config->p24_show_methods_confirmation = $this->from_selected_bool( $p24_show_methods_confirmation );
return $this;
}
/**
* Return p24_graphics from config.
*
* The value is converted to selected representation.
*
* @return bool|string
* @throws LogicException If the internal representation of value is broken.
*/
public function get_p24_graphics() {
try {
$p24_graphics = $this->config->p24_graphics;
return $this->to_selected_bool( $p24_graphics );
} catch ( InvalidArgumentException $ex ) {
$msg = 'The internal representation of p24_graphics is invalid.';
throw new LogicException( $msg, 0, $ex );
}
}
/**
* Set p24_graphics in config.
*
* The input is expected to be in selected representation.
*
* @param bool|string $p24_graphics The new p24_graphics.
* @return P24_Config_Accessor
* @throws InvalidArgumentException If input is in wrong representation.
*/
public function set_p24_graphics( $p24_graphics ) {
$this->config->p24_graphics = $this->from_selected_bool( $p24_graphics );
return $this;
}
/**
* Get p24_paymethods_first from config.
*
* @return string
*/
public function get_p24_paymethods_first() {
return (string) $this->config->p24_paymethods_first;
}
/**
* Set p24_paymethods_first in config.
*
* @param string $p24_paymethods_first The new p24_paymethods_first.
* @return P24_Config_Accessor
*/
public function set_p24_paymethods_first( $p24_paymethods_first ) {
$this->config->p24_paymethods_first = (string) $p24_paymethods_first;
return $this;
}
/**
* Get p24_paymethods_second from config.
*
* @return string
*/
public function get_p24_paymethods_second() {
return (string) $this->config->p24_paymethods_second;
}
/**
* Set p24_paymethods_second in config.
*
* @param string $p24_paymethods_second The new p24_paymethods_second.
* @return P24_Config_Accessor
*/
public function set_p24_paymethods_second( $p24_paymethods_second ) {
$this->config->p24_paymethods_second = (string) $p24_paymethods_second;
return $this;
}
/**
* Return p24_wait_for_result from config.
*
* The value is converted to selected representation.
*
* @return bool|string
* @throws LogicException If the internal representation of value is broken.
*/
public function get_p24_wait_for_result() {
try {
$p24_wait_for_result = $this->config->p24_wait_for_result;
return $this->to_selected_bool( $p24_wait_for_result );
} catch ( InvalidArgumentException $ex ) {
$msg = 'The internal representation of p24_wait_for_result is invalid.';
throw new LogicException( $msg, 0, $ex );
}
}
/**
* Set p24_wait_for_result in config.
*
* The input is expected to be in selected representation.
*
* @param bool|string $p24_wait_for_result The new p24_wait_for_result.
* @return P24_Config_Accessor
* @throws InvalidArgumentException If input is in wrong representation.
*/
public function set_p24_wait_for_result( $p24_wait_for_result ) {
$this->config->p24_wait_for_result = $this->from_selected_bool( $p24_wait_for_result );
return $this;
}
/**
* Return p24_use_special_status from config.
*
* The value is converted to selected representation.
*
* @return bool|string
* @throws LogicException If the internal representation of value is broken.
*/
public function get_p24_use_special_status() {
try {
$p24_use_special_status = $this->config->p24_use_special_status;
return $this->to_selected_bool( $p24_use_special_status );
} catch ( InvalidArgumentException $ex ) {
$msg = 'The internal representation of p24_use_special_status is invalid.';
throw new LogicException( $msg, 0, $ex );
}
}
/**
* Set p24_use_special_status in config.
*
* The input is expected to be in selected representation.
*
* @param bool|string $p24_use_special_status The new p24_use_special_status.
* @return P24_Config_Accessor
* @throws InvalidArgumentException If input is in wrong representation.
*/
public function set_p24_use_special_status( $p24_use_special_status ) {
$this->config->p24_use_special_status = $this->from_selected_bool( $p24_use_special_status );
return $this;
}
/**
* Get p24_custom_pending_status from config.
*
* @return string
*/
public function get_p24_custom_pending_status() {
return (string) $this->config->p24_custom_pending_status;
}
/**
* Get p24_custom_pending_status from config.
*
* @return string
*/
public function get_p24_custom_processing_status() {
return (string) $this->config->p24_custom_processing_status;
}
/**
* Return sub_enabled from config.
*
* The value is converted to selected representation.
*
* @return bool|string
* @throws LogicException If the internal representation of value is broken.
*/
public function get_sub_enabled() {
try {
$sub_enabled = $this->config->sub_enabled;
return $this->to_selected_bool( $sub_enabled );
} catch ( InvalidArgumentException $ex ) {
$msg = 'The internal representation of sub_enabled is invalid.';
throw new LogicException( $msg, 0, $ex );
}
}
/**
* Set sub_enabled in config.
*
* The input is expected to be in selected representation.
*
* @param bool|string $sub_enabled The new sub_enabled.
* @return P24_Config_Accessor
* @throws InvalidArgumentException If input is in wrong representation.
*/
public function set_sub_enabled( $sub_enabled ) {
$this->config->sub_enabled = $this->from_selected_bool( $sub_enabled );
return $this;
}
/**
* Get p24_custom_promote_p24 from config
*
* @return bool|string
*/
public function get_is_pay_now_promoted() {
$is_pay_now_promoted = $this->config->p24_custom_promote_p24;
return $this->to_selected_bool( $is_pay_now_promoted );
}
/**
* Get p24_add_to_alternative_button from config
*
* @return bool|string
*/
public function get_is_pay_now_alternative_button() {
$is_pay_now_alt_button = $this->config->p24_add_to_alternative_button;
return $this->to_selected_bool( $is_pay_now_alt_button );
}
}

View File

@@ -0,0 +1,134 @@
<?php
/**
* File that define P24_Config_Eraser class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class to erase Przelewy24 configuration.
*/
class P24_Config_Eraser {
const SLUG_CLEAR_CONFIG = 'p24_clear_config';
/**
* Instance of core of plugin.
*
* @var P24_Core
*/
private $plugin_core;
/**
* Construct class instance.
*
* @param P24_Core $plugin_core The core class for plugin.
*/
public function __construct( P24_Core $plugin_core ) {
$this->plugin_core = $plugin_core;
}
/**
* Get kay of option record from database.
*
* It is different for each currency.
*
* @param string $for_currency Code of currency.
*
* @return string
*/
public static function get_key_for_config_for_currency( $for_currency ) {
$code = strtolower( $for_currency );
return 'woocommerce_' . WC_Gateway_Przelewy24::PAYMENT_METHOD . '_' . $code . '_settings';
}
/**
* Execute clear payment config.
*/
private function execute_clear_payment_config() {
$currencies = $this->plugin_core->get_available_currencies_or_default();
foreach ( $currencies as $currency ) {
$key = self::get_key_for_config_for_currency( $currency );
delete_option( $key );
}
delete_option( P24_Settings_Helper::OPTION_KEY_COMMON );
delete_option( 'p24_statuses_active' );
delete_option( P24_Status_Provider::ADDITIONAL_STATUSES_KEY );
delete_option( 'przelewy24_multi_currency_formats' );
delete_option( 'przelewy24_multi_currency_multipliers' );
delete_option( P24_Install::P24_INSTALLED_VERSION );
delete_option( 'przelewy24_subscriptions_days' );
delete_option( 'przelewy24_subscriptions_active' );
delete_option( 'p24_subscription_page_id' );
}
/**
* Render page to clear config.
*/
public function render_clear_config() {
$params = array(
'field_name' => strtr( self::SLUG_CLEAR_CONFIG, '-', '_' ),
'deleted' => false,
);
if ( isset( $_POST['p24_nonce'] ) ) {
$nonce = sanitize_key( $_POST['p24_nonce'] );
if ( wp_verify_nonce( $nonce, 'p24_action' ) ) {
if ( isset( $_POST[ $params['field_name'] ] ) ) {
$this->execute_clear_payment_config();
$params['deleted'] = true;
}
}
}
$this->plugin_core->render_template( 'confirm-clear-config', $params );
}
/**
* Prepare additional config pages.
*/
public function prepare_pages() {
add_submenu_page(
'wc-settings',
__( 'Wyczyść ustawienia' ),
__( 'Wyczyść ustawienia' ),
'delete_plugins',
self::SLUG_CLEAR_CONFIG,
array( $this, 'render_clear_config' )
);
}
/**
* Add link for plugins page
*
* @param array $actions Default actions.
* @param string $plugin_file Main filename of plugin.
* @param array $plugin_data Plugin data.
* @param string $context Context.
* @return array
*/
public function add_plugin_action_link( $actions, $plugin_file, $plugin_data, $context ) {
if ( 'przelewy24/woocommerce-gateway-przelewy24.php' !== $plugin_file ) {
return $actions;
} elseif ( current_user_can( 'delete_plugins' ) ) {
$url = menu_page_url( self::SLUG_CLEAR_CONFIG, false );
$actions['clear'] = '<a href="' . $url . '">' . __( 'Wyczyść ustawienia' ) . '</a>';
return $actions;
} else {
return $actions;
}
}
/**
* Bind events.
*/
public function bind_events() {
add_filter( 'plugin_action_links', array( $this, 'add_plugin_action_link' ), 10, 4 );
add_action( 'admin_menu', array( $this, 'prepare_pages' ) );
}
}

View File

@@ -0,0 +1,179 @@
<?php
/**
* File that define P24_Config_Holder class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Simple class that hold config.
*
* The active currency and style of booleans are unknown to this class.
* The accessor is external.
*/
class P24_Config_Holder {
/**
* Title
*
* @var string
*/
public $title;
/**
* Identification of merchant.
*
* @var string
*/
public $merchant_id;
/**
* Identification of store.
*
* It may be the same as $merchant_id.
*
* @var string
*/
public $shop_id;
/**
* Salt or CRC key.
*
* @var string
*/
public $salt;
/**
* Mode of operation.
*
* @var string
*/
public $p24_operation_mode;
/**
* Longer description.
*
* @var string
*/
public $description;
/**
* Key to API.
*
* @var string
*/
public $p24_api;
/**
* Methods to put on peyment selection page.
*
* @var string
*/
public $p24_paymethods_super_first;
/**
* Activate the Onclick.
*
* @var bool
*/
public $p24_oneclick;
/**
* Option to pay in shop via card.
*
* @var bool
*/
public $p24_payinshop;
/**
* Option to accept p24 terms in shop.
*
* @var bool
*/
public $p24_acceptinshop;
/**
* Select payment methods in shop on checkout page.
*
* @var bool
*/
public $p24_show_methods_checkout;
/**
* Select payment methods in shop on confirmation page.
*
* @var bool
*/
public $p24_show_methods_confirmation;
/**
* User graphic list of pay options.
*
* @var bool
*/
public $p24_graphics;
/**
* Comma separated list of promoted pay options.
*
* @var string
*/
public $p24_paymethods_first;
/**
* Comma separated list of additional methods.
*
* @var string
*/
public $p24_paymethods_second;
/**
* Wait for transaction result.
*
* @var bool
*/
public $p24_wait_for_result;
/**
* Use special statuses for orders.
*
* @var bool
*/
public $p24_use_special_status;
/**
* Special pending status.
*
* @var string
*/
public $p24_custom_pending_status;
/**
* Special processing status.
*
* @var string
*/
public $p24_custom_processing_status;
/**
* Enable selected currency.
*
* @var bool
*/
public $sub_enabled;
/**
* Enable P24NOW promoted.
*
* @var bool
*/
public $p24_custom_promote_p24;
/**
* Enable p24 alternative button.
*
* @var bool
*/
public $p24_add_to_alternative_button;
}

View File

@@ -0,0 +1,373 @@
<?php
/**
* File that define P24_Config class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Methods for Przelewy 24 plugin to display admin config.
*
* Processing of config is in different class.
*/
class P24_Config_Menu {
/**
* Instance of core of plugin.
*
* @var P24_Core
*/
private $plugin_core;
/**
* Construct class instance.
*
* @param P24_Core $plugin_core The core class for plugin.
*/
public function __construct( P24_Core $plugin_core ) {
$this->plugin_core = $plugin_core;
}
/**
* Render multi currency config page.
*/
public function render_mc_config_page() {
$tab = empty( $_GET['tab'] ) ? 'main' : sanitize_key( wp_unslash( $_GET['tab'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
$multicurrency = $this->plugin_core->is_internal_multi_currency_active();
switch ( $tab ) {
case 'main':
$this->render_config_tabs( $tab, $multicurrency );
$this->render_config_mc_main_page();
break;
case 'multipliers':
$this->render_config_tabs( $tab, $multicurrency );
$this->render_config_multipliers_page();
break;
case 'formats':
$this->render_config_tabs( $tab, $multicurrency );
$this->render_config_format_page();
break;
}
}
/**
* Render tabs of config page.
*
* @param string $tab The active tab.
* @param bool $multicurrency If multi currency is active.
*/
private function render_config_tabs( $tab, $multicurrency ) {
$params = compact( 'tab', 'multicurrency' );
$this->plugin_core->render_template( 'multi-currency-tabs', $params );
}
/**
* Render form to activate multi currency module.
*
* @throws LogicException Not expected.
*/
private function render_config_mc_main_page() {
$multi_currency_instance = $this->plugin_core->get_any_active_mc();
if ( $multi_currency_instance->is_internal() ) {
if ( ! $multi_currency_instance instanceof P24_Multi_Currency ) {
$class = get_class( $multi_currency_instance );
throw new LogicException( "The implementation of $class has broken is_internal method or the logic of application has changed." );
}
$this->render_config_main_page_extended( $multi_currency_instance );
return;
}
$value = $this->plugin_core->should_activate_multi_currency();
$order_created_notification_value = $this->plugin_core->should_activate_order_created_notification();
$params = compact( 'multi_currency_instance', 'value', 'order_created_notification_value' );
$this->plugin_core->render_template( 'multi-currency-main', $params );
}
/**
* Render config main page extended by reports currency field.
*
* @param P24_Multi_Currency $multi_currency_instance Multi currency instance.
*/
private function render_config_main_page_extended( P24_Multi_Currency $multi_currency_instance ) {
$value = $this->plugin_core->should_activate_multi_currency();
$currency_options = $multi_currency_instance->get_available_currencies();
$report_currency = P24_Multi_Currency::get_admin_reports_currency( get_woocommerce_currency() );
wp_verify_nonce( null ); /* There is no nonce in request. */
if ( isset( $_POST['p24_reports_currency'] ) ) {
$report_currency = sanitize_text_field( wp_unslash( $_POST['p24_reports_currency'] ) );
}
$order_created_notification_value = $this->plugin_core->should_activate_order_created_notification();
$params = compact( 'multi_currency_instance', 'value', 'currency_options', 'report_currency', 'order_created_notification_value' );
$this->plugin_core->render_template( 'multi-currency-main', $params );
}
/**
* Render form to set currency multipliers.
*/
private function render_config_multipliers_page() {
$available = get_woocommerce_currencies();
$multipliers = $this->plugin_core->get_multi_currency_instance()->get_multipliers();
$base_currency = P24_Woo_Commerce_Low_Level_Getter::get_unhooked_currency_form_woocommerce();
$multipliers[ $base_currency ] = 1;
$params = compact( 'multipliers', 'base_currency', 'available' );
$this->plugin_core->render_template( 'multi-currency-multipliers', $params );
}
/**
* Render form to change format of currency.
*/
private function render_config_format_page() {
$formats = get_option( 'przelewy24_multi_currency_formats', array() );
$active_currency = $this->plugin_core->get_multi_currency_instance()->get_active_currency();
if ( array_key_exists( $active_currency, $formats ) ) {
$format = $formats[ $active_currency ];
} else {
$base_currency = P24_Woo_Commerce_Low_Level_Getter::get_unhooked_currency_form_woocommerce();
if ( array_key_exists( $base_currency, $formats ) ) {
$format = $formats[ $base_currency ];
} else {
$format = array(
'currency_pos' => get_option( 'woocommerce_currency_pos' ),
'thousand_separator' => wc_get_price_thousand_separator(),
'decimal_separator' => wc_get_price_decimal_separator(),
'decimals' => wc_get_price_decimals(),
);
}
}
$currency_options = get_przelewy24_multi_currency_options();
$params = compact( 'format', 'active_currency', 'currency_options' );
$this->plugin_core->render_template( 'multi-currency-formats', $params );
}
/**
* Render status page.
*/
public function render_order_status_page() {
$tab = empty( $_GET['tab'] ) ? 'main' : sanitize_key( wp_unslash( $_GET['tab'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
switch ( $tab ) {
case 'main':
$this->render_order_status_tabs( $tab );
$this->render_order_status_activation_page();
break;
case 'list':
$this->render_order_status_tabs( $tab );
$this->render_order_status_config_page();
break;
}
}
/**
* Render tabs for statuses.
*
* @param string $tab The active tab.
*/
private function render_order_status_tabs( $tab ) {
$is_active = P24_Status_Decorator::is_active();
$params = compact( 'tab', 'is_active' );
$this->plugin_core->render_template( 'statuses-tabs', $params );
}
/**
* Render order status page.
*/
public function render_order_status_activation_page() {
$is_active = P24_Status_Decorator::is_active();
$params = compact( 'is_active' );
$this->plugin_core->render_template( 'status-config', $params );
}
/**
* Render order status config page.
*/
public function render_order_status_config_page() {
$status_provider = $this->plugin_core->get_status_provider_instance();
$statuses = P24_Status_Provider::get_formatted_config();
$error = $status_provider->get_adding_error();
$new_code = $status_provider->get_proposed_code_if_error();
$new_label = $status_provider->get_proposed_label_if_error();
$params = compact( 'statuses', 'error', 'new_code', 'new_label' );
$this->plugin_core->render_template( 'statuses', $params );
}
/**
* Render subscription page.
*/
public function render_subscription_page() {
$tab = empty( $_GET['tab'] ) ? 'main' : sanitize_key( wp_unslash( $_GET['tab'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
switch ( $tab ) {
case 'main':
$this->render_subscription_tabs( $tab );
$this->render_subscription_config_page();
break;
case 'list':
$this->render_subscription_tabs( $tab );
$this->render_subscription_list();
break;
case 'inactive':
$this->render_subscription_tabs( $tab );
$this->render_inactive_subscription_list();
break;
}
}
/**
* Render tabs for subscription.
*
* @param string $tab The active tab.
*/
private function render_subscription_tabs( $tab ) {
$is_active = P24_Subscription_Config::is_active();
$params = compact( 'tab', 'is_active' );
$this->plugin_core->render_template( 'subscriptions-tabs', $params );
}
/**
* Render subscription config page.
*/
public function render_subscription_config_page() {
$params = array(
'is_active' => P24_Subscription_Config::is_active(),
'days_to_renew' => P24_Subscription_Config::days_to_renew(),
'page_id' => P24_Subscription_Config::page_id(),
);
$this->plugin_core->render_template( 'subscriptions-config', $params );
}
/**
* Render subscription list.
*/
public function render_subscription_list() {
P24_Subscription_Admin::parse_cancellation_request();
$params = array(
'list' => P24_Subscription_Db::get_active_list(),
);
$this->plugin_core->render_template( 'subscriptions-list', $params );
}
/**
* Render inactive subscription list.
*/
public function render_inactive_subscription_list() {
$params = array(
'inactive_list' => P24_Subscription_Db::get_inactive_list(),
);
$this->plugin_core->render_template( 'subscriptions-list-inactive', $params );
}
/**
* Prepare common config menus.
*/
public function prepare_config_menu() {
add_submenu_page(
'woocommerce',
'P24 Multi Currency',
'P24 Multi Currency',
'manage_options',
'p24-multi-currency',
array( $this, 'render_mc_config_page' )
);
if ( $this->plugin_core->check_need_for_extra_statuses() ) {
add_submenu_page(
'woocommerce',
'P24 Order Status',
'P24 Order Status',
'manage_options',
'p24-order-status',
array( $this, 'render_order_status_page' )
);
}
add_submenu_page(
'woocommerce',
'P24 Subscriptions',
'P24 Subscriptions',
'manage_options',
'p24-subscription',
array( $this, 'render_subscription_page' )
);
}
/**
* Add scripts used on admin page.
*/
public function add_admin_scripts() {
wp_enqueue_style( 'p24_multi_currency_admin', PRZELEWY24_URI . 'assets/css/p24_multi_currency_style_admin.css', array(), P24_Core::SCRIPTS_VERSION );
}
/**
* Update WooCommerce settings panels.
*
* The MultiCurrency make few changes.
* Few config items have to be renamed or overwritten.
* The required config is added by different functions.
*
* @param array $input The WooCommerce settings.
* @return array
*/
public function clear_woocommerce_settings( $input ) {
$ret = array();
foreach ( $input as $k => $v ) {
switch ( $v['id'] ) {
case P24_Woo_Commerce_Internals::CURRENCY:
/* Change label. */
$v['title'] = __( 'Waluta podstawowa', 'przelewy24' );
$v['desc'] = null;
$ret[ $k ] = $v;
break;
case P24_Woo_Commerce_Internals::CURRENCY_POS:
case P24_Woo_Commerce_Internals::PRICE_THOUSAND_SEP:
case P24_Woo_Commerce_Internals::PRICE_DECIMAL_SEP:
case P24_Woo_Commerce_Internals::PRICE_NUM_DECIMALS:
/* These options are overwritten by multi currency. */
break;
default:
$ret[ $k ] = $v;
}
}
return $ret;
}
/**
* Add box to set currency for order.
*
* This box is used on admin panel.
*
* @param WP_Post $post The post object.
*/
public function add_admin_order_change_currency( WP_Post $post ) {
$currency_options = $this->plugin_core->get_multi_currency_instance()->get_available_currencies();
$params = compact( 'post', 'currency_options' );
$this->plugin_core->render_template( 'multi-currency-order-edit', $params );
}
/**
* Add all meta boxes for different pages.
*/
public function add_meta_boxes() {
foreach ( wc_get_order_types( 'order-meta-boxes' ) as $type ) {
add_meta_box( 'p24_admin_order_multi_currency', __( 'Aktywna waluta', 'przelewy24' ), array( $this, 'add_admin_order_change_currency' ), $type, 'side', 'high' );
}
}
/**
* Bind common events.
*/
public function bind_common_events() {
add_action( 'admin_enqueue_scripts', array( $this, 'add_admin_scripts' ) );
add_action( 'admin_menu', array( $this, 'prepare_config_menu' ) );
}
/**
* Bind multi currency events.
*/
public function bind_multi_currency_events() {
add_filter( 'woocommerce_general_settings', array( $this, 'clear_woocommerce_settings' ) );
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
}
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* File that define P24_Context_Provider class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class with methods allowing user to determine context this script was run from.
*/
class P24_Context_Provider {
/**
* Is this reports context.
*
* @return bool
*/
public function is_reports_context() {
return $this->is_dashboard_context() || $this->is_analytics_context();
}
/**
* Is wc analytics context.
*
* @return bool
*/
public function is_analytics_context() {
if ( isset( $_GET['rest_route'] )
&& 0 === strpos( sanitize_text_field( wp_unslash( $_GET['rest_route'] ) ), '/wc-analytics/' ) ) {
return true;
}
return $this->is_admin_context()
&& isset( $_GET['path'] )
&& 0 === strpos( sanitize_text_field( wp_unslash( $_GET['path'] ) ), '/analytics/' );
}
/**
* Is this script launched from wc dashboard context.
*
* @return bool
*/
public function is_dashboard_context() {
return $this->is_admin_context() && ! isset( $_GET['path'] );
}
/**
* Is this script launched from wc admin context.
*
* @return bool
*/
public function is_admin_context() {
return isset( $_GET['page'] ) && 'wc-admin' === sanitize_text_field( wp_unslash( $_GET['page'] ) );
}
}

View File

@@ -0,0 +1,603 @@
<?php
/**
* File that define P24_Core class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Core methods for Przelewy 24 plugin.
*/
class P24_Core {
/**
* String to add to loaded scripts.
*
* @var string
*/
const SCRIPTS_VERSION = '1.6.0';
/**
* The internal version to use.
*
* Due to technical reasons, there may be few other places with the same purpose.
* This one should take precedence.
*
* @var string
*/
const INTERNAL_VERSION = '1.0.6';
/**
* Key used to mark when Przelewy24 has been used to pay for order.
*
* @var string
*/
const CHOSEN_TIMESTAMP_META_KEY = '_p24_chosen_timestamp';
/**
* Key to store Przelewy24 payment method id.
*/
const P24_METHOD_META_KEY = 'p24_method';
/**
* Key used to store session id, which may be used later i.e. for refunds
*/
const ORDER_SESSION_ID_KEY = '_p24_order_session_id';
/**
* Key used to store Przelewy24 internal order id.
*/
const ORDER_P24_ID = '_p24_order_id';
/**
* The null or P24_Multi_Currency instance.
*
* @var null|P24_Multi_Currency
*/
private $multi_currency = null;
/**
* The P24_Request_Support instance.
*
* @var P24_Request_Support
*/
private $request_support;
/**
* The P24_Config_Menu instance.
*
* @var P24_Config_Menu;
*/
private $config_menu;
/**
* The instance of class configuring WP menu.
*
* @var P24_Multi_Currency_Menu
*/
private $wp_menu_support;
/**
* The WC_Gateway_Przelewy24 instance.
*
* @var WC_Gateway_Przelewy24
*/
private $gateway;
/**
* Context provider.
*
* @var P24_Context_Provider
*/
private $context_provider;
/**
* HTML for SOAP BLIK.
*
* Most logic is in the constructor.
*
* @var P24_Blik_Html
*/
private $soap_blik_html;
/**
* Status provider.
*
* @var P24_Status_Provider
*/
private $status_provider;
/**
* Status_decorator.
*
* @var P24_Status_Decorator
*/
private $status_decorator;
/**
* Support for extra gateway.
*
* @var P24_Extra_Gateway_Support
*/
private $eg_support;
/**
* External_multicurrency.
*
* @var P24_MC_Pool
*/
private $mc_pool;
/**
* Subscription class.
*
* @var P24_Subscription
*/
private $subscription;
/**
* Icon generator.
*
* @var P24_Icon_Svg_Generator
*/
private $icon_generator;
/**
* Configuration helper
*
* @var P24_Config_Eraser
*/
private $config_eraser;
/**
* Construct class instance.
*/
public function __construct() {
$this->request_support = new P24_Request_Support();
$this->context_provider = new P24_Context_Provider();
$this->wp_menu_support = new P24_Multi_Currency_Menu( $this );
$config_factory = array( &$this->gateway, 'load_settings_from_db_formatted' );
$this->status_provider = new P24_Status_Provider();
$this->status_decorator = new P24_Status_Decorator( $config_factory, $this->status_provider, $this );
$this->eg_support = new P24_Extra_Gateway_Support( $this );
$this->mc_pool = new P24_MC_Pool( $this );
$this->subscription = new P24_Subscription( $this );
$this->config_eraser = new P24_Config_Eraser( $this );
if ( ! $this->is_in_user_mode() ) {
$this->config_menu = new P24_Config_Menu( $this );
}
}
/**
* Check if page is in user mode.
*
* @return bool
*/
public function is_in_user_mode() {
if ( is_admin() ) {
return false;
} elseif ( defined( 'DOING_CRON' ) && DOING_CRON ) {
return false;
} elseif ( $this->is_in_json_mode() ) {
return false;
} else {
return true;
}
}
/**
* Check if application is in JSON mode.
*
* @return bool
*/
public function is_in_json_mode() {
$request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI' );
return (bool) preg_match( '/^\\/wp\\-json\\//', $request_uri );
}
/**
* Check if internal multi currency is activated.
*
* @return bool
*/
public function is_internal_multi_currency_active() {
return (bool) $this->multi_currency;
}
/**
* Get any active multi currency instance or proxy.
*
* @return P24_MC_Interface
*/
public function get_any_active_mc() {
return $this->mc_pool->get_preffered_mc();
}
/**
* Get_external_active_mc.
*
* @return null|P24_MC_Interface
*/
public function get_external_active_mc() {
return $this->mc_pool->get_external_mc();
}
/**
* Return multi currency instance.
*
* Should be called only if multi currency i active.
*
* @return P24_Multi_Currency
* @throws LogicException If there is no instance.
*/
public function get_multi_currency_instance() {
if ( $this->is_internal_multi_currency_active() ) {
return $this->multi_currency;
} else {
throw new LogicException( 'Multi currency is not active. It should be tested.' );
}
}
/**
* Get status provider instance.
*
* @return P24_Status_Provider
*/
public function get_status_provider_instance() {
return $this->status_provider;
}
/**
* Get status decorator instance.
*
* @return P24_Status_Decorator
*/
public function get_status_decorator_instance() {
return $this->status_decorator;
}
/**
* Try override active currency.
*
* The communication with Przelewy24 is quite late.
*
* @param P24_Communication_Parser $parser The P24_Communication_Parser instance.
*/
public function try_override_active_currency( P24_Communication_Parser $parser ) {
if ( $this->is_internal_multi_currency_active() ) {
$this->multi_currency->try_override_active_currency( $parser );
}
}
/**
* Return current instance i parameter is null.
*
* This should be useful in filters.
*
* @param mixed $default Default value from filter.
* @return P24_Core
*/
public function get_this_if_null( $default ) {
return $default ? $default : $this;
}
/**
* Render template and output.
*
* @param string $template The name of template.
* @param array $params The array of parameters.
* @throws LogicException If the file is not found.
*/
public function render_template( $template, $params = array() ) {
$dir = __DIR__ . '/../templates/';
$file = $template . '.php';
wc_get_template( $file, $params, $dir, $dir );
}
/**
* Check if multi currency should be activated.
*
* @return bool
*/
public function should_activate_multi_currency() {
$common = get_option( P24_Request_Support::OPTION_KEY_COMMON, array() );
return array_key_exists( 'p24_multi_currency', $common ) && 'yes' === $common['p24_multi_currency'];
}
/**
* Check if order created notification should be activated.
*
* @return bool
*/
public function should_activate_order_created_notification() {
$common = get_option( P24_Request_Support::OPTION_KEY_COMMON, array() );
return array_key_exists( 'p24_notification_order_created', $common ) && 'yes' === $common['p24_notification_order_created'];
}
/**
* Register gateway.
*
* The constructor of gateway has to be called in external plugin.
* This function may be called before the main gateway is in a usable state.
*
* @param WC_Gateway_Przelewy24 $gateway The gateway instance.
*/
public function register_gateway( WC_Gateway_Przelewy24 $gateway ) {
$this->gateway = $gateway;
}
/**
* Code to execute after main gateway initiation.
*
* This function should be called on the main gateway becoming usable.
*
* @throws LogicException Throws if executed too early.
*/
public function after_main_gateway_initiation() {
if ( ! isset( $this->gateway ) ) {
throw new LogicException( 'This function has to be called after register_gateway.' );
}
$this->eg_support->prep_extra_gateways( $this->gateway );
$this->soap_blik_html = new P24_Blik_Html( $this );
}
/**
* Get config for currency.
*
* @param null|string $currency The currency for requested config.
* @return P24_Config_Accessor
* @throws LogicException If there is no gateway created.
*/
public function get_config_for_currency( $currency = null ) {
if ( ! $this->gateway ) {
throw new LogicException( 'Gateway in not registered yet.' );
}
return $this->gateway->load_settings_from_db_formatted( $currency );
}
/**
* Get P24_Message_Validator instance.
*
* @return P24_Message_Validator
*/
public function get_message_validator() {
return new P24_Message_Validator();
}
/**
* Get P24_Communication_Parser instance.
*
* @return P24_Communication_Parser
*/
public function get_communication_parser() {
$message_validator = $this->get_message_validator();
return new P24_Communication_Parser( $message_validator );
}
/**
* Get default currency.
*
* @return string
*/
public function get_default_currency() {
if ( $this->is_internal_multi_currency_active() ) {
return $this->multi_currency->get_default_currency();
} else {
return get_woocommerce_currency();
}
}
/**
* Get all currencies including default.
*
* @return array
*/
public function get_available_currencies_or_default() {
$mc = $this->mc_pool->get_preffered_mc();
if ( $mc->is_multi_currency_active() ) {
$currencies = $mc->get_available_currencies();
} else {
$currencies = array( $this->get_default_currency() );
}
return $currencies;
}
/**
* Late configuration after Woocommerce init.
*/
public function after_woocommerce_init() {
$this->request_support->analyse();
$this->request_support->flush_options();
$this->status_provider->try_add_new( $this->request_support->get_order_status_changes() );
$this->status_decorator->bind_events();
$currency_changes = $this->request_support->get_currency_changes();
if ( $this->should_activate_multi_currency() ) {
/* The logic to set active currency is in P24_Multi_Currency class. */
$this->multi_currency = new P24_Multi_Currency( $this, $currency_changes );
$this->multi_currency->bind_events();
if ( is_admin() ) {
$this->config_menu->bind_multi_currency_events();
}
}
if ( $currency_changes ) {
$this->mc_pool->set_active_currency( $currency_changes );
}
}
/**
* Check if order is cancellable.
*
* @param bool $default Default value.
* @param WC_Order $order The order to check.
*
* @return mixed
*/
public function check_if_cancellable( $default, $order ) {
if ( $default ) {
return $default;
} elseif ( ! $order instanceof WC_Order ) {
return $default;
} elseif ( WC_Gateway_Przelewy24::PAYMENT_METHOD === $order->get_payment_method() ) {
$minutes = (int) get_option( P24_Woo_Commerce_Internals::HOLD_STOCK_MINUTES );
$timestamp = $order->get_meta( self::CHOSEN_TIMESTAMP_META_KEY );
if ( $minutes && $timestamp ) {
$now = time();
$seconds = $minutes * 60;
return ( $timestamp + $seconds ) < $now;
}
}
return $default;
}
/**
* Check need for extra statuses.
*
* @return bool
*/
public function check_need_for_extra_statuses() {
if ( $this->is_internal_multi_currency_active() ) {
$active = $this->multi_currency->get_available_currencies();
foreach ( $active as $one ) {
$config = P24_Settings_Helper::load_settings( $one );
if ( ! $config ) {
continue;
}
$config->access_mode_to_strict();
if ( $config->get_p24_use_special_status() ) {
return true;
}
}
} else {
$currency = $this->get_default_currency();
$config = P24_Settings_Helper::load_settings( $currency );
if ( ! $config ) {
return false;
}
$config->access_mode_to_strict();
return $config->get_p24_use_special_status();
}
return false;
}
/**
* Add scripts used on admin page.
*/
public function add_admin_scripts() {
wp_enqueue_style( 'p24_admin', PRZELEWY24_URI . 'assets/css/p24_style_admin.css', array(), self::SCRIPTS_VERSION );
}
/**
* Get cached icon generator.
*
* @return P24_Icon_Svg_Generator
*/
public function get_cached_icon_generator() {
if ( ! isset( $this->icon_generator ) ) {
$config = $this->gateway->load_settings_from_db_formatted();
$this->icon_generator = new P24_Icon_Svg_Generator( $config );
}
return $this->icon_generator;
}
/**
* Generate hidden icon url list.
*/
public function generate_hidden_icon_url_list() {
global $current_section;
if ( 'przelewy24' !== $current_section ) {
/* Nothing to add. */
return;
}
$icon_generator = $this->get_cached_icon_generator();
$icons = $icon_generator->get_all();
echo '<table id="p24-hidden-bank-icon-list" style="display: none;">';
foreach ( $icons as $id => $icon ) {
echo '<tr class="js-bank-id-', esc_attr( $id ), '">';
echo '<td class="js-icon-type-base">', esc_html( $icon['base'] ), '</td>';
echo '<td class="js-icon-type-mobile">', esc_html( $icon['mobile'] ), '</td>';
echo '</tr>';
}
echo '</table>';
}
/**
* Bind events.
*/
public function bind_core_events() {
add_filter( 'przelewy24_plugin_instance', array( $this, 'get_this_if_null' ) );
add_action( 'woocommerce_init', array( $this, 'after_woocommerce_init' ) );
add_filter( 'woocommerce_cancel_unpaid_order', array( $this, 'check_if_cancellable' ), 10, 2 );
add_action( 'admin_enqueue_scripts', array( $this, 'add_admin_scripts' ) );
add_filter( 'woocommerce_settings_checkout', array( $this, 'generate_hidden_icon_url_list' ) );
$this->wp_menu_support->bind_events();
$this->eg_support->bind_common_events();
$this->mc_pool->bind_events();
$this->subscription->bind_core_events();
$this->config_eraser->bind_events();
if ( is_admin() ) {
$this->config_menu->bind_common_events();
}
add_action( 'rest_api_init', function () {
register_rest_route( 'przelewy24/v1', '/create-payment', array(
'methods' => 'POST',
'callback' => array($this, 'przelewy24_request'),
'permission_callback' => '__return_true',
) );
} );
}
public function przelewy24_request($data) {
return $this->gateway->przelewy24_request($data);
}
/**
* Get context provider.
*/
public function get_context_provider() {
return $this->context_provider;
}
/**
* Get P24_Blik_Html.
*
* @return P24_Blik_Html
*/
public function get_soap_blik_html() {
return $this->soap_blik_html;
}
/**
* Converts money amount from stringified float (1.10) to cents in int.
*
* @param string $string Stringified float.
*
* @return int
*/
public static function convert_stringified_float_to_cents( $string ) {
list( $fulls, $cents ) = explode( '.', $string );
$sum = (int) $fulls * 100;
if ( $cents ) {
$sum += $cents;
}
return $sum;
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* Class for a widget
*/
class P24_Currency_Selector_Widget extends WP_Widget {
/**
* The P24_Core instance.
*
* @var P24_Core
*/
private $plugin_core;
/**
* The constructor.
*
* @param P24_Core $plugin_core The P24_Core instance.
*/
public function __construct( P24_Core $plugin_core ) {
$this->plugin_core = $plugin_core;
$id_base = 'p24_currency_selector';
$name = __( 'Widget wyboru waluty Przelewy24' );
parent::__construct( $id_base, $name );
}
/**
* Display the widget.
*
* @param array $args Display arguments, ignored.
* @param array $instance Settings.
*/
public function widget( $args, $instance ) {
if ( isset( $instance['title'] ) && $instance['title'] ) {
$title = $instance['title'];
} else {
$title = $this->name;
}
$params = [
'widget_title' => $title,
'active_currency' => get_woocommerce_currency(),
'currency_options' => get_przelewy24_multi_currency_options(),
];
$this->plugin_core->render_template( 'change-currency-widget', $params );
do_action( 'przelewy24_multi_currency_change_form_rendered' );
}
/**
* Handles updating settings.
*
* @param array $new_instance New settings for this instance.
* @param array $old_instance Old settings for this instance.
* @return array Updated settings to save.
*/
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = sanitize_text_field( $new_instance['title'] );
return $instance;
}
/**
* Outputs the settings form.
*
* @param array $instance Current settings.
*/
public function form( $instance ) {
$instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
$title = sanitize_text_field( $instance['title'] );
$title_field_id = $this->get_field_id( 'title' );
$title_field_name = $this->get_field_name( 'title' );
$params = [
'widget_title' => $title,
'title_field_id' => $title_field_id,
'title_field_name' => $title_field_name,
];
$this->plugin_core->render_template( 'config-change-currency-widget', $params );
}
}

View File

@@ -0,0 +1,199 @@
<?php
/**
* File that define P24_Extra_Gateway_Support.
*
* @package Przelewy24
*/
/**
* Class P24_Extra_Gateway_Support
*/
class P24_Extra_Gateway_Support {
/**
* Plugin core.
*
* @var P24_Core The plugin core.
*/
private $core;
/**
* The set of extra gateways.
*
* @var array
*/
private $extra_gateways;
/**
* P24_Extra_Gateway_Support constructor.
*
* @param P24_Core $core The plugin core.
*/
public function __construct( $core ) {
$this->core = $core;
}
/**
* Prepare extra gateways.
*
* @param WC_Gateway_Przelewy24 $main_gateway The main Przelewy24 gateway.
*/
public function prep_extra_gateways( WC_Gateway_Przelewy24 $main_gateway ) {
$currency = get_woocommerce_currency();
$config = $this->core->get_config_for_currency( $currency );
$config->access_mode_to_strict();
$this->extra_gateways = array();
$to_prep = array();
if ( $config->get_p24_show_methods_checkout() ) {
$imploded = $config->get_p24_paymethods_super_first();
$to_prep = explode( ',', $imploded );
if ( $to_prep ) {
$all_banks = $main_gateway->get_all_payment_methods();
$generator = new Przelewy24Generator( $main_gateway );
$icon_generator = $this->core->get_cached_icon_generator();
}
}
foreach ( $to_prep as $id ) {
$total = ( null !== WC()->cart ) ? (int) WC()->cart->total : 0;
if ( ! $total && null !== WC()->cart ) {
// hack for WooCommerce Active Payments pluin.
$total = WC()->cart->get_cart_contents_total() + WC()->cart->get_taxes_total() + WC()->cart->get_shipping_total();
}
if ( ! $this->is_p24_now_allowed( $total, $currency ) && 266 === (int) $id ) {
continue;
}
if ( ! $this->is_oneyraty_now_allowed( $total, $currency ) && 294 === (int) $id ) {
continue;
}
if ( ! $id ) {
continue;
} elseif ( ! isset( $all_banks[ $id ] ) ) {
continue;
}
$icon = $icon_generator->get_icon( $id, true );
if ( ! $icon ) {
/* Fallback. */
$icon = PRZELEWY24_URI . 'logo.png';
}
$this->extra_gateways[] = new P24_Extra_Gateway( $id, $all_banks[ $id ], $generator, $main_gateway, $icon );
}
}
/**
* Check if P24 Now is allowed
*
* @param numeric $amount Amount order.
* @param string $currency Active currency.
*
* @return bool
*/
private function is_p24_now_allowed( $amount, $currency ) {
return $amount > 0 && $amount < 10000 && 'PLN' === $currency;
}
/**
* Check if Oney raty is allowed
*
* @param numeric $amount Amount order.
* @param string $currency Active currency.
*
* @return bool
*/
private function is_oneyraty_now_allowed( $amount, $currency ) {
return $amount >= 150 && $amount <= 30000 && 'PLN' === $currency;
}
/**
* Inject additional gateways.
*
* Used for super first methods.
*
* @param array $gateways Prepared gateways.
* @return array
* @throws LogicException Throws if executed too early.
*/
public function inject_additional_gateways( $gateways ) {
if ( array_key_exists( WC_Gateway_Przelewy24::PAYMENT_METHOD, $gateways ) ) {
if ( ! isset( $this->extra_gateways ) ) {
throw new LogicException( 'The extra getways are not prepared yet.' );
}
foreach ( $this->extra_gateways as $extra ) {
$gateways[ $extra->id ] = $extra;
}
}
return $gateways;
}
/**
* Check gateway name.
*
* @param string $subject The gateway name.
* @return bool
*/
private function check_gateway_name( $subject ) {
$prefix = WC_Gateway_Przelewy24::PAYMENT_METHOD . '_extra_';
$prefix_quoted = preg_quote( $prefix, '/' );
$pattern = '/^' . $prefix_quoted . '\d+$/';
return (bool) preg_match( $pattern, $subject );
}
/**
* Do hack on hidden box.
*
* @param mixed $default We are not interested in changing this variable.
* @param WP_Screen $screen Data about active screen.
* @return mixed Return default value.
*/
public function do_hack_on_hidden_box( $default, WP_Screen $screen ) {
/* Fix refunds */
if ( 'woocommerce' === $screen->parent_base && 'shop_order' === $screen->post_type ) {
/* We have to try to overwrite this global variable. */
global $theorder;
if ( $theorder instanceof \Automattic\WooCommerce\Admin\Overrides\Order ) {
$old_method = $theorder->get_payment_method();
if ( $this->check_gateway_name( $old_method ) ) {
try {
$theorder->set_payment_method( WC_Gateway_Przelewy24::PAYMENT_METHOD );
} catch ( WC_Data_Exception $ex ) {
error_log( __METHOD__ . ' There is an error with unknown plugin.' ); // phpcs:ignore
error_log( __METHOD__ . $ex->getMessage() ); // phpcs:ignore
return $default;
}
}
}
}
/* We are not interested in altering default value. */
return $default;
}
/**
* Hack to fix refund.
*
* @param string $gateway_name The gateway name.
* @param WC_Order $order The order.
* @return string
*/
public function do_hack_to_fix_refund( $gateway_name, WC_Order $order ) {
if ( is_admin() ) {
if ( $this->check_gateway_name( $gateway_name ) ) {
if ( $order instanceof \Automattic\WooCommerce\Admin\Overrides\Order ) {
return WC_Gateway_Przelewy24::PAYMENT_METHOD;
}
}
}
return $gateway_name;
}
/**
* Bind common events.
*/
public function bind_common_events() {
add_filter( 'woocommerce_available_payment_gateways', array( $this, 'inject_additional_gateways' ), 256, 1 );
add_filter( 'default_hidden_meta_boxes', array( $this, 'do_hack_on_hidden_box' ), 5, 2 );
add_filter( 'woocommerce_order_get_payment_method', array( $this, 'do_hack_to_fix_refund' ), 10, 2 );
}
}

View File

@@ -0,0 +1,134 @@
<?php
/**
* File that define P24_Extra_Gateway class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The class for extra gateway.
*/
class P24_Extra_Gateway extends WC_Payment_Gateway {
/**
* Internal id.
*
* @var string
*/
private $internal_id;
/**
* The id of BLIK method on Przelewy24 page.
*/
const BLIK_METHOD = '181';
/**
* The name of form field on checkout page.
*/
const BLIK_CODE_INPUT_NAME = 'p24-blik-code';
/**
* The key the blik code is stored in the database.
*/
const BLIK_CODE_META_KEY = '_p24_blik_code';
/**
* Generator.
*
* @var Przelewy24Generator
*/
private $generator;
/**
* Main_gateway.
*
* @var WC_Gateway_Przelewy24
*/
private $main_gateway;
/**
* P24_Extra_Gateway constructor.
*
* @param string $id Id of payment method.
* @param string $title Title of payment method.
* @param Przelewy24Generator $generator Przelewy24 generator.
* @param WC_Gateway_Przelewy24 $main_gateway Main Prelewy24 payment gateway.
* @param string $icon Icon url.
*/
public function __construct( $id, $title, $generator, $main_gateway, $icon ) {
$this->internal_id = (string) $id;
$this->id = WC_Gateway_Przelewy24::PAYMENT_METHOD . '_extra_' . $id;
$this->generator = $generator;
$this->main_gateway = $main_gateway;
$this->icon = $icon;
$this->title = (string) $title;
add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'print_receipt' ) );
}
/**
* Get title.
*
* @return mixed
*/
public function get_title() {
return $this->title;
}
/**
* Aditional conntent on print receipt page.
*
* @param int $order_id If of order.
*/
public function print_receipt( $order_id ) {
$order_id = (int) $order_id;
$is_blik = self::BLIK_METHOD === $this->internal_id;
$order = new WC_Order( (int) $order_id );
if ( $is_blik ) {
$blik_code = $order->get_meta( self::BLIK_CODE_META_KEY );
} else {
$blik_code = false;
}
if ( $blik_code ) {
$legacy_auto_submit = false;
} else {
$legacy_auto_submit = true;
}
$ajax_url = add_query_arg( array( 'wc-api' => 'wc_gateway_przelewy24' ), home_url( '/' ) );
echo $this->generator->generate_przelewy24_form( $order, $legacy_auto_submit ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo "<div id='p24-additional-order-data' data-order-id='$order_id' data-ajax-url='$ajax_url'></div>\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
if ( $blik_code ) {
echo P24_Blik_Html::get_modal_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
/**
* Process the payment and return the result
*
* @param int $order_id Id of orer.
* @return array
*/
public function process_payment( $order_id ) {
$order = new WC_Order( $order_id );
/* This is the default place to reduce stock levels. It is safe to call function below multiple times. */
wc_maybe_reduce_stock_levels( $order );
wp_verify_nonce( null ); /* There is no nonce in request. */
if ( isset( $_POST[ self::BLIK_CODE_INPUT_NAME ] ) ) {
$blik_code = sanitize_text_field( wp_unslash( $_POST[ self::BLIK_CODE_INPUT_NAME ] ) );
$order->update_meta_data( P24_Core::CHOSEN_TIMESTAMP_META_KEY, time() );
$order->update_meta_data( P24_Core::P24_METHOD_META_KEY, $this->internal_id );
$order->update_meta_data( self::BLIK_CODE_META_KEY, $blik_code );
$order->save_meta_data();
}
do_action( 'wc_extra_gateway_przelewy24_process_payment', $order );
return array(
'result' => 'success',
'redirect' => $order->get_checkout_payment_url( $order ),
);
}
}

View File

@@ -0,0 +1,102 @@
<?php
/**
* File that define P24_Icon_Html_Generator class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The class for bank icons.
*/
class P24_Icon_Html_Generator {
/**
* Icon generator set.
*
* @var P24_Icon_Svg_Generator $svg_gnerator
*/
private $svg_gnerator;
/**
* P24_Icon_Html_Generator constructor.
*
* @param P24_Icon_Svg_Generator $svg_generator SVG generator.
*/
public function __construct( P24_Icon_Svg_Generator $svg_generator ) {
$this->svg_gnerator = $svg_generator;
}
/**
* Get bank icon html.
*
* @param int $bank_id Bank id.
* @param string $bank_name Bank name.
* @param string $text Bank description.
* @param string $cc_id CC id data.
* @param string $class Additional class.
* @param string $onclick On click JavaScript code.
* @param bool $with_input Generate additional form.
* @return string
*/
public function get_bank_html( $bank_id, $bank_name, $text = '', $cc_id = '', $class = '', $onclick = '', $with_input = false ) {
$bank_id = sanitize_text_field( $bank_id );
$bank_name = sanitize_text_field( $bank_name );
$text = sanitize_text_field( $text );
$cc_id = sanitize_text_field( $cc_id );
$class = sanitize_text_field( $class );
$onclick = sanitize_text_field( $onclick );
$with_input = sanitize_text_field( $with_input );
$css = $this->get_logo_css( $bank_id, true );
return '<a class="bank-box bank-item ' . $class . '" data-id="' . $bank_id . '" data-cc="' . $cc_id . '" onclick="' . $onclick . '">' .
( empty( $cc_id ) ? '' : '<span class="removecc" ' .
' title="' . __( 'Usuń zapamiętaną kartę', 'przelewy24' ) . ' ' . $bank_name . ' ' . $text . '" ' .
' onclick="arguments[0].stopPropagation(); if (confirm(\'' . __( 'Czy na pewno?', 'przelewy24' ) . '\')) removecc(' . $cc_id . ')"></span>' ) .
'<div class="bank-logo" style="' . $css . '">' .
( empty( $text ) ? '' : "<span>{$text}</span>" ) .
'</div><div class="bank-name">' . $bank_name . '</div>' . ( $with_input ? "<input style='display:none;' name='selected_banks[]' value='" . $bank_id . "' type='checkbox'/>" : '' ) . '</a>';
}
/**
* Get pay now html due to lack of proper template machine.
*
* @param int $bank_id The id of a bank.
* @param string $bank_name The name of a bank.
*
* @return string
*/
public function get_pay_now_html( $bank_id = 266, $bank_name = '' ) {
$css = $this->get_logo_css( $bank_id, true );
$logo = sprintf( '<div class="align-center bank-logo" style="%s"></div>', $css );
$text = sprintf( '<div class="bank-name ">%s</div>', $bank_name );
return sprintf(
'<a class="box-wrapper" data-id="%s"><div id="p24-now-box" class="%s">%s%s</div></a>',
$bank_id,
'payments-extra-promoted extra-promoted-box text-center',
$logo,
$text
);
}
/**
* Get logo CSS.
*
* @param int $bank_id The id of a bank.
* @param bool $mobile True if a mobile icon is requested.
* @return string
*/
private function get_logo_css( $bank_id, $mobile ) {
$bg_image = $this->svg_gnerator->get_icon( $bank_id, $mobile );
if ( $bg_image ) {
$css = "background-image: url('$bg_image')";
} else {
$css = '';
}
return $css;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* File that define P24_Icon_Svg_Generator class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The class for extra gateway.
*/
class P24_Icon_Svg_Generator {
/**
* Icon_set.
*
* @var array|null
*/
private $icon_set = null;
/**
* Config.
*
* @var P24_Config_Accessor
*/
private $config;
/**
* P24_Icon_Svg_Generator constructor.
*
* @param P24_Config_Accessor $config A valid config.
*/
public function __construct( P24_Config_Accessor $config ) {
$this->icon_set = null;
$this->config = clone $config;
$this->config->access_mode_to_strict();
}
/**
* Generate set.
*/
public function generate_set() {
$this->icon_set = array();
$rest_api = new P24_Rest_Common( $this->config );
$res = $rest_api->payment_methods( 'pl' );
if ( isset( $res['data'] ) ) {
foreach ( $res['data'] as $row ) {
$this->icon_set[ $row['id'] ] = array(
'base' => $row['imgUrl'],
'mobile' => $row['mobileImgUrl'],
);
}
}
ksort( $this->icon_set, SORT_NUMERIC );
}
/**
* Get icon.
*
* @param int $id Id of payment method.
* @param bool $mobile True for mobile version.
* @return string|null
*/
public function get_icon( $id, $mobile ) {
if ( ! isset( $this->icon_set ) ) {
$this->generate_set();
}
$id = (int) $id;
if ( array_key_exists( $id, $this->icon_set ) ) {
$type = $mobile ? 'mobile' : 'base';
return $this->icon_set[ $id ][ $type ];
} else {
return null;
}
}
/**
* Get_all.
*
* @return array
*/
public function get_all() {
if ( ! isset( $this->icon_set ) ) {
$this->generate_set();
}
return $this->icon_set;
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* File that define P24_Install class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
/**
* Install methods for Przelewy 24 plugin.
*/
class P24_Install {
const P24_INSTALLED_VERSION = 'p24_installed_version';
/**
* Update database.
*/
private static function update_database() {
global $wpdb;
dbDelta(
'
CREATE TABLE ' . $wpdb->prefix . 'woocommerce_p24_data (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
data_type VARCHAR(32) NOT NULL,
data_id INT NOT NULL,
custom_key VARCHAR(32) NOT NULL,
custom_value TEXT,
robik TEXT,
INDEX search_key (data_type, data_id, custom_key),
INDEX get_key (data_type, data_id)
);
'
);
dbDelta(
'
CREATE TABLE ' . $wpdb->prefix . 'woocommerce_p24_order_map (
order_hash VARCHAR(40) UNIQUE NOT NULL PRIMARY KEY,
order_id INT NOT NULL,
INDEX search_hash (order_hash)
);
'
);
dbDelta(
'
CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'woocommerce_p24_subscription(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
valid_to DATETIME NOT NULL,
extend TINYINT NOT NULL,
card_ref TEXT NULL,
last_order_id BIGINT NOT NULL,
last_checked DATETIME NOT NULL,
INDEX (user_id),
INDEX (product_id),
INDEX (last_order_id),
INDEX (valid_to)
);
'
);
if ( $wpdb->get_var( "SHOW TABLES LIKE '" . $wpdb->prefix . "woocommerce_p24_custom_data'" ) === $wpdb->prefix . 'woocommerce_p24_custom_data' && ! $wpdb->get_var( 'SELECT COUNT(*) FROM ' . $wpdb->prefix . 'woocommerce_p24_data' ) ) {
$wpdb->query(
'
INSERT INTO ' . $wpdb->prefix . 'woocommerce_p24_data
SELECT * FROM ' . $wpdb->prefix . 'woocommerce_p24_custom_data
'
); /* db call ok; no cache ok */
}
}
/**
* Update shedules.
*/
private static function update_shedules() {
if ( ! wp_next_scheduled( 'p24_daily_event' ) ) {
wp_schedule_event( time(), 'daily', 'p24_daily_event' );
}
}
/**
* Check install.
*/
public static function check_install() {
$configured = get_option( self::P24_INSTALLED_VERSION );
$actual = P24_Core::INTERNAL_VERSION;
if ( $configured !== $actual ) {
self::update_database();
self::update_shedules();
update_option( self::P24_INSTALLED_VERSION, $actual, true );
}
}
}

View File

@@ -0,0 +1,299 @@
<?php
/**
* File that define P24_Leaderboards_Controller class. This is code from WooCommerce plugin with overwritten data
* stores. Slightly rebuilt (few texts were moved to constants).
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Leaderboards;
use P24_Categories_Data_Store as CategoriesDataStore;
use P24_Coupons_Data_Store as CouponsDataStore;
use P24_Customers_Data_Store as CustomersDataStore;
use P24_Products_Data_Store as ProductsDataStore;
/**
* Class P24_Leaderbords_Controller.
*/
class P24_Leaderboards_Controller extends Leaderboards {
const LEADERBOARD_ARGUMENT_ORDER_BY = 'orderby';
const LEADERBOARD_ARGUMENT_ORDER = 'order';
const LEADERBOARD_ARGUMENT_AFTER = 'after';
const LEADERBOARD_ARGUMENT_BEFORE = 'before';
const LEADERBOARD_ARGUMENT_PER_PAGE = 'per_page';
const LEADERBOARD_ARGUMENT_EXTENDED_INFO = 'extended_info';
const LEADERBOARD_ARGUMENT_ORDER_AFTER = 'order_after';
const LEADERBOARD_ARGUMENT_ORDER_BEFORE = 'order_before';
/**
* Get the data for the coupons leaderboard.
*
* @param int $per_page Number of rows.
* @param string $after Items after date.
* @param string $before Items before date.
* @param string $persisted_query URL query string.
*
* @return array
*/
public function get_coupons_leaderboard( $per_page, $after, $before, $persisted_query ) {
$coupons_data_store = new CouponsDataStore();
$coupons_data = $per_page > 0 ? $coupons_data_store->get_data(
array(
self::LEADERBOARD_ARGUMENT_ORDER_BY => 'orders_count',
self::LEADERBOARD_ARGUMENT_ORDER => 'desc',
self::LEADERBOARD_ARGUMENT_AFTER => $after,
self::LEADERBOARD_ARGUMENT_BEFORE => $before,
self::LEADERBOARD_ARGUMENT_PER_PAGE => $per_page,
self::LEADERBOARD_ARGUMENT_EXTENDED_INFO => true,
)
)->data : array();
$rows = array();
foreach ( $coupons_data as $coupon ) {
$url_query = wp_parse_args(
array(
'filter' => 'single_coupon',
'coupons' => $coupon['coupon_id'],
),
$persisted_query
);
$coupon_url = wc_admin_url( '/analytics/coupons', $url_query );
$coupon_code = isset( $coupon['extended_info'] ) && isset( $coupon['extended_info']['code'] ) ? $coupon['extended_info']['code'] : '';
$rows[] = array(
array(
'display' => "<a href='{$coupon_url}'>{$coupon_code}</a>",
'value' => $coupon_code,
),
array(
'display' => wc_admin_number_format( $coupon['orders_count'] ),
'value' => $coupon['orders_count'],
),
array(
'display' => wc_price( $coupon['amount'] ),
'value' => $coupon['amount'],
),
);
}
return array(
'id' => 'coupons',
'label' => __( 'Top Coupons - Number of Orders', 'woocommerce' ),
'headers' => array(
array(
'label' => __( 'Coupon Code', 'woocommerce' ),
),
array(
'label' => __( 'Orders', 'woocommerce' ),
),
array(
'label' => __( 'Amount Discounted', 'woocommerce' ),
),
),
'rows' => $rows,
);
}
/**
* Get the data for the categories leaderboard.
*
* @param int $per_page Number of rows.
* @param string $after Items after date.
* @param string $before Items before date.
* @param string $persisted_query URL query string.
*
* @return array
*/
public function get_categories_leaderboard( $per_page, $after, $before, $persisted_query ) {
$categories_data_store = new CategoriesDataStore();
$categories_data = $per_page > 0 ? $categories_data_store->get_data(
array(
self::LEADERBOARD_ARGUMENT_ORDER_BY => 'items_sold',
self::LEADERBOARD_ARGUMENT_ORDER => 'desc',
self::LEADERBOARD_ARGUMENT_AFTER => $after,
self::LEADERBOARD_ARGUMENT_BEFORE => $before,
self::LEADERBOARD_ARGUMENT_PER_PAGE => $per_page,
self::LEADERBOARD_ARGUMENT_EXTENDED_INFO => true,
)
)->data : array();
$rows = array();
foreach ( $categories_data as $category ) {
$url_query = wp_parse_args(
array(
'filter' => 'single_category',
'categories' => $category['category_id'],
),
$persisted_query
);
$category_url = wc_admin_url( '/analytics/categories', $url_query );
$category_name = isset( $category['extended_info'] ) && isset( $category['extended_info']['name'] ) ? $category['extended_info']['name'] : '';
$rows[] = array(
array(
'display' => "<a href='{$category_url}'>{$category_name}</a>",
'value' => $category_name,
),
array(
'display' => wc_admin_number_format( $category['items_sold'] ),
'value' => $category['items_sold'],
),
array(
'display' => wc_price( $category['net_revenue'] ),
'value' => $category['net_revenue'],
),
);
}
return array(
'id' => 'categories',
'label' => __( 'Top Categories - Items Sold', 'woocommerce' ),
'headers' => array(
array(
'label' => __( 'Category', 'woocommerce' ),
),
array(
'label' => __( 'Items Sold', 'woocommerce' ),
),
array(
'label' => __( 'Net Sales', 'woocommerce' ),
),
),
'rows' => $rows,
);
}
/**
* Get the data for the customers leaderboard.
*
* @param int $per_page Number of rows.
* @param string $after Items after date.
* @param string $before Items before date.
* @param string $persisted_query URL query string.
*
* @return array
*/
public function get_customers_leaderboard( $per_page, $after, $before, $persisted_query ) {
$customers_data_store = new CustomersDataStore();
$customers_data = $per_page > 0 ? $customers_data_store->get_data(
array(
self::LEADERBOARD_ARGUMENT_ORDER_BY => 'total_spend',
self::LEADERBOARD_ARGUMENT_ORDER => 'desc',
self::LEADERBOARD_ARGUMENT_ORDER_AFTER => $after,
self::LEADERBOARD_ARGUMENT_ORDER_BEFORE => $before,
self::LEADERBOARD_ARGUMENT_PER_PAGE => $per_page,
)
)->data : array();
$rows = array();
foreach ( $customers_data as $customer ) {
$url_query = wp_parse_args(
array(
'filter' => 'single_customer',
'customers' => $customer['id'],
),
$persisted_query
);
$customer_url = wc_admin_url( '/analytics/customers', $url_query );
$rows[] = array(
array(
'display' => "<a href='{$customer_url}'>{$customer['name']}</a>",
'value' => $customer['name'],
),
array(
'display' => wc_admin_number_format( $customer['orders_count'] ),
'value' => $customer['orders_count'],
),
array(
'display' => wc_price( $customer['total_spend'] ),
'value' => $customer['total_spend'],
),
);
}
return array(
'id' => 'customers',
'label' => __( 'Top Customers - Total Spend', 'woocommerce' ),
'headers' => array(
array(
'label' => __( 'Customer Name', 'woocommerce' ),
),
array(
'label' => __( 'Orders', 'woocommerce' ),
),
array(
'label' => __( 'Total Spend', 'woocommerce' ),
),
),
'rows' => $rows,
);
}
/**
* Get the data for the products leaderboard.
*
* @param int $per_page Number of rows.
* @param string $after Items after date.
* @param string $before Items before date.
* @param string $persisted_query URL query string.
*
* @return array
*/
public function get_products_leaderboard( $per_page, $after, $before, $persisted_query ) {
$products_data_store = new ProductsDataStore();
$products_data = $per_page > 0 ? $products_data_store->get_data(
array(
self::LEADERBOARD_ARGUMENT_ORDER_BY => 'items_sold',
self::LEADERBOARD_ARGUMENT_ORDER => 'desc',
self::LEADERBOARD_ARGUMENT_AFTER => $after,
self::LEADERBOARD_ARGUMENT_BEFORE => $before,
self::LEADERBOARD_ARGUMENT_PER_PAGE => $per_page,
self::LEADERBOARD_ARGUMENT_EXTENDED_INFO => true,
)
)->data : array();
$rows = array();
foreach ( $products_data as $product ) {
$url_query = wp_parse_args(
array(
'filter' => 'single_product',
'products' => $product['product_id'],
),
$persisted_query
);
$product_url = wc_admin_url( '/analytics/products', $url_query );
$product_name = isset( $product[ self::LEADERBOARD_ARGUMENT_EXTENDED_INFO ] )
&& isset( $product[ self::LEADERBOARD_ARGUMENT_EXTENDED_INFO ]['name'] )
? $product[ self::LEADERBOARD_ARGUMENT_EXTENDED_INFO ]['name'] : '';
$rows[] = array(
array(
'display' => "<a href='{$product_url}'>{$product_name}</a>",
'value' => $product_name,
),
array(
'display' => wc_admin_number_format( $product['items_sold'] ),
'value' => $product['items_sold'],
),
array(
'display' => wc_price( $product['net_revenue'] ),
'value' => $product['net_revenue'],
),
);
}
return array(
'id' => 'products',
'label' => __( 'Top Products - Items Sold', 'woocommerce' ),
'headers' => array(
array(
'label' => __( 'Product', 'woocommerce' ),
),
array(
'label' => __( 'Items Sold', 'woocommerce' ),
),
array(
'label' => __( 'Net Sales', 'woocommerce' ),
),
),
'rows' => $rows,
);
}
}

View File

@@ -0,0 +1,210 @@
<?php
/**
* File that define P24_Message_Validator class.
*
* @package Przelewy24
*/
/**
* Class P24_Message_Validator.
*/
class P24_Message_Validator {
/**
* Validate version.
*
* @param string $version Reference to version variable.
* @return bool
*/
private function validate_version( &$version ) {
if ( preg_match( '/^[0-9]+(?:\.[0-9]+)*(?:[\.\-][0-9a-z]+)?$/', $version ) ) {
return true;
}
$version = '';
return false;
}
/**
* Validate email.
*
* @param string $email Reference to email variable.
* @return bool
*/
private function validate_email( &$email ) {
$email = filter_var( $email, FILTER_VALIDATE_EMAIL );
if ( $email ) {
return true;
}
$email = '';
return false;
}
/**
* Validate number.
*
* @param string|float|int $value Reference to value that should be a number.
* @param bool|int $min The minimum allowed value, false for unbound.
* @param bool|int $max The maximum allowed value, false for unbound.
* @return bool
*/
private function validate_number( &$value, $min = false, $max = false ) {
if ( is_numeric( $value ) ) {
$value = (int) $value;
if ( ( false !== $min && $value < $min ) || ( false !== $max && $value > $max ) ) {
return false;
}
return true;
}
$value = ( false !== $min ? $min : 0 );
return false;
}
/**
* Validate string.
*
* @param string $value The reference to string.
* @param int $len The maximum length, 0 for unlimited.
* @return bool
*/
private function validate_string( &$value, $len = 0 ) {
if ( preg_match( '/<[^<]+>/', $value, $m ) === 1 ) {
return false;
}
if ( 0 === $len ^ strlen( $value ) <= $len ) {
return true;
}
$value = '';
return false;
}
/**
* Validate URL.
*
* @param string $url The reference to url.
* @param int $len The maximum length, 0 for unlimited.
* @return bool
*/
private function validate_url( &$url, $len = 0 ) {
if ( 0 === $len ^ strlen( $url ) <= $len ) {
if ( preg_match( '@^https?://[^\s/$.?#].[^\s]*$@iS', $url ) ) {
return true;
}
}
$url = '';
return false;
}
/**
* Validate enum.
*
* @param string $value The reference to value.
* @param array $haystack The list of valid values.
* @return bool
*/
private function validate_enum( &$value, $haystack ) {
if ( in_array( strtolower( $value ), $haystack, true ) ) {
return true;
}
$value = $haystack[0];
return false;
}
/**
* Validate field.
*
* @param string $field The name of field.
* @param mixed $value The reference to value.
* @return boolean
*/
public function validate_field( $field, &$value ) {
$ret = false;
switch ( $field ) {
case 'p24_session_id':
$ret = $this->validate_string( $value, 100 );
break;
case 'p24_description':
$ret = $this->validate_string( $value, 1024 );
break;
case 'p24_address':
$ret = $this->validate_string( $value, 80 );
break;
case 'p24_country':
case 'p24_language':
$ret = $this->validate_string( $value, 2 );
break;
case 'p24_client':
case 'p24_city':
$ret = $this->validate_string( $value, 50 );
break;
case 'p24_merchant_id':
case 'p24_pos_id':
case 'p24_order_id':
case 'p24_amount':
case 'p24_method':
case 'p24_time_limit':
case 'p24_channel':
case 'p24_shipping':
$ret = $this->validate_number( $value );
break;
case 'p24_wait_for_result':
$ret = $this->validate_number( $value, 0, 1 );
break;
case 'p24_api_version':
$ret = $this->validate_version( $value );
break;
case 'p24_sign':
if ( strlen( $value ) === 32 && ctype_xdigit( $value ) ) {
$ret = true;
} else {
$value = '';
}
break;
case 'p24_url_return':
case 'p24_url_status':
$ret = $this->validate_url( $value, 250 );
break;
case 'p24_currency':
$ret = (bool) preg_match( '/^[A-Z]{3}$/', $value );
if ( ! $ret ) {
$value = '';
}
break;
case 'p24_email':
$ret = $this->validate_email( $value );
break;
case 'p24_encoding':
$ret = $this->validate_enum( $value, array( 'iso-8859-2', 'windows-1250', 'urf-8', 'utf8' ) );
break;
case 'p24_transfer_label':
$ret = $this->validate_string( $value, 20 );
break;
case 'p24_phone':
$ret = $this->validate_string( $value, 12 );
break;
case 'p24_zip':
$ret = $this->validate_string( $value, 10 );
break;
default:
if ( strpos( $field, 'p24_quantity_' ) === 0 || strpos( $field, 'p24_price_' ) === 0 || strpos( $field, 'p24_number_' ) === 0 ) {
$ret = $this->validate_number( $value );
} elseif ( strpos( $field, 'p24_name_' ) === 0 || strpos( $field, 'p24_description_' ) === 0 ) {
$ret = $this->validate_string( $value, 127 );
} else {
$value = '';
}
break;
}
return $ret;
}
/**
* Filter value.
*
* @param string $field The name of field.
* @param string|float|int $value The value to test.
* @return bool|string
*/
public function filter_value( $field, $value ) {
return ( $this->validate_field( $field, $value ) ) ? addslashes( $value ) : false;
}
}

View File

@@ -0,0 +1,116 @@
<?php
/**
* File that define P24_Multi_Currency_Menu class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class P24_Multi_Currency_Menu
*
* Update the menu section on admin panel.
*/
class P24_Multi_Currency_Menu {
/**
* The P24_Core instance.
*
* @var P24_Core
*/
private $plugin_core;
/**
* The constructor.
*
* @param P24_Core $plugin_core The P24_Core instance.
*/
public function __construct( P24_Core $plugin_core ) {
$this->plugin_core = $plugin_core;
}
/**
* Generate form to select links to change currency in user mode.
*/
public function nav_menu_link() {
$params = [
'currency_options' => get_przelewy24_multi_currency_options(),
];
$this->plugin_core->render_template( 'currency-menu-generator', $params );
}
/**
* Add box on admin panel to select links.
*/
public function add_menu_box() {
if ( $this->plugin_core->is_internal_multi_currency_active() ) {
add_meta_box(
'p24_menu_box',
__( 'Moduł multi currency', 'przelewy24' ),
[ $this, 'nav_menu_link' ],
'nav-menus',
'side',
'low'
);
}
}
/**
* Check if selected post should be show in menu.
*
* @param WP_Post $item The element to show in menu.
*
* @return bool
*/
private function check_drop_inactive_currency( WP_Post $item ) {
if ( property_exists( $item, 'url' ) ) {
$url = $item->{'url'};
$rx = '/^\\?p24\\_change\\_currency\\=(.+)$/';
if ( preg_match( $rx, $url, $m ) ) {
$currency = $m[1];
$mc = $this->plugin_core->get_multi_currency_instance();
if ( $currency === $mc->get_active_currency() ) {
return true;
} elseif ( ! in_array( $currency, $mc->get_available_currencies(), true ) ) {
return true;
}
}
}
return false;
}
/**
* Filter user menu items.
*
* @param array $items Sorted list of items in menu.
*
* @return array
*/
public function filter_user_menu( $items ) {
$ret = [];
foreach ( $items as $item ) {
$classes = $item->classes;
if ( in_array( 'p24-change-currency', $classes, true ) ) {
if ( ! $this->plugin_core->is_internal_multi_currency_active() ) {
/* If there is no multi currency, drop all links. */
continue;
}
if ( $this->check_drop_inactive_currency( $item ) ) {
continue;
}
}
$ret[] = $item;
}
return $ret;
}
/**
* Bind events.
*/
public function bind_events() {
add_action( 'admin_init', [ $this, 'add_menu_box' ] );
add_filter( 'wp_nav_menu_objects', [ $this, 'filter_user_menu' ] );
}
}

View File

@@ -0,0 +1,733 @@
<?php
/**
* File that define P24_Multi_Currency class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class P24_Multi_Currency
*
* Add elementary functions to support multi currency.
*/
class P24_Multi_Currency implements P24_MC_Interface {
// WooCommerce values - no constants are used in WC libraries for them.
const WOOCOMMERCE_FIELD_DECIMAL_SEPARATOR = 'decimal_separator';
const WOOCOMMERCE_FIELD_THOUSAND_SEPARATOR = 'thousand_separator';
const WOOCOMMERCE_FIELD_DECIMALS = 'decimals';
/**
* Internal name for this implementation of Multi Currency.
*/
const MC_NAME = 'P24_MC_Internal';
/**
* Instance of core of plugin.
*
* @var P24_Core
*/
private $plugin_core;
/**
* The currency to display for users.
*
* @var string|null
*/
private $active_currency;
/**
* P24_Multi_Currency constructor.
*
* @param P24_Core $plugin_core Instance of main plugin.
* @param string|null $active_currency Active currency to set.
*/
public function __construct( P24_Core $plugin_core, $active_currency ) {
$this->plugin_core = $plugin_core;
$this->active_currency = $active_currency;
}
/**
* Check if external multi currency is activated.
*
* If this instance exists, it should be active.
*
* @return bool
*/
public function is_multi_currency_active() {
return true;
}
/**
* Check if multi currency is internal.
*
* @return bool
*/
public function is_internal() {
return true;
}
/**
* Get reports currency.
*
* @param string|null $default Default reports currency.
*
* @return string|null
*/
public static function get_admin_reports_currency( $default = null ) {
if ( ! isset( $_COOKIE['admin_p24_reports_currency'] ) ) {
return $default;
}
return sanitize_text_field( wp_unslash( $_COOKIE['admin_p24_reports_currency'] ) );
}
/**
* Get sql query which filters report data by order currency.
*
* @param string $order_table Name of table with orders (without prefix).
*
* @return string
*/
public static function get_currency_filter_for_reports( $order_table ) {
/**
* Global variable usage suggested in WordPress Documentation:
* https://developer.wordpress.org/reference/classes/wpdb/ .
*
* Unfortunately there does not seem to be any alternative to access db prefix by global variables.
*/
global $wpdb;
$metadata_table = esc_sql( "{$wpdb->prefix}postmeta" );
$currency = esc_sql( self::get_admin_reports_currency( get_woocommerce_currency() ) );
$metadata_alias = 'p24_postmeta';
$order_table = esc_sql( $order_table );
return " JOIN {$metadata_table} as {$metadata_alias} ON (" .
"{$metadata_alias}.meta_key = '_order_currency'" . ' AND ' .
"{$metadata_alias}.meta_value = '" . $currency . "'" . ' AND ' .
"{$metadata_alias}.post_id = {$order_table}.order_id)";
}
/**
* Get active currency.
*
* @return string
*/
public function get_active_currency() {
if ( ! $this->active_currency ) {
$multipliers = $this->get_multipliers();
wp_verify_nonce( null ); /* There is no noce. */
if ( $this->plugin_core->is_in_user_mode() ) {
$this->active_currency = $this->get_active_currency_from_cookie( $multipliers );
} elseif ( $this->plugin_core->is_in_json_mode() ) {
if ( array_key_exists( P24_Request_Support::WP_JSON_GET_KEY_CURRENCY, $_GET ) ) {
$this->active_currency = sanitize_text_field( wp_unslash( $_GET[ P24_Request_Support::WP_JSON_GET_KEY_CURRENCY ] ) );
}
}
if ( ! $this->active_currency || ! array_key_exists( $this->active_currency, $multipliers ) ) {
$this->active_currency = P24_Woo_Commerce_Low_Level_Getter::get_unhooked_currency_form_woocommerce();
}
}
return $this->active_currency;
}
/**
* Get default currency.
*
* It may be different from active currency.
*
* @return string
*/
public function get_default_currency() {
return P24_Woo_Commerce_Low_Level_Getter::get_unhooked_currency_form_woocommerce();
}
/**
* Save active currency to cookie.
*/
public function save_currency_to_cookie() {
wc_setcookie( 'user_p24_currency', $this->active_currency );
}
/**
* Try to get active currency from cookie.
*
* @param array $multipliers Array of valid currencies with multipliers.
* @return string|null
*/
private function get_active_currency_from_cookie( array $multipliers ) {
if ( isset( $_COOKIE['user_p24_currency'] ) ) {
$this->active_currency = sanitize_text_field( wp_unslash( $_COOKIE['user_p24_currency'] ) );
} else {
$this->active_currency = null;
}
if ( ! $this->active_currency || ! array_key_exists( $this->active_currency, $multipliers ) ) {
/* Fix cookie. */
$this->active_currency = P24_Woo_Commerce_Low_Level_Getter::get_unhooked_currency_form_woocommerce();
$this->save_currency_to_cookie();
}
return $this->active_currency;
}
/**
* Get array of multipliers for currencies.
*
* @return array
*/
public function get_multipliers() {
$set = get_option( 'przelewy24_multi_currency_multipliers', array() );
$default = P24_Woo_Commerce_Low_Level_Getter::get_unhooked_currency_form_woocommerce();
$set[ $default ] = 1;
return $set;
}
/**
* Get list of available currencies.
*
* It is based on multipliers.
*
* @return array
*/
public function get_available_currencies() {
$set = $this->get_multipliers();
$keys = array_keys( $set );
return array_combine( $keys, $keys );
}
/**
* Get name.
*
* @return string
*/
public function get_name() {
return self::MC_NAME;
}
/**
* Method for filter that change default currency.
*
* The default value is ignored.
* The wrapped function should always return something.
*
* @param mixed $default Default value provided by filter.
* @return string
*/
public function try_change_default_currency( $default ) {
$active = $this->get_active_currency();
return $active ? $active : $default;
}
/**
* Try change price format.
*
* @param mixed $default Default value.
* @param string $option Name of option.
* @return mixed
*/
private function try_change_price_format( $default, $option ) {
$is_reports_context = $this->plugin_core->get_context_provider()->is_reports_context();
/* Do not change defaults on admin panel except for reports. */
if ( is_admin() && ! $is_reports_context ) {
return $default;
}
$currency = $is_reports_context ? $this->get_admin_reports_currency() : $this->get_active_currency();
if ( null === $currency ) {
return $default;
}
$format = $this->get_przelewy24_multi_currency_format( $currency, $option );
return null !== $format ? $format : $default;
}
/**
* Get price format from multicurrency settings.
*
* @param string $currency Default value.
* @param string $option Name of option.
*
* @return string|null
*/
private function get_przelewy24_multi_currency_format( $currency, $option ) {
$formats = get_option( 'przelewy24_multi_currency_formats', array() );
if ( ! array_key_exists( $currency, $formats ) || ! array_key_exists( $option, $formats[ $currency ] ) ) {
return null;
}
$return = $formats[ $currency ][ $option ];
if ( 'thousand_separator' !== $option && '' === $return ) {
return null;
}
return $return;
}
/**
* Try change thousand separator.
*
* @param string $default Default thousand separator.
* @return string
*/
public function try_change_thousand_separator( $default ) {
return $this->try_change_price_format( $default, 'thousand_separator' );
}
/**
* Try change decimal separator.
*
* @param string $default Default decimal separator.
* @return string
*/
public function try_change_decimal_separator( $default ) {
return $this->try_change_price_format( $default, 'decimal_separator' );
}
/**
* Try change number of fraction digits.
*
* @param mixed $default Default number of fraction digits.
* @return mixed
*/
public function try_change_decimals( $default ) {
return $this->try_change_price_format( $default, 'decimals' );
}
/**
* Try change currency position.
*
* @param string $default Default currency position.
* @return string
*/
public function try_change_currency_pos( $default ) {
return $this->try_change_price_format( $default, 'currency_pos' );
}
/**
* Add scripts used on admin page.
*/
public function add_admin_scripts() {
wp_enqueue_script( 'p24_multi_currency_admin_script', PRZELEWY24_URI . 'assets/js/p24_multi_currency_admin_script.js', array( 'jquery' ), P24_Core::SCRIPTS_VERSION, true );
}
/**
* Add scripts used on user page.
*/
public function add_user_scripts() {
wp_enqueue_style( 'p24_multi_currency_form', PRZELEWY24_URI . 'assets/css/p24_multi_currency_style.css', array(), P24_Core::SCRIPTS_VERSION );
}
/**
* No product class error suppressor.
*
* We have to run this code before find_product_class.
*
* @param string|null $suggested
* @return string
*/
public function no_product_class_error_suppressor( $suggested ) {
if ( ! $suggested || ! class_exists( $suggested ) ) {
return WC_Product_Simple::class;
} else {
return $suggested;
}
}
/**
* Try find name of class for product.
*
* This method has to be run after no_product_class_error_suppressor.
*
* This method works as filter. The suggested class is required to do proper override.
*
* @param string $suggested Suggested product class.
* @param string $type Product type.
* @param string $variation Product variation.
* @param int $product_id Product id.
* @return string
* @throws LogicException If nothing was provided or found.
*/
public function find_product_class( $suggested, $type, $variation, $product_id ) {
$rx1 = '/^WC\\_Product\\_(.+)$/';
$rx2 = '/^P24\\_No\\_MC\\_Product\\_(.+)$/';
if ( preg_match( $rx1, $suggested, $m ) ) {
$class = 'P24_Product_' . $m[1];
} elseif ( preg_match( $rx2, $suggested, $m ) ) {
$class = 'P24_Product_' . $m[1];
} else {
$class = $suggested;
}
if ( class_exists( $class ) ) {
return $class;
} else {
$msg = "The incompatability with multi currency and other plugin occured. Cannot compute price. The required class $class cannot be found. Suggested class was $suggested, type was $type, variation was $variation, id was $product_id.";
throw new LogicException( $msg );
}
}
/**
* Update price hash.
*
* The multiplier for currency is added.
*
* @param array $hash Default hash.
* @param WC_Product $product The product.
* @param string $context The context.
* @return array
* @throws LogicException If the currency is not configured.
*/
public function filter_price_hash( $hash, $product, $context ) {
if ( method_exists( $product, 'get_currency' ) ) {
$currency = $product->get_currency( $context );
$multipliers = $this->get_multipliers();
if ( ! array_key_exists( $currency, $multipliers ) ) {
throw new LogicException( "The requested currency $currency is not configured." );
}
$hash[] = $multipliers[ $currency ];
}
return $hash;
}
/**
* Try override active currency.
*
* The communication with Przelewy24 is quite late.
*
* @param P24_Communication_Parser $parser The P24_Communication_Parser instance.
*/
public function try_override_active_currency( P24_Communication_Parser $parser ) {
if ( $parser->is_valid() ) {
$this->active_currency = $parser->get_currency();
}
}
/**
* Replaces store element.
*
* @param array $results Current stores.
*
* @return array
*/
public static function add_to_store( $results ) {
$p24_stores = array(
'report-orders-stats' => 'P24_Orders_Stats_Data_Store',
'report-revenue-stats' => 'P24_Orders_Stats_Data_Store',
'report-products-stats' => 'P24_Products_Stats_Data_Store',
'report-products' => 'P24_Products_Data_Store',
'report-categories' => 'P24_Categories_Data_Store',
'report-orders' => 'P24_Orders_Data_Store',
'report-variations' => 'P24_Variations_Data_Store',
'report-taxes' => 'P24_Taxes_Data_Store',
'report-taxes-stats' => 'P24_Taxes_Stats_Data_Store',
'report-coupons' => 'P24_Coupons_Data_Store',
'report-coupons-stats' => 'P24_Coupons_Stats_Data_Store',
'report-customers' => 'P24_Customers_Data_Store',
'report-customers-stats' => 'P24_Customers_Stats_Data_Store',
);
return array_merge( $results, $p24_stores );
}
/**
* Compute price in provided currency.
*
* @param mixed $price Price in default currency.
* @param string $currency Provided currency.
* @return mixed
* @throws LogicException If currency is not found.
*/
public function compute_price_in_currency( $price, $currency ) {
if ( ! $price ) {
/* We have to preserve different false values. */
return $price;
}
$multipliers = $this->get_multipliers();
if ( array_key_exists( $currency, $multipliers ) ) {
$multiplier = $multipliers[ $currency ];
} else {
throw new LogicException( "The currency $currency not found in config." );
}
if ( 1.0 === (float) $multiplier ) {
return $price;
} else {
return $price * $multiplier;
}
}
/**
* Convert price between currencies.
*
* @param mixed $price Price in default currency.
* @param string $from From currency.
* @param string $to To currency.
* @return mixed
* @throws LogicException If any currency is not found.
*/
public function convert_price( $price, $from, $to ) {
if ( ! $price ) {
/* We have to preserve different false values. */
return $price;
}
$multipliers = $this->get_multipliers();
if ( array_key_exists( $from, $multipliers ) ) {
$multiplier_from = $multipliers[ $from ];
} else {
throw new LogicException( "The currency $from not found in config." );
}
if ( array_key_exists( $to, $multipliers ) ) {
$multiplier_to = $multipliers[ $to ];
} else {
throw new LogicException( "The currency $to not found in config." );
}
if ( 1.0 === (float) $multiplier_to / $multiplier_from ) {
return $price;
} else {
return $price * $multiplier_to / $multiplier_from;
}
}
/**
* Compute prices for sending package.
*
* @param array $rates The set of rages.
*
* @return array
*/
public function update_package_rates( $rates ) {
$currency = $this->get_active_currency();
$ret = array();
foreach ( $rates as $idx => $rate ) {
$cost = $rate->get_cost();
$cost = $this->compute_price_in_currency( $cost, $currency );
$rate->set_cost( $cost );
$taxes = $rate->get_taxes();
$currencies_map = array_fill_keys( array_keys( $taxes ), $currency );
$taxes_keys = array_keys( $taxes );
$taxes = array_map( array( $this, 'compute_price_in_currency' ), $taxes, $currencies_map );
$rate->set_taxes( array_combine( $taxes_keys, $taxes ) );
$ret[ $idx ] = $rate;
}
return $rates;
}
/**
* Try override one field for multi currency.
*
* @param string $field The name of field in meta table.
* @param array $sql The SQL split into few parts.
*
* @return array
*/
private function sql_override_field( $field, $sql ) {
$rxs = '/^(.*\\S)\\s?SUM\\s*\\(\\s*meta_' . $field . '\\.meta_value\\s*\\)(.*)$/Dis';
$rxj = '/INNER\\s+JOIN\\s+(\\S*postmeta)\\s+AS\\s+(\\S+)\\s+ON\\s*\\([^\\)]*\\.meta_key\\s*\\=\\s*\\\'' . $field . '\\\'[^\\)]*\\)/is';
if ( preg_match( $rxs, $sql['select'], $ms ) && preg_match( $rxj, $sql['join'], $mj ) ) {
$meta_tbl = $mj[1];
$base_tbl = $mj[2];
$our_tbl = $base_tbl . '_p24dc';
$our_field = $field . '_p24dc';
$select_head = $ms[1];
$select_tail = $ms[2];
$sql['select'] = "$select_head SUM(IFNULL($our_tbl.meta_value, $base_tbl.meta_value ) )$select_tail";
$sql['join'] = $sql['join'] . "\n"
. " LEFT JOIN $meta_tbl AS $our_tbl ON (\n"
. " $our_tbl.meta_key = '$our_field'\n"
. " AND $our_tbl.post_id = $base_tbl.post_id\n"
. " )\n";
}
return $sql;
}
/**
* Override SQL to be compatible with multi currency.
*
* @param array $sql The SQL split into few parts.
*
* @return array
*/
public function sql_override( $sql ) {
if ( array_key_exists( 'select', $sql ) && array_key_exists( 'join', $sql ) ) {
$sql = $this->sql_override_field( '_order_total', $sql );
$sql = $this->sql_override_field( '_order_tax', $sql );
$sql = $this->sql_override_field( '_order_shipping', $sql );
$sql = $this->sql_override_field( '_order_shipping_tax', $sql );
$sql = $this->sql_override_field( '_order_discount', $sql );
$sql = $this->sql_override_field( '_order_discount_tax', $sql );
}
return $sql;
}
/**
* Add additional fields to order.
*
* @param WC_Abstract_Order $order The order to save.
*/
public function before_order_save( $order ) {
$dc = $this->get_default_currency();
$oc = $order->get_currency();
if ( $dc !== $order->get_currency() ) {
$multipliers = $this->get_multipliers();
$multiplier = $multipliers[ $oc ];
$total = $order->get_total();
$dc_total = $total / $multiplier;
$tax = $order->get_cart_tax();
$dc_tax = $tax / $multiplier;
$shipping = $order->get_shipping_total();
$dc_shipping = $shipping / $multiplier;
$shipping_tax = $order->get_shipping_tax();
$dc_shipping_tax = $shipping_tax / $multiplier;
$discount = $order->get_discount_total();
$dc_discount = $discount / $multiplier;
$discount_tax = $order->get_discount_tax();
$dc_discount_tax = $discount_tax / $multiplier;
$order->add_meta_data( '_order_total_p24dc', $dc_total, true );
$order->add_meta_data( '_order_tax_p24dc', $dc_tax, true );
$order->add_meta_data( '_order_shipping_p24dc', $dc_shipping, true );
$order->add_meta_data( '_order_shipping_tax_p24dc', $dc_shipping_tax, true );
$order->add_meta_data( '_cart_discount_p24dc', $dc_discount, true );
$order->add_meta_data( '_cart_discount_tax_p24dc', $dc_discount_tax, true );
if ( $order instanceof WC_Order_Refund ) {
$refund = $order->get_amount();
$dc_refund = $refund / $multiplier;
$order->add_meta_data( '_refund_amount_p24dc', $dc_refund, true );
}
}
}
/**
* Update order currency.
*
* The function should be called after nonce verification.
* We have to get the raw data from global variable, though.
*
* @param int|null $id The id of order.
*/
public function update_order_currency( $id ) {
if ( isset( $_POST['p24_order_currency'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
$currency = sanitize_text_field( wp_unslash( $_POST['p24_order_currency'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
$available = $this->get_available_currencies();
if ( in_array( $currency, $available, true ) ) {
update_metadata( 'post', $id, '_order_currency', $currency );
}
}
}
/**
* Register widget for multi currency.
*/
public function register_widget() {
$widget = new P24_Currency_Selector_Widget( $this->plugin_core );
register_widget( $widget );
}
/**
* Updates admin report rest controllers.
*
* @param array $controllers Rest controllers supplied for reports context.
*
* @return array
*/
public function update_admin_rest_controllers( $controllers ) {
$key = array_search( 'Automattic\WooCommerce\Admin\API\Leaderboards', $controllers, true );
if ( false === $key ) {
return $controllers;
}
$controllers[ $key ] = 'P24_Leaderboards_Controller';
return $controllers;
}
/**
* Update admin wc price format arguments.
*
* @param array $args Currency arguments.
*
* @return array
*/
public function update_wc_price_format_arguments( $args ) {
$currency = isset( $args[ P24_Request_Support::WP_JSON_GET_KEY_CURRENCY ] ) && $args[ P24_Request_Support::WP_JSON_GET_KEY_CURRENCY ]
? $args[ P24_Request_Support::WP_JSON_GET_KEY_CURRENCY ] : get_woocommerce_currency();
foreach ( self::get_multi_currency_format_fields() as $argument ) {
$p24_multi_currency_value = $this->get_przelewy24_multi_currency_format( $currency, $argument );
if ( null !== $p24_multi_currency_value ) {
$args[ $argument ] = $p24_multi_currency_value;
}
}
$args['price_format'] = $this->get_currency_format_for_currency_pos(
$this->get_przelewy24_multi_currency_format( $currency, 'currency_pos' )
);
return $args;
}
/**
* Get multi currency format fields.
*
* @return array
*/
public static function get_multi_currency_format_fields() {
return array(
self::WOOCOMMERCE_FIELD_DECIMAL_SEPARATOR,
self::WOOCOMMERCE_FIELD_THOUSAND_SEPARATOR,
self::WOOCOMMERCE_FIELD_DECIMALS,
);
}
/**
* Get currency format from currency position.
*
* @param string|null $currency_pos Currency position. Allowed values are: left, right, left_space and right_space.
*
* @return string Value for 'left' will be returned by default - just like in WooCommerce.
*/
private function get_currency_format_for_currency_pos( $currency_pos = null ) {
switch ( $currency_pos ) {
case 'right':
return '%2$s%1$s';
case 'left_space':
return '%1$s&nbsp;%2$s';
case 'right_space':
return '%2$s&nbsp;%1$s';
default: // left - like in dollars.
return '%1$s%2$s';
}
}
/**
* Bind events to use multi currency.
*/
public function bind_events() {
add_action( 'wp_enqueue_scripts', array( $this, 'add_user_scripts' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'add_admin_scripts' ) );
add_action( 'widgets_init', array( $this, 'register_widget' ) );
if ( ! is_admin() ) {
add_filter( 'woocommerce_currency', array( $this, 'try_change_default_currency' ) );
add_filter( 'wc_get_price_decimals', array( $this, 'try_change_decimals' ) );
add_action( 'wp_loaded', array( $this, 'save_currency_to_cookie' ) );
add_filter( 'woocommerce_package_rates', array( $this, 'update_package_rates' ) );
}
if ( $this->plugin_core->get_context_provider()->is_reports_context() ) {
add_filter( 'woocommerce_currency', array( $this, 'get_admin_reports_currency' ) );
add_filter( 'woocommerce_data_stores', array( __CLASS__, 'add_to_store' ) );
}
add_filter( 'wc_price_args', array( $this, 'update_wc_price_format_arguments' ) );
add_filter( 'option_woocommerce_currency_pos', array( $this, 'try_change_currency_pos' ) ); /* Core event. */
add_filter( 'wc_get_price_thousand_separator', array( $this, 'try_change_thousand_separator' ) );
add_filter( 'wc_get_price_decimal_separator', array( $this, 'try_change_decimal_separator' ) );
add_filter( 'woocommerce_product_class', array( $this, 'no_product_class_error_suppressor' ), 40, 1 );
add_filter( 'woocommerce_product_class', array( $this, 'find_product_class' ), 60, 4 );
add_action( 'woocommerce_before_order_object_save', array( $this, 'before_order_save' ) );
add_action( 'woocommerce_before_order_refund_object_save', array( $this, 'before_order_save' ), 10, 2 );
add_action( 'woocommerce_process_shop_order_meta', array( $this, 'update_order_currency' ) );
add_filter( 'woocommerce_get_variation_prices_hash', array( $this, 'filter_price_hash' ), 10, 3 );
add_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'sql_override' ), 10, 1 );
add_filter( 'woocommerce_admin_rest_controllers', array( $this, 'update_admin_rest_controllers' ) );
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**
* File that define P24_Product_Simple class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
*
*
* The product is not aware of multiple currencies.
* We need this class before we have configured multi currency.
*/
class P24_No_Mc_Product_Subscription extends WC_Product {
const TYPE = 'p24_subscription';
/**
* Stores additional product data.
*
* @var array
*/
protected $extra_data = array(
'days' => 1,
);
/**
* P24_Product_Simple constructor.
*
* @param int $product Id of product.
*/
public function __construct( $product = 0 ) {
$this->product_type = self::TYPE;
parent::__construct( $product );
}
/**
* Get days.
*
* @return int
*/
public function get_days() {
$days = (int) $this->get_prop( 'days' );
if ( $days < 1 ) {
$days = 1;
}
return $days;
}
/**
* Set_days.
*
* @param int $days Number of days.
*/
public function set_days( $days ) {
$days = (int) $days;
if ( $days < 1 ) {
$days = 1;
}
$this->set_prop( 'days', $days );
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* File that define P24_Payment_Methods_helper class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The helper for payment methods.
*/
class P24_Payment_Methods_Helper {
/**
* Config.
*
* @var P24_Config_Accessor
*/
private $config;
/**
* Data set.
*
* @var array
*/
private $data_set;
/**
* P24_Icon_Svg_Generator constructor.
*
* @param P24_Config_Accessor $config A valid config.
*/
public function __construct( P24_Config_Accessor $config ) {
$this->config = clone $config;
$this->config->access_mode_to_strict();
}
/**
* Get set.
*
* @return array
*/
private function get_set() {
if ( ! isset( $this->data_set ) ) {
$rest_api = new P24_Rest_Common( $this->config );
$response = $rest_api->payment_methods( 'pl' );
if ( isset( $response['data'] ) ) {
$this->data_set = $response['data'];
} else {
$this->data_set = array();
}
}
return $this->data_set;
}
/**
* Has P24Now.
*
* @return bool
*/
public function has_p24_now() {
$set = $this->get_set();
foreach ( $set as $one ) {
if ( 266 === $one['id'] ) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* File that define P24_Product_External class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The class add to parent awareness of multiple currencies.
*/
class P24_Product_External extends WC_Product_External {
use P24_Product_Trait;
/**
* P24_Product_External constructor.
*
* @param int $product The id of product.
*/
public function __construct( $product = 0 ) {
$this->populate_internal_data();
parent::__construct( $product );
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* File that define P24_Product_Grouped class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The class add to parent awareness of multiple currencies.
*/
class P24_Product_Grouped extends WC_Product_Grouped {
use P24_Product_Trait;
/**
* P24_Product_Grouped constructor.
*
* @param int $product The id of product.
*/
public function __construct( $product = 0 ) {
$this->populate_internal_data();
parent::__construct( $product );
}
}

View File

@@ -0,0 +1,19 @@
<?php
/**
* File that define P24_Product_Keys class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class with keys for overwritten producs.
*/
class P24_Product_Keys {
const KEY_CURRENCY = 'currency';
const KEY_DEFAULT_CURRENCY_PRICE = 'default_currency_price';
const KEY_DEFAULT_CURRENCY_REGULAR_PRICE = 'default_currency_regular_price';
const KEY_DEFAULT_CURRENCY_SALE_PRICE = 'default_currency_sale_price';
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* File that define P24_Product_LP_Course class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The class fix support of multiple currencies in LearnPress.
*/
class P24_Product_LP_Course extends WC_Product_LP_Course {
/**
* Convert_price.
*
* @param mixed $price The base price in LearnPress base currency.
* @return mixed
*/
private function convert_price( $price ) {
$multi_currency = get_przelewy24_plugin_instance()->get_multi_currency_instance();
$from = learn_press_get_currency();
$to = $multi_currency->get_active_currency();
return $multi_currency->convert_price( $price, $from, $to );
}
/**
* Get_price.
*
* @param string|null $context The name of context.
* @return mixed
*/
public function get_price( $context = 'view' ) {
$native = parent::get_price( $context );
$public = $this->convert_price( $native );
return $public;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* File that define P24_Product_Simple class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The class add to parent awareness of multiple currencies.
*/
class P24_Product_Simple extends WC_Product_Simple {
use P24_Product_Trait;
/**
* P24_Product_Simple constructor.
*
* @param int $product Id of product.
*/
public function __construct( $product = 0 ) {
$this->populate_internal_data();
parent::__construct( $product );
}
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* File that define P24_Product_Simple class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
*
*
* The product is aware of multiple currencies.
*/
class P24_Product_Subscription extends P24_No_Mc_Product_Subscription {
use P24_Product_Trait;
/**
* P24_Product_Simple constructor.
*
* @param int $product Id of product.
*/
public function __construct( $product = 0 ) {
$this->populate_internal_data();
parent::__construct( $product );
}
}

View File

@@ -0,0 +1,150 @@
<?php
/**
* File that define P24_Product_Trait trait.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Trait with common methods for overwritten objects.
*/
trait P24_Product_Trait {
/**
* A getter.
*
* Should be defined in parent class of classes including this trait.
*
* @param string $prop The name of prop.
* @param string $context The name of context.
* @return mixed
*/
abstract protected function get_prop( $prop, $context = 'view' );
/**
* A setter for internal variables.
*
* Should be defined in parent class of classes including this trait.
*
* @param string $prop The name of prop.
* @param mixed $value The value of prop.
* @return mixed
*/
abstract protected function set_prop( $prop, $value );
/**
* Common code to run in constructor.
*/
protected function populate_internal_data() {
$this->data[ P24_Product_Keys::KEY_CURRENCY ] = get_woocommerce_currency();
$this->data[ P24_Product_Keys::KEY_DEFAULT_CURRENCY_PRICE ] = '';
$this->data[ P24_Product_Keys::KEY_DEFAULT_CURRENCY_REGULAR_PRICE ] = '';
$this->data[ P24_Product_Keys::KEY_DEFAULT_CURRENCY_SALE_PRICE ] = '';
}
/**
* Compute price native to object.
*
* The object has own currency.
* The false values have special meaning.
*
* @param mixed $price Price in default currency.
* @return mixed
* @throws LogicException If currency is not found.
*/
protected function compute_native_price( $price ) {
$currency = $this->get_currency();
$multi_currency = get_przelewy24_plugin_instance()->get_multi_currency_instance();
return $multi_currency->compute_price_in_currency( $price, $currency );
}
/**
* Get currency of the object.
*
* @param string $context The name of context.
* @return mixed
*/
public function get_currency( $context = 'view' ) {
return $this->get_prop( P24_Product_Keys::KEY_CURRENCY, $context );
}
/**
* Set the product's active price.
*
* @param string $price Price in default currency.
*/
public function set_price( $price ) {
$native_price = $this->compute_native_price( $price );
$this->set_prop( 'price', wc_format_decimal( $native_price ) );
$this->set_prop( 'default_currency_price', wc_format_decimal( $price ) );
}
/**
* Get price.
* It is in base currency for editing.
*
* @param string $context Name of context.
* @return mixed
*/
public function get_price( $context = 'view' ) {
if ( 'edit' === $context ) {
return $this->get_prop( 'default_currency_price', $context );
} else {
return $this->get_prop( 'price', $context );
}
}
/**
* Set the product's regular price.
*
* @param string $price Price in default currency.
*/
public function set_regular_price( $price ) {
$native_price = $this->compute_native_price( $price );
$this->set_prop( 'regular_price', wc_format_decimal( $native_price ) );
$this->set_prop( 'default_currency_regular_price', wc_format_decimal( $price ) );
}
/**
* Get regular price.
* It is in base currency for editing.
*
* @param string $context Name of context.
* @return mixed
*/
public function get_regular_price( $context = 'view' ) {
if ( 'edit' === $context ) {
return $this->get_prop( 'default_currency_regular_price', $context );
} else {
return $this->get_prop( 'regular_price', $context );
}
}
/**
* Set the product's sale price.
*
* @param string $price Price in default currency.
*/
public function set_sale_price( $price ) {
$native_price = $this->compute_native_price( $price );
$this->set_prop( 'sale_price', wc_format_decimal( $native_price ) );
$this->set_prop( 'default_currency_sale_price', wc_format_decimal( $price ) );
}
/**
* Get sale price.
* It is in base currency for editing.
*
* @param string $context Name of context.
* @return mixed
*/
public function get_sale_price( $context = 'view' ) {
if ( 'edit' === $context ) {
return $this->get_prop( 'default_currency_sale_price', $context );
} else {
return $this->get_prop( 'sale_price', $context );
}
}
}

View File

@@ -0,0 +1,43 @@
<?php
/**
* File that define P24_Product_Variable class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The class add to parent awareness of multiple currencies.
*/
class P24_Product_Variable extends WC_Product_Variable {
use P24_Product_Trait;
/**
* P24_Product_Variable constructor.
*
* @param int $product Id of product.
*/
public function __construct( $product = 0 ) {
$this->populate_internal_data();
parent::__construct( $product );
}
/**
* Get an array of all sale and regular prices from all variations.
*
* @param bool $for_display If true, prices will be adapted for display.
* @return array Array of prices.
*/
public function get_variation_prices( $for_display = false ) {
$prices = parent::get_variation_prices( $for_display );
$new_prices = array();
foreach ( $prices as $key => $set ) {
$new_set = array_map( array( $this, 'compute_native_price' ), $set );
$new_prices[ $key ] = $new_set;
}
return $new_prices;
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* File that define P24_Product_Variation class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* The class add to parent awareness of multiple currencies.
*/
class P24_Product_Variation extends WC_Product_Variation {
use P24_Product_Trait;
/**
* P24_Product_Variation constructor.
*
* @param int $product Id of product.
*/
public function __construct( $product = 0 ) {
$this->populate_internal_data();
parent::__construct( $product );
}
}

View File

@@ -0,0 +1,305 @@
<?php
/**
* File that define P24_Request_Support class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class that analyse requests originated from WordPress but WooCommerce.
*
* It supports user mode and admin mode.
* Requests from WooCommerce are supported in different places.
*
* The class interact with $_POST.
*/
class P24_Request_Support {
const WP_JSON_GET_KEY_CURRENCY = 'currency';
const OPTION_KEY_FLAT = 'przelewy24_flat_settings';
const OPTION_KEY_MULTI_CURRENCY_MULTIPLIERS = 'przelewy24_multi_currency_multipliers';
const OPTION_KEY_MULTI_CURRENCY_FORMATS = 'przelewy24_multi_currency_formats';
const OPTION_KEY_COMMON = 'przelewy24_common_settings';
const KEY_CHANGES_CURRENCY = 'currency';
const KEY_NEW_STATUS = 'new_status';
/**
* Set of changes.
*
* @var array
*/
private $changes = array();
/**
* Return changes of active currency.
*
* @return string|null
*/
public function get_currency_changes() {
return ( array_key_exists( self::KEY_CHANGES_CURRENCY, $this->changes ) )
? $this->changes[ self::KEY_CHANGES_CURRENCY ] : null;
}
/**
* Analyse if there is new currency to set.
*
* @param array $data Array of data to analyse.
*/
private function preload_currency_changes( $data ) {
if ( isset( $data['p24_currency'] ) ) {
$this->changes[ self::KEY_CHANGES_CURRENCY ] = $data['p24_currency'];
}
}
/**
* Get changes of format.
*
* @return array|null
*/
public function get_format_changes() {
if ( array_key_exists( 'formats', $this->changes ) ) {
return $this->changes['formats'];
} else {
return null;
}
}
/**
* Analyse if there are new formats to set.
*
* @param array $data Array of data to analyse.
*/
private function preload_format_changes( $data ) {
if ( array_key_exists( 'p24_currency', $data ) && array_key_exists( 'p24_formats', $data ) ) {
$this->changes['formats'] = array( $data['p24_currency'] => $data['p24_formats'] );
}
}
/**
* Get changes of multipliers.
*
* @return array|null
*/
public function get_multipliers_changes() {
if ( array_key_exists( 'p24_multiplers', $this->changes ) ) {
return $this->changes['p24_multiplers'];
} else {
return null;
}
}
/**
* Analyse if there are new multipliers to change.
*
* @param array $data Array of data to analyse.
* @throws LogicException If there is a bug in send data.
*/
private function preload_multipliers_changes( $data ) {
if ( isset( $data['p24_multipliers'] ) ) {
$multipliers = $data['p24_multipliers'];
} else {
$multipliers = array();
}
$default = P24_Woo_Commerce_Low_Level_Getter::get_unhooked_currency_form_woocommerce();
$multipliers[ $default ] = 1;
$multipliers = array_map( 'floatval', $multipliers );
$multipliers = array_filter( $multipliers );
$this->changes['p24_multiplers'] = $multipliers;
}
/**
* Get list of common changes.
*
* @return mixed|null
*/
public function get_common_changes() {
if ( array_key_exists( 'p24_common', $this->changes ) ) {
return $this->changes['p24_common'];
} else {
return null;
}
}
/**
* Get list of flat changes.
*
* @return array
*/
public function get_flat_changes() {
if ( array_key_exists( self::OPTION_KEY_FLAT, $this->changes ) ) {
return $this->changes[ self::OPTION_KEY_FLAT ];
} else {
return array();
}
}
/**
* Get status changes.
*
* @return null|array
*/
public function get_order_status_changes() {
if ( array_key_exists( self::KEY_NEW_STATUS, $this->changes ) ) {
return $this->changes[ self::KEY_NEW_STATUS ];
} else {
return null;
}
}
/**
* Analyse if activation of multi currency is set.
*
* @param array $data Array of data to analyse.
*/
private function preload_multi_currency_changes( $data ) {
$active = array_key_exists( 'p24_multi_currency_active', $data ) && 'yes' === $data['p24_multi_currency_active'] ? 'yes' : 'no';
$this->changes['p24_common']['p24_multi_currency'] = $active;
if ( 'yes' === $active && array_key_exists( 'p24_reports_currency', $data ) ) {
wc_setcookie( 'admin_p24_reports_currency', $data['p24_reports_currency'] );
}
$order_created_notification = array_key_exists( 'p24_notification_order_created', $data ) && 'yes' === $data['p24_notification_order_created'] ? 'yes' : 'no';
$this->changes['p24_common']['p24_notification_order_created'] = $order_created_notification;
}
/**
* Analyse if activation of multi currency is set.
*
* @param array $data Array of data to analyse.
*/
private function preload_activate_statuses( $data ) {
$active = array_key_exists( 'p24_statuses_active', $data ) && $data['p24_statuses_active'];
$value = $active ? 'yes' : 'no';
$this->changes[ self::OPTION_KEY_FLAT ]['p24_statuses_active'] = $value;
}
/**
* Preload add new status.
*
* @param array $data Post data.
*/
private function preload_add_status( $data ) {
if ( isset( $data['p24-status-new-label'] ) && isset( $data['p24-status-new-code'] ) ) {
$this->changes[ self::KEY_NEW_STATUS ] = array(
'code' => $data['p24-status-new-code'],
'label' => $data['p24-status-new-label'],
);
}
}
/**
* Update subscription config.
*
* @param array $data Array of data to analyse.
*/
private function update_subscription_config( $data ) {
$new_keys = P24_Subscription_Config::update_config( $data );
if ( ! array_key_exists( self::OPTION_KEY_FLAT, $this->changes ) ) {
$this->changes[ self::OPTION_KEY_FLAT ] = $new_keys;
} else {
$this->changes[ self::OPTION_KEY_FLAT ] += $new_keys;
}
}
/**
* Process data from GET.
*/
private function check_get() {
wp_verify_nonce( null );
$get = $_GET;
if ( isset( $get['p24_change_currency'] ) ) {
$this->changes[ self::KEY_CHANGES_CURRENCY ] = $get['p24_change_currency'];
}
}
/**
* Validate nonce and return request.
*
* @return null|array
*/
private function get_post_data() {
if ( isset( $_POST['p24_nonce'] ) ) {
$nonce = sanitize_key( $_POST['p24_nonce'] );
if ( wp_verify_nonce( $nonce, 'p24_action' ) ) {
return $_POST;
}
}
return null;
}
/**
* Analyse the whole request.
*
* We need call this action very early.
*/
public function analyse() {
$this->check_get();
$data = $this->get_post_data();
if ( ! $data ) {
return;
}
if ( isset( $data['p24_action_type_field'] ) ) {
$field = $data['p24_action_type_field'];
switch ( $field ) {
case 'change_currency':
$this->preload_currency_changes( $data );
break;
case 'change_formats':
$this->preload_currency_changes( $data );
$this->preload_format_changes( $data );
break;
case 'change_multipliers':
$this->preload_multipliers_changes( $data );
break;
case 'activate_multi_currency':
$this->preload_multi_currency_changes( $data );
break;
case 'activate_statuses':
$this->preload_activate_statuses( $data );
break;
case 'add_status':
$this->preload_add_status( $data );
break;
case 'update_subscription':
$this->update_subscription_config( $data );
break;
}
}
}
/**
* Flush options to the database.
*
* This action should be done later thant analyse.
*/
public function flush_options() {
$set_overwrite = array(
self::OPTION_KEY_MULTI_CURRENCY_MULTIPLIERS => $this->get_multipliers_changes(),
);
$set_merge = array(
self::OPTION_KEY_MULTI_CURRENCY_FORMATS => $this->get_format_changes(),
self::OPTION_KEY_COMMON => $this->get_common_changes(),
);
$set_flat = $this->get_flat_changes();
foreach ( $set_overwrite as $k => $v ) {
if ( $v ) {
update_option( $k, $v );
}
}
foreach ( $set_merge as $k => $v ) {
if ( $v ) {
$v = $v + get_option( $k, array() );
update_option( $k, $v );
}
}
foreach ( $set_flat as $k => $v ) {
if ( $v ) {
update_option( $k, $v );
}
}
}
}

View File

@@ -0,0 +1,223 @@
<?php
/**
* File that define P24_Rest_Server class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Base class for REST API transaction.
*/
class P24_Rest_Server {
/**
* Config factory.
*
* @var callable
*/
protected $config_factory;
/**
* Przelewy24RestAbstract constructor.
*
* @param callable $config_factory Config factory.
*/
public function __construct( $config_factory ) {
$this->config_factory = $config_factory;
}
/**
* Support REST api.
*/
public function support_status() {
$status_payload = $this->get_json_from_body();
$cf = $this->get_config( $status_payload['currency'] );
$reg_session = '/^[0-9a-zA-Z_\.]+$/D';
if ( ! preg_match( $reg_session, $status_payload['sessionId'] ) ) {
return;
}
$session_id = explode( '_', $status_payload['sessionId'] );
$order_id = $session_id[0];
$order = new WC_Order( $order_id );
$verified = $this->verify( $order, $status_payload, $cf );
if ( $verified ) {
/* This value mey be not set yet. */
$order->update_meta_data( P24_Core::ORDER_P24_ID, $status_payload['orderId'] );
$verified = $this->external_verify( $order, $status_payload, $cf );
}
if ( ! $verified ) {
http_response_code( 400 );
$answer = wp_json_encode( array( 'success' => false ) );
exit( esc_js( "\n" . $answer ) );
} else {
$order->add_order_note( __( 'IPN payment completed', 'woocommerce' ) );
$order->payment_complete();
if ( (int) $status_payload['methodId'] ) {
$user_id = $order->get_user_id();
$method_id = (int) $status_payload['methodId'];
Przelewy24Helpers::setCustomData( 'user', $user_id, 'lastmethod', $method_id );
Przelewy24Helpers::setCustomData( 'user', $user_id, 'accept', 1 );
$this->save_reference_id( $status_payload['orderId'], $status_payload['methodId'], $user_id, $cf );
}
$order->update_meta_data( P24_Core::ORDER_SESSION_ID_KEY, $status_payload['sessionId'] );
$order->save_meta_data();
do_action( 'p24_payment_complete', $order, null );
}
$answer = wp_json_encode( array( 'success' => true ) );
exit( esc_js( "\n" . $answer ) );
}
/**
* Save card id reference number (to allow one click payments).
*
* @param int $order_id P24 order id.
* @param int $method_id Method id (in p24).
* @param int $user_id Id of order owner.
* @param P24_Config_Accessor $cf Plugin configuration.
*/
public function save_reference_id( $order_id, $method_id, $user_id, $cf ) {
if ( ! in_array( (int) $method_id, Przelewy24Class::getChannelsCard(), true ) ) {
return;
}
if ( WC_Gateway_Przelewy24::get_cc_forget( $user_id ) ) {
return;
}
if ( ! $cf->get_p24_payinshop() || ! $cf->get_p24_oneclick() ) {
return;
}
$api_rest_card = new P24_Rest_Card( $cf );
$res = $api_rest_card->info( $order_id );
if ( ! isset( $res['data']['refId'] ) ) {
error_log( __METHOD__ . ' brak numeru referencyjnego karty użytkownika' );
return;
}
$ref = $res['data']['refId'];
$expires = substr( $res['data']['cardDate'], 2 ) . substr( $res['data']['cardDate'], 0, 2 );
if ( date( 'Ym' ) > $expires ) {
error_log( __METHOD__ . ' termin ważności ' . var_export( $expires, true ) );
return;
}
$key = md5( $res['data']['mask'] . '|' . $res['data']['cardType'] . '|' . substr( $expires, 2 ) );
Przelewy24Helpers::setCustomData(
'user_cards',
$user_id,
$key,
array(
'ref' => $ref,
'exp' => substr( $expires, 2 ),
'mask' => $res['data']['mask'],
'type' => $res['data']['cardType'],
'time' => date( 'Y-m-d H:i.s' ),
)
);
}
/**
* Verify payload.
*
* @param WC_Order $order Order.
* @param array $payload Payload.
* @param P24_Config_Accessor $config Config accessor.
* @return bool
*/
private function verify( $order, $payload, $config ) {
$total_amount = number_format( $order->get_total() * 100, 0, '', '' );
$saved_p24_order_id = $order->get_meta( P24_Core::ORDER_P24_ID );
if ( $payload['merchantId'] !== (int) $config->get_merchant_id() ) {
return false;
} elseif ( $payload['posId'] !== (int) $config->get_shop_id() ) {
return false;
} elseif ( (string) $payload['amount'] !== $total_amount ) {
return false;
} elseif ( $payload['currency'] !== $config->get_currency() ) {
return false;
} elseif ( $saved_p24_order_id && (int) $saved_p24_order_id !== (int) $payload['orderId'] ) {
return false;
} elseif ( $this->sign( $payload, $config ) !== $payload['sign'] ) {
return false;
}
return true;
}
/**
* External_verify.
*
* @param WC_Order $order Order.
* @param array $data Additional data.
* @param P24_Config_Accessor $config Config accessor.
*
* @return bool
*/
private function external_verify( $order, $data, $config ) {
$rest_transaction = new P24_Rest_Transaction( $config );
$payload = array(
'merchantId' => (int) $config->get_merchant_id(),
'posId' => (int) $config->get_shop_id(),
'sessionId' => $data['sessionId'],
'amount' => (int) number_format( $order->get_total() * 100, 0, '', '' ),
'currency' => $config->get_currency(),
'orderId' => (int) $order->get_meta( P24_Core::ORDER_P24_ID ),
);
return $rest_transaction->verify_bool( $payload );
}
/**
* Sign
*
* @param array $payload Payload.
* @param P24_Config_Accessor $config Config accessor.
* @return string
*/
private function sign( $payload, $config ) {
unset( $payload['sign'] );
$payload['crc'] = $config->get_salt();
$string = wp_json_encode( $payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
$sign = hash( 'sha384', $string );
return $sign;
}
/**
* Get JSON from body.
*
* @return array
*/
private function get_json_from_body() {
$body = file_get_contents( 'php://input' );
$json = json_decode( $body, true );
if ( ! is_array( $json ) ) {
$json = (array) $json;
}
return $json;
}
/**
* Get_config.
*
* @param string|null $currency Currency.
* @return P24_Config_Accessor Config accessor.
*/
private function get_config( $currency = null ) {
$factory = $this->config_factory;
$cf = $factory( $currency );
$cf->access_mode_to_strict();
return $cf;
}
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* File that define P24_Settings_Helper.
*
* @package Przelewy24
*/
/**
* Helper to access config.
*
* There is some legacy code for this purpose in WC_Gateway_Przelewy24 too.
*/
class P24_Settings_Helper {
const OPTION_KEY_COMMON = 'przelewy24_common_settings';
const OPTION_KEY_CURRENCY_TEMPLATE = 'woocommerce_przelewy24_%s_settings';
/**
* Convert common arrays to config holder.
*
* @param array $array The config as array.
* @return P24_Config_Holder
*/
public static function map_array_to_config_holder( $array ) {
$config_holder = new P24_Config_Holder();
foreach ( $array as $k => $v ) {
if ( property_exists( $config_holder, $k ) ) {
$config_holder->{$k} = $v;
} elseif ( 'CRC_key' === $k ) {
$config_holder->salt = $v;
} elseif ( 'p24_testmod' === $k ) {
$config_holder->p24_operation_mode = $v;
}
}
return $config_holder;
}
/**
* Get config for currency in object.
*
* @param string $currency The currency.
* @return P24_Config_Accessor|null
*/
public static function load_settings( $currency ) {
$common_options = get_option( self::OPTION_KEY_COMMON, array() );
if ( ! array_key_exists( 'enabled', $common_options ) ) {
return null;
} elseif ( 'yes' !== $common_options['enabled'] ) {
return null;
}
$key = sprintf( self::OPTION_KEY_CURRENCY_TEMPLATE, $currency );
$array = get_option( $key, array() );
$config_holder = self::map_array_to_config_holder( $array );
return new P24_Config_Accessor( $currency, $config_holder );
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* File that define P24_Status_Decorator_Db class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class to help decorate statuses with access to a database.
*/
class P24_Status_Decorator_Db {
/**
* Escape strings in array and make it in comma separated list.
*
* @param array $input Array of string.
* @return string
*/
private static function implode_strings( $input ) {
$mapper = function ( $in ) {
return "'" . esc_sql( $in ) . "'";
};
$mapped = array_map( $mapper, $input );
return implode( ', ', $mapped );
}
/**
* Cancel unpaid orders that has custom Przelewy24 status.
*
* @param string $pending_status Status for pending Przelewy24 payments.
*/
public static function cancel_unpaid_p24_orders( $pending_status ) {
$held_duration = (int) get_option( P24_Woo_Commerce_Internals::HOLD_STOCK_MINUTES );
/* We have to copy these two conditions from wc_cancel_unpaid_orders function. */
if ( $held_duration < 1 || 'yes' !== get_option( P24_Woo_Commerce_Internals::MANAGE_STOCK ) ) {
return;
}
$date = new DateTime( $held_duration . ' minutes ago', wp_timezone() );
$escaped_post_types = self::implode_strings( wc_get_order_types() );
/*
* The code below is formatted after WC_Order_Data_Store_CPT::get_unpaid_orders.
* It is not possible to make it follow standards.
*/
// @codingStandardsIgnoreStart
global $wpdb;
$unpaid_orders = $wpdb->get_col(
$wpdb->prepare(
"SELECT posts.ID
FROM {$wpdb->posts} AS posts
WHERE posts.post_type IN ({$escaped_post_types})
AND posts.post_status = '%s'
AND posts.post_modified < %s",
$pending_status,
$date->format( 'Y-m-d H:i:s' )
)
);
// @codingStandardsIgnoreEnd
/* The code fragment below is copied from wc_cancel_unpaid_orders function. */
if ( $unpaid_orders ) {
foreach ( $unpaid_orders as $unpaid_order ) {
$order = wc_get_order( $unpaid_order );
if ( apply_filters( 'woocommerce_cancel_unpaid_order', 'checkout' === $order->get_created_via(), $order ) ) {
$order->update_status( 'cancelled', __( 'Unpaid order cancelled - time limit reached.', 'woocommerce' ) );
}
}
}
}
}

View File

@@ -0,0 +1,510 @@
<?php
/**
* File that define P24_Status_Decorator class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class to decorate order statuses.
*/
class P24_Status_Decorator {
/**
* Suffix to use for status for the database.
* The length is very limited.
*/
const STATUS_SUFFIX = '-p24';
/**
* Suffix to use for status for humans.
*/
const STATUS_SUFFIX_HUMAN = ' P24';
/**
* Config factory.
*
* @var callable
*/
private $config_factory;
/**
* In_decoration_mode.
*
* @var bool
*/
private $in_decoration_mode = false;
/**
* Status provider.
*
* @var P24_Status_Provider
*/
private $status_provider;
/**
* Core of this plugin.
*
* @var P24_Core
*/
private $plugin_core;
/**
* P24_Status_Decorator constructor.
*
* @param callable $config_factory The config factory.
* @param P24_Status_Provider $status_provider Status provider.
* @param P24_Core $plugin_core Core of this plugin.
*/
public function __construct( $config_factory, $status_provider, $plugin_core ) {
$this->config_factory = $config_factory;
$this->status_provider = $status_provider;
$this->plugin_core = $plugin_core;
}
/**
* Get config in strict mode.
*
* @param string $currency The currency.
* @return P24_Config_Accessor
* @throws LogicException Should be not thrown in normal operation.
*/
private function get_config( $currency ) {
/* It may be not initialized. */
if ( is_callable( $this->config_factory ) ) {
$config_factory = $this->config_factory;
$config = $config_factory( $currency );
} else {
$config = P24_Settings_Helper::load_settings( $currency );
}
if ( ! $config ) {
throw new LogicException( 'Cannot load config for provided currency.' );
}
$config->access_mode_to_strict();
return $config;
}
/**
* Set decoration mode.
*
* @param bool $mode Desired mode of decorator.
* @param string $currency Currency.
* @return bool
*/
public function try_set_decoration_mode( $mode, $currency ) {
$config_accessor = $this->get_config( $currency );
if ( $mode && $config_accessor->get_p24_use_special_status() ) {
$this->in_decoration_mode = true;
} else {
$this->in_decoration_mode = false;
}
return $this->in_decoration_mode;
}
/**
* Check if code is in edit mode of order.
*
* @return bool
*/
private function check_if_in_edit_mode() {
global $typenow;
global $editing;
return 'shop_order' === $typenow && $editing;
}
/**
* Check if from Przelewy24.
*
* @param WC_Order $order The order from client.
*/
private function check_if_from_przelewy24( $order ) {
/* We have to support two types of gateways: main and extra. */
$rx = '/^przelewy24(\_extra\_\d+)?$/';
$method = $order->get_payment_method();
return preg_match( $rx, $method );
}
/**
* Add pending status.
*
* @param WC_Order $order The order.
* @param array $data Additional order data.
*/
public function try_set_custom_pending_status( $order, $data ) {
if ( $this->check_if_from_przelewy24( $order ) ) {
$config_accessor = $this->get_config( $order->get_currency() );
if ( $config_accessor->get_p24_use_special_status() ) {
$custom_pending_status = $config_accessor->get_p24_custom_pending_status();
if ( $custom_pending_status ) {
$order->set_status( $custom_pending_status );
} else {
$order->set_status( 'pending' . self::STATUS_SUFFIX );
}
}
}
}
/**
* Decorate order status.
*
* @param string $status Proposed new status for order.
* @param int $order_id Order id.
* @param WC_Order $order Order object.
*/
public function try_set_custom_processing_status( $status, $order_id, $order ) {
if ( $this->in_decoration_mode ) {
if ( 'processing' === $status ) {
$config_accessor = $this->get_config( $order->get_currency() );
$custom_processing_status = $config_accessor->get_p24_custom_processing_status();
if ( $custom_processing_status ) {
return $custom_processing_status;
} else {
return $status . self::STATUS_SUFFIX;
}
}
}
return $status;
}
/**
* Add valid statuses.
*
* @param array $statuses Default WooCommerce statuses.
* @return array
*/
public function add_valid_statuses( $statuses ) {
/*
* We have to add status with and without wc- prefix. There is a mess in WooCommerce code.
* There is an exception from this rule though.
*/
if ( ! $this->check_if_in_edit_mode() ) {
$statuses[ 'pending' . self::STATUS_SUFFIX ] = $statuses['wc-pending'] . self::STATUS_SUFFIX_HUMAN;
/* WooCommerce standards force us to use raw literals. */
$statuses[ 'processing' . self::STATUS_SUFFIX ] = __( 'Opłacone przez P24', 'przelewy24' );
$statuses += $this->status_provider->get_additional_valid_statuses( '' );
}
$statuses[ 'wc-pending' . self::STATUS_SUFFIX ] = $statuses['wc-pending'] . self::STATUS_SUFFIX_HUMAN;
/* WooCommerce standards force us to use raw literals. */
$statuses[ 'wc-processing' . self::STATUS_SUFFIX ] = __( 'Opłacone przez P24', 'przelewy24' );
$statuses += $this->status_provider->get_additional_valid_statuses( 'wc-' );
return $statuses;
}
/**
* Add valid statuses for unpaid.
*
* @param array $defaults Default unpaid statuses.
* @param WC_Order $order Order.
* @return array
*/
public function add_valid_for_unpaid( $defaults, $order ) {
if ( ! $this->check_if_from_przelewy24( $order ) ) {
return $defaults;
} else {
$defaults[] = 'pending' . self::STATUS_SUFFIX;
$config_accessor = $this->get_config( $order->get_currency() );
$defaults[] = $config_accessor->get_p24_custom_pending_status();
}
return $defaults;
}
/**
* Add valid status to change from.
*
* @param array $defaults Default WooCommerce statuses.
* @return array
*/
public function add_valid_for_from( $defaults ) {
$defaults[] = 'pending' . self::STATUS_SUFFIX;
$defaults[] = 'processing' . self::STATUS_SUFFIX;
$additional = $this->status_provider->get_additional_valid_statuse_codes( '' );
$defaults = array_merge( $defaults, $additional );
/* We have to add status with and without wc- prefix. There is a mess in WooCommerce code. */
$defaults[] = 'wc-pending' . self::STATUS_SUFFIX;
$defaults[] = 'wc-processing' . self::STATUS_SUFFIX;
$additional = $this->status_provider->get_additional_valid_statuse_codes( 'wc-' );
$defaults = array_merge( $defaults, $additional );
return $defaults;
}
/**
* Fix statuses in args.
*
* @param array $default Default args.
* @param array $extra Extra data.
* @return array
*/
public function fix_statuses_in_args( $default, $extra ) {
/* Used on my orders list. */
$ret = $default;
if ( isset( $default['post_status'] ) && is_array( $default['post_status'] ) ) {
$statuses = $default['post_status'];
$custom_statuses = $this->status_provider->get_additional_valid_statuse_codes( '' );
$custom_statuses[] = 'pending' . self::STATUS_SUFFIX;
$custom_statuses[] = 'processing' . self::STATUS_SUFFIX;
foreach ( $statuses as $wk => $wv ) {
if ( preg_match( '/^wc-(.+)/', $wv, $m ) ) {
$ck = array_search( $m[1], $custom_statuses, true );
if ( false !== $ck ) {
/* There is a mess in WooCommerce code. Fix one of it. */
$ret['post_status'][ $wk ] = $custom_statuses[ $ck ];
}
}
}
}
return $ret;
}
/**
* Add valid status to change to.
*
* @param array $defaults Default WooCommerce statuses.
* @return array
*/
public function add_valid_for_to( $defaults ) {
if ( $this->in_decoration_mode ) {
$defaults[] = 'pending' . self::STATUS_SUFFIX;
$defaults[] = 'processing' . self::STATUS_SUFFIX;
$additional = $this->status_provider->get_additional_valid_statuse_codes( '' );
$defaults = array_merge( $defaults, $additional );
}
return $defaults;
}
/**
* Add description for status.
*
* @param array $defaults Default WooCommerce statuses.
* @return array
*/
public function add_all_status_descriptions( $defaults ) {
$defaults[ 'pending' . self::STATUS_SUFFIX ] = $this->prep_status_description( $defaults, 'wc-pending' );
$defaults[ 'processing' . self::STATUS_SUFFIX ] = $this->prep_status_description( $defaults, 'wc-processing' );
$defaults += $this->status_provider->status_description_list( $defaults );
return $defaults;
}
/**
* Prep status description.
*
* @param array $defaults Default statuses.
* @param string $base_key The code for base status.
* @return array
*/
public function prep_status_description( array $defaults, $base_key ): array {
$new = $defaults[ $base_key ];
if ( P24_Woo_Commerce_Internals::PROCESSING_STATUS === $base_key ) {
/* WooCommerce standards force us to use raw literals. */
$new['label'] = __( 'Opłacone przez P24', 'przelewy24' );
} else {
$new['label'] = $new['label'] . self::STATUS_SUFFIX_HUMAN;
}
$rx = '/([^\\<]+)(\\<.*)/';
$new_label_count = array();
foreach ( $new['label_count'] as $k => $v ) {
if ( is_string( $v ) && preg_match( $rx, $v, $m ) ) {
$new_label_count[ $k ] = $m[1] . self::STATUS_SUFFIX_HUMAN . ' ' . $m[2];
} else {
$new_label_count[ $k ] = $v;
}
}
$new['label_count'] = $new_label_count;
return $new;
}
/**
* Super translation.
*
* @param string $translation Proposed translation.
* @param string $single Proposed translation for single.
* @param string $plural Proposed translation for plural.
* @param int $number Number of items.
* @param string $domain Domain of translation.
* @return mixed|string
*/
public function super_translation( $translation, $single, $plural, $number, $domain ) {
if ( P24_Woo_Commerce_Internals::TRANSLATION_DOMAIN !== $domain ) {
return $translation;
}
$suffix = preg_quote( self::STATUS_SUFFIX_HUMAN, '/' );
$rx = '/([^\\<]+)' . $suffix . ' (\\<.*)/';
if ( preg_match( $rx, $translation, $m ) ) {
$filtered = $m[1] . $m[2];
if ( P24_Woo_Commerce_Strings::PENDING_PAYMENT_WITH_COUNT === $filtered ) {
/* WooCommerce standards force us to use raw literals, special comments and blank lines below. */
/* translators: %s number of orders. */
$raw = _n( 'Pending payment <span class="count">(%s)</span>', 'Pending payment <span class="count">(%s)</span>', $number, 'woocommerce' );
$rx = '/([^\\<]+)(\\<.*)/';
if ( preg_match( $rx, $raw, $m ) ) {
$translation = $m[1] . self::STATUS_SUFFIX_HUMAN . ' ' . $m[2];
}
} elseif ( P24_Woo_Commerce_Strings::PROCESSING_PAYMENT_WITH_COUNT === $filtered ) {
/* WooCommerce standards force us to use raw literals, special comments and blank lines below. */
/* translators: %s number of orders. */
$translation = __( 'Opłacone przez P24 <span class="count">(%s)</span>', 'przelewy24' );
}
}
return $translation;
}
/**
* Signal internal status changes.
*
* @param int $order_id Order id.
* @param string $from Existing status.
* @param string $to Proposed status.
* @param WC_Order $order The order.
*/
public function signal_more_status_changes( $order_id, $from, $to, $order ) {
$need_action = false;
$internal_from = $from;
$internal_to = $to;
$config_accessor = $this->get_config( $order->get_currency() );
$statuses = array(
'pending' . self::STATUS_SUFFIX => 'pending',
'processing' . self::STATUS_SUFFIX => 'processing',
$config_accessor->get_p24_custom_pending_status() => 'pending',
$config_accessor->get_p24_custom_processing_status() => 'processing',
);
foreach ( $statuses as $status => $internal ) {
if ( $from === $status ) {
$internal_from = $internal;
$need_action = true;
}
if ( $to === $status ) {
$internal_to = $internal;
$need_action = true;
}
}
if ( $need_action ) {
do_action( 'woocommerce_order_status_' . $internal_from . '_to_' . $internal_to, $order_id, $order );
do_action( 'woocommerce_order_status_changed', $order_id, $internal_from, $internal_to, $order );
if ( $internal_to !== $to ) {
do_action( 'woocommerce_order_status_' . $internal_to, $order_id, $order );
}
}
}
/**
* Check need of payment.
*
* @param bool $default Default need.
* @param WC_Order $order The order.
* @param array $statuses List of statuses.
* @return bool
*/
public function check_need_of_payment( $default, $order, $statuses ) {
if ( ! $this->check_if_from_przelewy24( $order ) ) {
return $default;
} elseif ( $default ) {
$status = $order->get_status();
$suffixed_paid_statuses = array(
'processing' . self::STATUS_SUFFIX,
'wc-processing' . self::STATUS_SUFFIX,
);
if ( in_array( $status, $suffixed_paid_statuses, true ) ) {
return false;
} else {
$config_accessor = $this->get_config( $order->get_currency() );
/* As long it is not precessing, we are fine. */
return $config_accessor->get_p24_custom_processing_status() !== $status;
}
} else {
return false;
}
}
/**
* Validate statuses.
*
* It should be safe as long as they are different.
*
* @param string $pending Code for status penging.
* @param string $processing Code for status processing.
* @return bool
*/
public static function validate_statuses( $pending, $processing ) {
if ( $pending ) {
$pending = (string) $pending;
} else {
$pending = 'pending' . self::STATUS_SUFFIX;
}
if ( $processing ) {
$processing = (string) $processing;
} else {
$processing = 'processing' . self::STATUS_SUFFIX;
}
return $processing !== $pending;
}
/**
* Check if module for statuses is active.
*
* @return bool
*/
public static function is_active() {
$status = get_option( 'p24_statuses_active', 'no' );
return 'yes' === $status;
}
/**
* Cancel unpaid orders that has custom Przelewy24 status.
*/
public function cancel_unpaid_p24_orders() {
$currencies = $this->plugin_core->get_available_currencies_or_default();
foreach ( $currencies as $currency ) {
$config = $this->get_config( $currency );
$pending_status = $config->get_p24_custom_pending_status();
if ( ! $pending_status ) {
$pending_status = 'pending' . self::STATUS_SUFFIX;
}
P24_Status_Decorator_Db::cancel_unpaid_p24_orders( $pending_status );
}
}
/**
* Bind events.
*/
public function bind_events() {
if ( ! self::is_active() ) {
/* Nothing to bind. */
return;
}
add_action( 'woocommerce_cancel_unpaid_orders', array( $this, 'cancel_unpaid_p24_orders' ) );
add_action( 'woocommerce_checkout_create_order', array( $this, 'try_set_custom_pending_status' ), 10, 2 );
add_action( 'woocommerce_order_status_changed', array( $this, 'signal_more_status_changes' ), 5, 4 );
add_filter( 'woocommerce_payment_complete_order_status', array( $this, 'try_set_custom_processing_status' ), 10, 3 );
add_filter( 'woocommerce_valid_order_statuses_for_payment_complete', array( $this, 'add_valid_for_unpaid' ), 10, 2 );
add_filter( 'woocommerce_valid_order_statuses_for_payment', array( $this, 'add_valid_for_from' ) );
add_filter( 'woocommerce_order_is_paid_statuses', array( $this, 'add_valid_for_to' ) );
add_filter( 'woocommerce_register_shop_order_post_statuses', array( $this, 'add_all_status_descriptions' ) );
add_filter( 'wc_order_statuses', array( $this, 'add_valid_statuses' ) );
add_filter( 'woocommerce_get_wp_query_args', array( $this, 'fix_statuses_in_args' ), 10, 2 );
add_filter( 'woocommerce_order_needs_payment', array( $this, 'check_need_of_payment' ), 10, 3 );
add_filter( 'ngettext_woocommerce', array( $this, 'super_translation' ), 10, 5 );
}
}

View File

@@ -0,0 +1,231 @@
<?php
/**
* File that define P24_Status_Decorator class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class to add additional order statuses.
*/
class P24_Status_Provider {
const ADDITIONAL_STATUSES_KEY = 'woocommerce_przelewy24_additional_statuses';
/**
* Adding_error.
*
* @var string|null
*/
private $adding_error;
/**
* Proposed_values.
*
* @var array|null
*/
private $proposed_values;
/**
* Get config for internal use.
*
* @return array
*/
private static function get_config() {
$data = get_option( self::ADDITIONAL_STATUSES_KEY );
if ( $data && is_array( $data ) ) {
return $data;
} else {
return array();
}
}
/**
* Get formatted config.
*
* @return array
*/
public static function get_formatted_config() {
$data = self::get_config();
$ret = array();
foreach ( $data as $one ) {
if ( isset( $one['code'] ) && isset( $one['label'] ) ) {
$ret[] = $one;
}
}
return $ret;
}
/**
* Get config for select.
*
* @param string $base_status Base status.
* @return array
*/
public static function get_config_for_select( $base_status ) {
/* The _x function do not accept variables. We have to use this switch. */
switch ( $base_status ) {
case 'Pending payment':
$default = _x( 'Pending payment', 'Order status', 'woocommerce' );
break;
case 'Processing':
$default = _x( 'Processing', 'Order status', 'woocommerce' );
break;
default:
$default = 'No translation for ' . $base_status;
}
$data = self::get_formatted_config();
$ret = array(
'' => $default,
);
foreach ( $data as $one ) {
$ret[ $one['code'] ] = $one['label'];
}
return $ret;
}
/**
* Try add new status.
*
* @param array $status New array with status.
*/
public function try_add_new( $status ) {
if ( ! $status ) {
$this->adding_error = null;
} elseif ( ! $status['code'] || ! $status['label'] ) {
/* Someone has hand crafted request. No need for better description. */
$this->adding_error = __( 'Błąd przy dodawaniu nowego statusu.' );
$this->proposed_values = $status;
} elseif ( preg_match( '/^wc-/', $status['code'] ) ) {
$this->adding_error = __( 'Prefiks wc- dla kodu jest niedozwolony.' );
$this->proposed_values = $status;
} elseif ( ! preg_match( '/^[a-z\\-]+$/', $status['code'] ) ) {
$this->adding_error = __( 'Kod powinien składać się tylko z małych liter, bez znaków diakrytycznych.' );
$this->proposed_values = $status;
} elseif ( preg_match( '/^pending|processing|on-hold|completed|cancelled|refunded|failed$/', $status['code'] ) ) {
$this->adding_error = __( 'Kod jest używany wewnętrznie przez WooCommerce, nie można go użyć.' );
$this->proposed_values = $status;
} else {
$data = self::get_formatted_config();
$data[] = $status;
update_option( self::ADDITIONAL_STATUSES_KEY, $data );
}
}
/**
* Get additional valid statuses.
*
* @param string $prefix Optional prefix.
* @return array
*/
public function get_additional_valid_statuses( $prefix ) {
$statuses = array();
$data = $this->get_config();
foreach ( $data as $one ) {
if ( ! isset( $one['code'] ) || ! isset( $one['label'] ) ) {
continue;
}
$statuses[ $prefix . $one['code'] ] = $one['label'];
}
return $statuses;
}
/**
* Get additional valid statuse codes.
*
* @param string $prefix Optional prefix.
* @return array
*/
public function get_additional_valid_statuse_codes( $prefix ) {
$full = $this->get_additional_valid_statuses( $prefix );
return array_keys( $full );
}
/**
* Add description for status.
*
* @param array $defaults Default WooCommerce statuses.
* @return array
*/
public function status_description_list( $defaults ) {
$new = array();
$data = $this->get_config();
foreach ( $data as $one ) {
if ( ! isset( $one['code'] ) || ! isset( $one['label'] ) ) {
continue;
}
$new[ $one['code'] ] = $this->status_description( $one, $defaults );
}
return $new;
}
/**
* Prep_status_description.
*
* @param array $one One record from P24 status config.
* @param array $defaults Default sttuses.
* @return array
*/
public function status_description( $one, $defaults ) {
$new = $defaults['wc-processing'];
$new['label'] = $one['label'];
$rx = '/[^\\<]+(\\<.*)/';
$new_label_count = array();
foreach ( $new['label_count'] as $k => $v ) {
if ( is_string( $v ) && preg_match( $rx, $v, $m ) ) {
$new_label_count[ $k ] = $one['label'] . ' ' . $m[1];
} else {
$new_label_count[ $k ] = $v;
}
}
$new['label_count'] = $new_label_count;
return $new;
}
/**
* Get adding error.
*
* @return string
*/
public function get_adding_error() {
return (string) $this->adding_error;
}
/**
* Get proposed code if error.
*
* @return string
*/
public function get_proposed_code_if_error() {
if ( $this->adding_error ) {
return $this->proposed_values['code'];
} else {
return '';
}
}
/**
* Get proposed label if error.
*
* @return string
*/
public function get_proposed_label_if_error() {
if ( $this->adding_error ) {
return $this->proposed_values['label'];
} else {
return '';
}
}
}

View File

@@ -0,0 +1,118 @@
<?php
/**
* File that define P24_Sub_Generator.
*
* @package Przelewy24
*/
/**
* Class tat generate data to generate orders.
*
* It has some interaction with WC_Gateway_Przelewy24 .
*/
class P24_Sub_Generator {
/**
* Find_saved_card.
*
* @param string $key Kay of card, it is not reference id for Przelewy24.
* @param int $user_id User id.
* @return array|null
*/
public static function find_saved_card( $key, $user_id ) {
$cards = WC_Gateway_Przelewy24::get_all_cards( $user_id );
foreach ( $cards as $card ) {
if ( $card->custom_key === $key ) {
return $card->custom_value;
}
}
return null;
}
/**
* Generate order description.
*
* @param WC_Order $order The existing order.
*/
public static function generate_order_description( $order ) {
$currency = $order->get_currency();
$config = P24_Settings_Helper::load_settings( $currency );
$config->access_mode_to_strict();
$description_order_id = $order->get_order_number();
/* Modifies order number if Sequential Order Numbers Pro plugin is installed. */
if ( class_exists( 'WC_Seq_Order_Number_Pro' ) ) {
$seq = new WC_Seq_Order_Number_Pro();
$description_order_id = $seq->get_order_number( $description_order_id, $order );
} elseif ( class_exists( 'WC_Seq_Order_Number' ) ) {
$seq = new WC_Seq_Order_Number();
$description_order_id = $seq->get_order_number( $description_order_id, $order );
}
$now = new DateTime();
$short_date = $now->format( 'Ymdhi' );
/* Description depends on operation mode. */
$prefix = $config->is_p24_operation_mode( 'sandbox' ) ? __( 'Transakcja testowa', 'przelewy24' ) . ', ' : '';
$suffix = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() . ', ' . $short_date;
$desc = $prefix . __( 'Zamówienie nr', 'przelewy24' ) . ': ' . $description_order_id . ', ' . $suffix;
return $desc;
}
/**
* Generate payload for REST transaction.
*
* @param WC_Order $order The existing order.
* @return array|null
*/
public static function generate_payload_for_rest( $order ) {
$currency = $order->get_currency();
$config = P24_Settings_Helper::load_settings( $currency );
if ( ! $config ) {
return null;
}
/* We need a plain integer to generate session id. */
$order_id = (int) $order->get_id();
if ( ! $order_id ) {
return null;
}
$amount = (int) round( $order->get_total() * 100 );
$shipping = (int) round( $order->get_shipping_total() * 100 );
$session_id = addslashes( $order_id . '_' . uniqid( md5( wp_rand() ), true ) );
$status_page = add_query_arg(
array(
'wc-api' => 'WC_Gateway_Przelewy24',
'status' => 'REST',
),
home_url( '/' )
);
$return_page = WC_Gateway_Przelewy24::getReturnUrlStatic( $order );
global $locale;
$localization = ! empty( $locale ) ? explode( '_', $locale ) : 'pl';
return array(
'merchantId' => (int) $config->get_merchant_id(),
'posId' => (int) $config->get_shop_id(),
'sessionId' => $session_id,
'amount' => $amount,
'currency' => $currency,
'description' => self::generate_order_description( $order ),
'email' => filter_var( $order->get_billing_email(), FILTER_SANITIZE_EMAIL ),
'client' => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
'address' => $order->get_billing_address_1(),
'zip' => $order->get_billing_postcode(),
'city' => $order->get_billing_city(),
'country' => $order->get_billing_country(),
'language' => filter_var( $localization[0], FILTER_SANITIZE_STRING ),
'urlReturn' => filter_var( $return_page, FILTER_SANITIZE_URL ),
'urlStatus' => filter_var( $status_page, FILTER_SANITIZE_URL ),
'shipping' => $shipping,
'encoding' => 'UTF-8',
);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* File that define P24_Woo_Commerce_Internals class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class that defines few constants used by Woo Commerce.
*/
class P24_Woo_Commerce_Internals {
const CURRENCY = 'woocommerce_currency';
const CURRENCY_POS = 'woocommerce_currency_pos';
const HOLD_STOCK_MINUTES = 'woocommerce_hold_stock_minutes';
const MANAGE_STOCK = 'woocommerce_manage_stock';
const PRICE_THOUSAND_SEP = 'woocommerce_price_thousand_sep';
const PRICE_DECIMAL_SEP = 'woocommerce_price_decimal_sep';
const PRICE_NUM_DECIMALS = 'woocommerce_price_num_decimals';
const PROCESSING_STATUS = 'wc-processing';
const TRANSLATION_DOMAIN = 'woocommerce';
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* File that define P24_Woo_Commerce_Low_Level_Getter class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class that let access low level variables of Woo Commerce.
*
* It should be used with caution.
*/
class P24_Woo_Commerce_Low_Level_Getter
{
/**
* Get currency from configuration of Woo Commerce.
*
* Try to bypass as many Woo Commerce hooks as possible.
*
* @return string
*/
public static function get_unhooked_currency_form_woocommerce() {
return (string) get_option( P24_Woo_Commerce_Internals::CURRENCY );
}
}

View File

@@ -0,0 +1,18 @@
<?php
/**
* File that define P24_Woo_Commerce_Strings class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class that defines few strings used by Woo Commerce.
*/
class P24_Woo_Commerce_Strings {
const PENDING_PAYMENT_WITH_COUNT = 'Pending payment <span class="count">(%s)</span>';
const PROCESSING_PAYMENT_WITH_COUNT = 'Processing <span class="count">(%s)</span>';
}

View File

@@ -0,0 +1,350 @@
<?php
/**
* Przelewy24 comunication class
*
* @author Przelewy24 Sp. z o.o.
* @copyright DialCom24 Sp. z o.o.
* @version 1.1
* @since 2014-04-29
*/
/**
*
* Communication protol version
* @var double
*/
define('P24_VERSION', '3.2');
if (class_exists('Przelewy24Class', false)!=true) {
class Przelewy24Class {
/**
* Config.
* @var P24_Config_Accessor
*/
private $config;
/**
* Live system URL address
* @var string
*/
private static $hostLive = 'https://secure.przelewy24.pl/';
/**
* Sandbox system URL address
* @var string
*/
private static $hostSandbox = 'https://sandbox.przelewy24.pl/';
/**
* Use Live (false) or Sandbox (true) enviroment
* @var bool
*/
private $testMode = false;
/**
* Merchant Id
* @var int
*/
private $merchantId = 0;
/**
* Merchant posId
* @var int
*/
private $posId = 0;
/**
* API Key (from P24 panel)
* @var string
*/
private $api = '';
/**
* Array of POST data
* @var array
*/
private $postData = array();
/**
* The class to validate messages.
*
* @var P24_Message_Validator
*/
private $message_validator;
/**
* Przelewy24Class constructor.
* @param P24_Config_Accessor $config
*/
public function __construct( P24_Config_Accessor $config ) {
$this->config = clone $config;
$this->config->access_mode_to_strict();
#TODO Refactor this out.
$this->message_validator = new P24_Message_Validator();
$config->access_mode_to_strict();
$this->posId = (int) trim( $this->config->get_shop_id() );
$this->merchantId = (int) trim( $this->config->get_merchant_id() );
if ($this->merchantId === 0) {
$this->merchantId = $this->posId;
}
$this->testMode = $this->config->is_p24_operation_mode( 'sandbox' );
$this->addValue('p24_merchant_id', $this->merchantId);
$this->addValue('p24_pos_id', $this->posId);
$this->addValue('p24_api_version', P24_VERSION);
$this->api = $this->config->get_p24_api();
return true;
}
/**
* Returns host URL
*/
public function getHost() {
return self::getHostStatic($this->testMode);
}
public static function getHostStatic($testMode) {
if ($testMode) return self::$hostSandbox;
return self::$hostLive;
}
/**
* Add value do post request
*
* @param string $name Argument name
* @param mixed $value Argument value
*/
public function addValue($name, $value) {
if ($this->validateField($name, $value))
$this->postData[$name] = $value;
}
/**
* Redirects or returns URL to a P24 payment screen
*
* @param string $token Token
* @param bool $redirect If set to true redirects to P24 payment screen. If set to false function returns URL to redirect to P24 payment screen
* @return string URL to P24 payment screen
*/
public function trnRequest($token, $redirect = true) {
$url=$this->getHost().'trnRequest/'.$token;
if($redirect) {
header('Location: '.$url);
return '';
}
return $url;
}
/**
* Verify rest transaction.
*
* @return bool
*/
private function trn_verify_rest() {
$payload = array(
'merchantId' => (int) $this->merchantId,
'posId' => (int) $this->posId,
'sessionId' => $this->postData['p24_session_id'],
'amount' => (int) $this->postData['p24_amount'],
'currency' => $this->postData['p24_currency'],
'orderId' => (int) $this->postData['p24_order_id'],
);
$api_rest = new P24_Rest_Transaction( $this->config );
return $api_rest->verify_bool( $payload );
}
/**
* @param string $field
* @param mixed &$value
* @return boolean
*/
public function validateField($field, &$value) {
return $this->message_validator->validate_field($field, $value);
}
/**
* Filter value.
*
* @param string $field The name of field.
* @param string|float|int $value The value to test.
* @return bool|string
*/
private function filterValue($field, $value) {
return $this->message_validator->filter_value($field, $value);
}
/**
* Check if mandatory fields are set.
*
* @param $fieldsArray
*
* @return bool
* @throws Exception
*/
public static function checkMandatoryFieldsForAction($fieldsArray) {
$keys = array_keys($fieldsArray);
static $mandatory=array(
'p24_merchant_id','p24_pos_id','p24_api_version','p24_session_id','p24_amount',//all
'p24_currency','p24_description','p24_country','p24_url_return','p24_currency','p24_email');//register/direct
for ($i=0; $i<count($mandatory); $i++) {
if(!in_array($mandatory[$i], $keys)) {
throw new Exception('Field '.$mandatory[$i].' is required for request!');
}
}
return true;
}
/**
* Parse and validate POST response data from Przelewy24
* @return array|false
*/
public function parseStatusResponse() {
if (isset($_POST['p24_session_id'], $_POST['p24_order_id'], $_POST['p24_merchant_id'], $_POST['p24_pos_id'], $_POST['p24_amount'], $_POST['p24_currency'], $_POST['p24_method']/*, $_POST['p24_statement']*/, $_POST['p24_sign'])) {
$session_id = $this->filterValue('p24_session_id', $_POST['p24_session_id']);
$merchant_id = $this->filterValue('p24_merchant_id', $_POST['p24_merchant_id']);
$pos_id = $this->filterValue('p24_pos_id', $_POST['p24_pos_id']);
$order_id = $this->filterValue('p24_order_id', $_POST['p24_order_id']);
$amount = $this->filterValue('p24_amount', $_POST['p24_amount']);
$currency = $this->filterValue('p24_currency', $_POST['p24_currency']);
$method = $this->filterValue('p24_method', $_POST['p24_method']);
if ($merchant_id!=$this->merchantId || $pos_id!=$this->posId) return false;
return array(
'p24_session_id' => $session_id,
'p24_order_id' => $order_id,
'p24_amount' => $amount,
'p24_currency' => $currency,
'p24_method' => $method,
);
}
return null;
}
public function trn_verify_ex_rest( $data = null ) {
$response = $this->parseStatusResponse();
if ($response === null) return null;
elseif ($response) {
if ($data!=null) {
foreach ($data as $field => $value) {
if ($response[$field]!=$value) return false;
}
}
$this->postData=array_merge($this->postData,$response);
return $this->trn_verify_rest();
}
return false;
}
/**
* Zwraca listę kanałów płatności, którymi można płacić inną walutą niż PLN
*/
public static function getChannelsNonPln() {
return array(66,92,124,140,145,152,218);
}
/**
* Zwraca listę kanałów płatności ratalnej
*/
public static function getChannelsRaty() {
return array(72,129,136);
}
/**
* Zwraca minimalną kwotę dla płatności ratalnych
*/
public static function getMinRatyAmount() {
return 300;
}
/**
* Zwraca listę kanałów płatności kartą
*
*/
public static function getChannelsCard(): array {
return array(140,142,145,218);
}
/**
* Zwraca listę kanałów płatności [id => etykieta,]
*
* @param bool $only24at7 płatności, które są w tej chwili aktywne - usuwa z wyników te nienatychmiastowe
* @param string $currency ogranicza listę metod płatności do dostępnych dla wskazanej waluty
* @param string $lang Etykiety kanałów płatności w wybranym języku
* @return bool
*/
public function availablePaymentMethods($only24at7 = true, $currency = 'PLN', $lang = 'pl')
{
if (empty($this->api)) {
return false;
}
$rest_api = new P24_Rest_Common( $this->config );
$res = $rest_api->payment_methods( $lang );
if ( isset( $res['data'] ) ) {
$banks = $res['data'];
if ($only24at7) {
$there_is_218 = false;
foreach ($banks as $key => $bank) {
if (218 === $bank['id']) {
$there_is_218 = true;
}
if (!$bank['status'] || 1000 === $bank['id']) {
unset($banks[$key]);
}
}
}
if ($currency !== 'PLN') {
foreach ($banks as $key => $bank) {
if (!isset($there_is_218) && 218 === $bank['id']) {
$there_is_218 = true;
}
if (!in_array($bank['id'], $this->getChannelsNonPln())) {
unset($banks[$key]);
}
}
if (!isset($there_is_218)) {
$there_is_218 = false;
}
}
if (!isset($there_is_218)) {
$there_is_218 = false;
foreach ($banks as $bank) {
if (218 === $bank['id']) {
$there_is_218 = true;
break;
}
}
}
// filter method 142 and 145 when there is 218
if ($there_is_218) {
foreach ($banks as $key => $bank) {
if (in_array($bank['id'], array(142, 145))) {
unset($banks[$key]);
}
}
}
return $banks;
}
return false;
}
public function availablePaymentMethodsSimple($only24at7 = true, $currency = 'PLN', $lang = 'pl') {
$all = $this->availablePaymentMethods($only24at7, $currency, $lang);
$result = array();
if (is_array($all) && sizeof($all) > 0) {
foreach ($all as $item) {
$result[$item['id']] = $item['name'];
}
} else {
$result = $all;
}
return $result;
}
}
}

View File

@@ -0,0 +1,68 @@
<?php
class Przelewy24OneClickHelper
{
public static function getCardPaymentIds()
{
return array(140, 142, 145, 218);
}
public static function updateCustomerRememberCard($customerId, $remember = 0)
{
return Db::getInstance()->Execute("REPLACE INTO " . _DB_PREFIX_ . "przelewy24_customersettings (`customer_id`, `card_remember`) " .
"VALUES (" . (int)$customerId . ", '" . (int)$remember . "')");
}
public static function rememberCardForCustomer($customerId)
{
$rememberRow = Db::getInstance()->getRow('SELECT `card_remember` FROM ' . _DB_PREFIX_ . 'przelewy24_customersettings WHERE customer_id=' . (int)$customerId);
if (!isset($rememberRow['card_remember'])) {
// if empty, then set default value: 1
return (bool)self::updateCustomerRememberCard($customerId, 1);
}
return (bool)($rememberRow['card_remember'] > 0);
}
public static function saveCard($customerId, $refId, $expires, $mask, $cardType)
{
Db::getInstance()->Execute("REPLACE INTO " . _DB_PREFIX_ . "przelewy24_recuring (`website_id`, `customer_id`, `reference_id`, `expires`, `mask`, `card_type`) " .
"VALUES (1, " . (int)$customerId . ", '" . pSQL($refId) . "', '" . pSQL($expires) . "', '" . pSQL($mask) . "', '" . pSQL($cardType) . "')");
}
public static function escape($string)
{
$string = trim($string);
return htmlspecialchars($string);
}
public static function getCustomerCards($customerId)
{
$results = Db::getInstance()->ExecuteS(
' SELECT * ' . ' FROM ' . _DB_PREFIX_ . 'przelewy24_recuring WHERE customer_id=' . (int)$customerId
);
return $results;
}
public static function deleteCustomerCard($customerId, $cardId)
{
Db::getInstance()->Execute(
' DELETE FROM ' . _DB_PREFIX_ . 'przelewy24_recuring ' .
' WHERE customer_id=' . (int)$customerId . ' AND id=' . (int)$cardId
);
}
public static function isOneClickEnable($sufix = "")
{
$soap = new Przelewy24Soap($sufix);
if ($soap->checkCardRecurrency() && (int)Configuration::get('P24_ONECLICK_ENABLE') === 1) {
return true;
}
return false;
}
public static function getOneclickOrderId($orderId){
$result = Db::getInstance()->getRow('SELECT * FROM ' . _DB_PREFIX_ . 'przelewy24_oneclick WHERE p24_order_id = ' . (int)$orderId);
return $result;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/**
* File that define P24_External_Multi_Currency class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class with support for external multi currency.
*/
class P24_MC_External_None implements P24_MC_Interface {
/**
* Check if external multi currency is activated.
*
* This one is always inactive.
*
* @return bool
*/
public function is_multi_currency_active() {
return false;
}
/**
* Check if multi currency is internal.
*
* @return bool
*/
public function is_internal() {
return false;
}
/**
* Get list of available currencies.
*
* @return array
*/
public function get_available_currencies() {
return array();
}
/**
* Get name.
*
* @return string
*/
public function get_name() {
return '';
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* File that define P24_External_Multi_Currency class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class with support for external multi currency.
*/
class P24_MC_External_WPML implements P24_MC_Interface {
/**
* Get wpml settings.
*
* @return array
*/
private static function get_wpml_settings() {
global $woocommerce_wpml;
if ( $woocommerce_wpml ) {
if ( isset( $woocommerce_wpml->settings['currencies_order'] ) ) {
return $woocommerce_wpml->settings['currencies_order'];
}
}
return array();
}
/**
* Try create instance.
*
* @return null|P24_MC_External_WPML
*/
public static function try_create() {
$settings = self::get_wpml_settings();
if ( $settings ) {
return new self();
} else {
return null;
}
}
/**
* Check if external multi currency is activated.
*
* @return bool
*/
public function is_multi_currency_active() {
$settings = self::get_wpml_settings();
return (bool) $settings;
}
/**
* Check if multi currency is internal.
*
* @return bool
*/
public function is_internal() {
return false;
}
/**
* Get list of available currencies.
*
* @return array
*/
public function get_available_currencies() {
$settings = self::get_wpml_settings();
return array_combine( $settings, $settings );
}
/**
* Get name.
*
* @return string
*/
public function get_name() {
return 'WPML';
}
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* File that define P24_External_Multi_Currency class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class with support for external multi currency.
*/
interface P24_MC_Interface {
/**
* Check if external multi currency is activated.
*
* @return bool
*/
public function is_multi_currency_active();
/**
* Check if multi currency is internal.
*
* @return bool
*/
public function is_internal();
/**
* Get list of available currencies.
*
* @return array
*/
public function get_available_currencies();
/**
* Get name of multi currency implementation.
*
* @return string
*/
public function get_name();
}

View File

@@ -0,0 +1,152 @@
<?php
/**
* File that define P24_MC_Pool class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class that pool all multi currency support.
*/
class P24_MC_Pool {
/**
* Instance of core of plugin.
*
* @var P24_Core
*/
private $plugin_core;
/**
* External multi currency proxy.
*
* @var P24_MC_Interface|null
*/
private $external = null;
/**
* Active currency.
*
* @var string|null
*/
private $active_currency = null;
/**
* P24_MC_Pool constructor.
*
* @param P24_Core $plugin_core Instance of main plugin.
*/
public function __construct( P24_Core $plugin_core ) {
$this->plugin_core = $plugin_core;
}
/**
* Set_active_currency.
*
* @param string $currency Currency.
*/
public function set_active_currency( $currency ) {
$this->active_currency = $currency;
}
/**
* Get external Multi Currency proxy.
*
* @return P24_MC_Interface
*/
public function get_external_mc() {
if ( ! $this->external ) {
$wpml = P24_MC_External_WPML::try_create();
if ( $wpml && $wpml->is_multi_currency_active() ) {
$this->external = $wpml;
} else {
$this->external = new P24_MC_External_None();
}
}
return $this->external;
}
/**
* Get preffered Multi Currency proxy.
*
* @return P24_MC_Interface|null
*/
public function get_preffered_mc() {
if ( $this->plugin_core->is_internal_multi_currency_active() ) {
$mc = $this->plugin_core->get_multi_currency_instance();
} else {
$mc = $this->get_external_mc();
}
return $mc;
}
/**
* Method for filter that change default currency.
*
* The default value is ignored.
* The wrapped function should always return something.
*
* @param string|null $default Default value provided by filter.
* @return string|null
*/
public function check_admin_currency( $default ) {
if ( ! $this->active_currency ) {
$mc = $this->get_preffered_mc();
$available = $mc->get_available_currencies();
wp_verify_nonce( null ); /* There is no noce. */
if ( $this->plugin_core->is_in_json_mode() ) {
if ( array_key_exists( P24_Request_Support::WP_JSON_GET_KEY_CURRENCY, $_GET ) ) {
$this->active_currency = sanitize_text_field( wp_unslash( $_GET[ P24_Request_Support::WP_JSON_GET_KEY_CURRENCY ] ) );
}
} else {
if ( isset( $_COOKIE['admin_p24_currency'] ) ) {
$this->active_currency = sanitize_text_field( wp_unslash( $_COOKIE['admin_p24_currency'] ) );
}
}
if ( ! $this->active_currency || ! array_key_exists( $this->active_currency, $available ) ) {
$this->active_currency = P24_Woo_Commerce_Low_Level_Getter::get_unhooked_currency_form_woocommerce();
}
}
return $this->active_currency ? $this->active_currency : $default;
}
/**
* Get list of available currencies.
*
* It is based on multipliers.
*
* @return array
*/
public function get_available_currencies() {
return $this->get_preffered_mc()->get_available_currencies();
}
/**
* An AJAX method to change currency for admin.
*/
public function admin_ajax_change_currency() {
$mc = $this->get_preffered_mc();
if ( $mc->is_multi_currency_active() ) {
header( 'Content-Type: text/plain; charset=utf-8' );
wc_setcookie( 'admin_p24_currency', $this->check_admin_currency( '' ) );
echo 'Ok';
wp_die();
}
}
/**
* Bind events to use multi currency.
*/
public function bind_events() {
add_action( 'wp_ajax_p24_change_currency', array( $this, 'admin_ajax_change_currency' ) );
add_filter( 'przelewy24_multi_currency_admin_currency', array( $this, 'check_admin_currency' ) );
add_filter( 'przelewy24_multi_currency_options', array( $this, 'get_available_currencies' ) );
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* Autoload classes of Przelewy24 Plugin.
*
* The class has 3 requirements:
* 1. The class should start (case insensitive) from P24_.
* 2. The file has to reside in includes directory.
* 3. The file should be prefixed with class-.
* 4. The extension should be php.
* 5. The underscores should be replaced by hyphens.
*/
defined( 'ABSPATH' ) || exit;
spl_autoload_register(
function( $class ) {
if ( preg_match( '/^p24_[a-z][a-z0-9\\_]+/i', $class ) ) {
$normalised = strtolower( strtr( $class, array( '_' => '-' ) ) );
$directories = array(
__DIR__,
__DIR__ . '/subscription',
__DIR__ . '/report-data-stores',
__DIR__ . '/rest_api',
__DIR__ . '/multi_currency',
);
foreach ( $directories as $directory ) {
$path_class = $directory . '/class-' . $normalised . '.php';
if ( is_readable( $path_class ) ) {
require_once $path_class;
return;
}
}
}
}
);

View File

@@ -0,0 +1,36 @@
<?php
/**
* Categories data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Categories\DataStore;
use Automattic\WooCommerce\Admin\API\Reports\Orders\DataStore as OrdersDataStore;
/**
* Class P24_Categories_Data_Store.
*/
class P24_Categories_Data_Store extends DataStore {
/**
* Return the database query with parameters used for Categories report: time span and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function add_sql_query_params( $query_args ) {
parent::add_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( OrdersDataStore::get_db_table_name() );
$this->subquery->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Coupons data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Coupons\DataStore;
/**
* Class P24_Coupons_Data_Store.
*/
class P24_Coupons_Data_Store extends DataStore {
/**
* Updates the database query with parameters used for Products report: categories and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function add_sql_query_params( $query_args ) {
parent::add_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( self::get_db_table_name() );
$this->subquery->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* Coupons stats data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Coupons\Stats\DataStore;
/**
* Class P24_Coupons_Stats_Data_Store.
*/
class P24_Coupons_Stats_Data_Store extends DataStore {
/**
* Updates the database query with parameters used for Products Stats report: categories and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function update_sql_query_params( $query_args ) {
parent::update_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( self::get_db_table_name() );
$this->interval_query->add_sql_clause( 'join', $metadata_join );
$this->total_query->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* Customers data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Customers\DataStore;
use Automattic\WooCommerce\Admin\API\Reports\Orders\DataStore as OrdersDataStore;
/**
* Class P24_Customers_Data_Store.
*/
class P24_Customers_Data_Store extends DataStore {
/**
* Updates the database query with parameters used for Customers report: categories and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function add_sql_query_params( $query_args ) {
parent::add_sql_query_params( $query_args );
$query_statement = $this->subquery->get_query_statement();
$order_table = OrdersDataStore::get_db_table_name();
if ( false === strpos( $query_statement, $order_table ) ) {
return;
}
$metadata_alias = 'p24_postmeta';
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( $order_table );
$this->subquery->add_sql_clause( 'left_join', $metadata_join );
$this->subquery->add_sql_clause(
'where',
"AND {$metadata_alias}.meta_key = '_order_currency'"
);
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* Customers stats data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Customers\Stats\DataStore;
use Automattic\WooCommerce\Admin\API\Reports\Orders\DataStore as OrdersDataStore;
/**
* Class P24_Customers_Stats_Data_Store.
*/
class P24_Customers_Stats_Data_Store extends DataStore {
/**
* Updates the database query with parameters used for Customers report: categories and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function add_sql_query_params( $query_args ) {
parent::add_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( OrdersDataStore::get_db_table_name() );
$this->subquery->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Orders data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Orders\DataStore;
/**
* Class P24_Orders_Data_Store.
*/
class P24_Orders_Data_Store extends DataStore {
/**
* Updates the database query with parameters used for orders report: coupons and products filters.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function add_sql_query_params( $query_args ) {
parent::add_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( self::get_db_table_name() );
$this->subquery->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* Orders stats data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Orders\Stats\DataStore;
/**
* Class P24_Orders_Stats_Data_Store.
*/
class P24_Orders_Stats_Data_Store extends DataStore {
/**
* Updates the totals and intervals database queries with parameters used for Orders report: categories, coupons and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function orders_stats_sql_filter( $query_args ) {
parent::orders_stats_sql_filter( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( self::get_db_table_name() );
$this->total_query->add_sql_clause( 'join', $metadata_join );
$this->interval_query->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* Products data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Products\DataStore;
use Automattic\WooCommerce\Admin\API\Reports\Orders\DataStore as OrdersDataStore;
/**
* Class P24_Products_Data_Store.
*/
class P24_Products_Data_Store extends DataStore {
/**
* Updates the database query with parameters used for Products report: categories and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function add_sql_query_params( $query_args ) {
parent::add_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( OrdersDataStore::get_db_table_name() );
$this->subquery->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* Products data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Products\Stats\DataStore;
use Automattic\WooCommerce\Admin\API\Reports\Orders\DataStore as OrdersDataStore;
/**
* Class P24_Products_Stats_Data_Store.
*/
class P24_Products_Stats_Data_Store extends DataStore {
/**
* Updates the database query with parameters used for Products Stats report: categories and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function update_sql_query_params( $query_args ) {
parent::update_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( OrdersDataStore::get_db_table_name() );
$this->interval_query->add_sql_clause( 'join', $metadata_join );
$this->total_query->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Taxes data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Taxes\DataStore;
/**
* Class P24_Taxes_Data_Store.
*/
class P24_Taxes_Data_Store extends DataStore {
/**
* Updates the totals and intervals database queries with parameters used for Orders report: categories, coupons and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function add_sql_query_params( $query_args ) {
parent::add_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( self::get_db_table_name() );
$this->subquery->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* Taxes stats data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Taxes\Stats\DataStore;
/**
* Class P24_Taxes_Stats_Data_Store.
*/
class P24_Taxes_Stats_Data_Store extends DataStore {
/**
* Updates the database query with parameters used for Taxes Stats report
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function update_sql_query_params( $query_args ) {
parent::update_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( self::get_db_table_name() );
$this->total_query->add_sql_clause( 'join', $metadata_join );
$this->interval_query->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Variations data store.
*
* @package Przelewy24
*/
use Automattic\WooCommerce\Admin\API\Reports\Variations\DataStore;
/**
* Class P24_Variations_Data_Store.
*/
class P24_Variations_Data_Store extends DataStore {
/**
* Updates the database query with parameters used for Products report: categories and order status.
*
* @param array $query_args Query arguments supplied by the user.
*/
protected function add_sql_query_params( $query_args ) {
parent::add_sql_query_params( $query_args );
$metadata_join = P24_Multi_Currency::get_currency_filter_for_reports( self::get_db_table_name() );
$this->subquery->add_sql_clause( 'join', $metadata_join );
}
/**
* Get cache key.
*
* @param array $params Parameters.
*
* @return string
*/
protected function get_cache_key( $params ) {
return parent::get_cache_key( $params ) . '_' . P24_Multi_Currency::get_admin_reports_currency();
}
}

View File

@@ -0,0 +1,89 @@
<?php
/**
* File that define P24_Rest_Abstract class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Base class for REST API transaction.
*/
class P24_Rest_Abstract {
const URL_SECURE = 'https://secure.przelewy24.pl/api/v1';
const URL_SANDBOX = 'https://sandbox.przelewy24.pl/api/v1';
/**
* Url.
*
* @var string|null
*/
protected $url;
/**
* Config accessor.
*
* @var P24_Config_Accessor
*/
protected $cf;
/**
* Przelewy24RestAbstract constructor.
*
* @param P24_Config_Accessor $cf
*/
public function __construct( P24_Config_Accessor $cf ) {
$this->cf = clone $cf;
$this->cf->access_mode_to_strict();
if ( $this->cf->is_p24_operation_mode( 'sandbox' ) ) {
$this->url = self::URL_SANDBOX;
} else {
$this->url = self::URL_SECURE;
}
}
/**
* Call rest command
*
* @param string $path Api path.
* @param array|object|null $payload Method call parameters.
* @param string $method Method name.
*
* @return array
*/
protected function call( $path, $payload, $method ) {
$credentials = $this->cf->get_shop_id() . ':' . $this->cf->get_p24_api();
$json_style = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$options = array(
CURLOPT_USERPWD => $credentials,
CURLOPT_URL => $this->url . $path,
CURLOPT_RETURNTRANSFER => true,
);
if ( 'PUT' === $method ) {
$options[ CURLOPT_CUSTOMREQUEST ] = 'PUT';
}
if ( 'GET' !== $method ) {
$headers = array(
'Content-Type: application/json',
);
$options[ CURLOPT_POST ] = true;
$options[ CURLOPT_HTTPHEADER ] = $headers;
$options[ CURLOPT_POSTFIELDS ] = wp_json_encode( $payload, $json_style );
}
$h = curl_init();
curl_setopt_array( $h, $options );
$ret = curl_exec( $h );
curl_close( $h );
$decoded = json_decode( $ret, true );
if ( ! is_array( $decoded ) ) {
$decoded = array();
}
return $decoded;
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* File that define P24_Rest_Blik class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class that support card API.
*/
class P24_Rest_Blik extends P24_Rest_Abstract {
/**
* Charge by code
*
* @param string $token Przelewy24 transaction token.
* @param string $blik_code Blik code.
*
* @return array
*/
public function charge_by_code( $token, $blik_code ) {
$path = '/paymentMethod/blik/chargeByCode';
$payload = array(
'token' => $token,
'blikCode' => $blik_code,
);
$ret = $this->call( $path, $payload, 'POST' );
return $ret;
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* File that define P24_Rest_Card class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class that support card API.
*/
class P24_Rest_Card extends P24_Rest_Abstract {
/**
* Charge with 3ds.
*
* @param string $token Przelewy24 transaction token.
* @return array
*/
public function chargeWith3ds( $token ) {
$path = '/card/chargeWith3ds';
$payload = array(
'token' => $token,
);
$ret = $this->call( $path, $payload, 'POST' );
return $ret;
}
/**
* Charge without 3ds.
*
* @param string $token Przelewy24 transaction token.
* @return array
*/
public function chargeWithout3ds( $token ) {
$path = '/card/charge';
$payload = array(
'token' => $token,
);
$ret = $this->call( $path, $payload, 'POST' );
return $ret;
}
/**
* Pay.
*
* @param array $payload Array with transaction data required to make card payment.
*
* @return array
*/
public function pay( $payload ) {
$path = '/card/pay';
$ret = $this->call( $path, $payload, 'POST' );
return $ret;
}
/**
* Info.
*
* @param string $order_id Order id used to collect card data with.
*
* @return array
*/
public function info( $order_id ) {
return $this->call( '/card/info/' . $order_id, null, 'GET' );
}
}

View File

@@ -0,0 +1,57 @@
<?php
/**
* File that define P24_Rest_Common class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class that support card API.
*/
class P24_Rest_Common extends P24_Rest_Abstract {
/**
* Test access.
*
* @return array
*/
public function test_access() {
$path = '/testAccess';
$ret = $this->call( $path, null, 'GET' );
return $ret;
}
/**
* Test access bool.
*
* @return bool
*/
public function test_access_bool() {
$data = $this->test_access();
return isset( $data['error'] ) && empty( $data['error'] );
}
/**
* Payment_methods.
*
* @param string $lang One of supported languages (only 'pl' and 'en' for now).
*
* @return array
*
* @throws LogicException When wrong language is provided.
*/
public function payment_methods( $lang ) {
if ( ! in_array( $lang, array( 'pl', 'en' ), true ) ) {
throw new LogicException( 'The lang ' . $lang . ' is not supported.' );
}
$path = '/payment/methods/' . $lang;
$ret = $this->call( $path, null, 'GET' );
return $ret;
}
}

View File

@@ -0,0 +1,146 @@
<?php
/**
* File that define P24_Rest_Transaction class.
*
* @package Przelewy24
*/
defined( 'ABSPATH' ) || exit;
/**
* Class that support transaction API.
*/
class P24_Rest_Transaction extends P24_Rest_Abstract {
/**
* Register.
*
* @param array $payload
* @return array
*/
public function register( $payload ) {
$path = '/transaction/register';
$payload['sign'] = $this->sign_sha_384_register( $payload );
return $this->call( $path, $payload, 'POST' );
}
/**
* Register raw token.
*
* @param array $payload Array with payload data.
*
* @return string|null
*/
public function register_raw_token( $payload ) {
$res = $this->register( $payload );
if ( isset( $res['data']['token'] ) ) {
return $res['data']['token'];
} else {
return null;
}
}
/**
* Register.
*
* @param array $payload
* @return array
*/
public function verify( $payload ) {
$path = '/transaction/verify';
$payload['sign'] = $this->sign_sha_384_verify( $payload );
return $this->call( $path, $payload, 'PUT' );
}
/**
* Register.
*
* @param array $payload Array with optional data -> status field.
*
* @return bool
*/
public function verify_bool( $payload ) {
$res = $this->verify( $payload );
if ( isset( $res['data']['status'] ) ) {
$status = $res['data']['status'];
} else {
$status = '';
}
return 'success' === $status;
}
/**
* Register.
*
* @param array $payload Array with transaction refund data.
*
* @return array
*/
public function refund( $payload ) {
$path = '/transaction/refund';
return $this->call( $path, $payload, 'POST' );
}
/**
* By_session_id.
*
* @param string $session_id Session id of transaction to search for by REST api.
*
* @return array
*
* @throws InvalidArgumentException When invalid session id is provided.
*/
public function by_session_id( $session_id ) {
/* RFC 3986 unreserved characters. */
if ( ! preg_match( '/^[a-zA-Z0-9\\_\\.\\-\\~]+$/', $session_id ) ) {
/* We do not support other than unreserved characters in $session_id. */
throw new InvalidArgumentException( 'Invalid session id provided.' );
}
$path = '/transaction/by/sessionId/' . $session_id;
return $this->call( $path, null, 'GET' );
}
/**
* Sign sha384.
*
* @param array $payload
* @return string
*/
private function sign_sha_384_register( $payload ) {
$data = array(
'sessionId' => $payload['sessionId'],
'merchantId' => $payload['merchantId'],
'amount' => $payload['amount'],
'currency' => $payload['currency'],
'crc' => $this->cf->get_salt(),
);
$string = json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
$sign = hash( 'sha384', $string );
return $sign;
}
/**
* Sign sha384.
*
* @param array $payload
* @return string
*/
private function sign_sha_384_verify( $payload ) {
$data = array(
'sessionId' => $payload['sessionId'],
'orderId' => $payload['orderId'],
'amount' => $payload['amount'],
'currency' => $payload['currency'],
'crc' => $this->cf->get_salt(),
);
$string = json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
$sign = hash( 'sha384', $string );
return $sign;
}
}

View File

@@ -0,0 +1,12 @@
# Change Log #
## [Zencard] - 2016-11-10 ##
- Has coupon field.
## [Przelewy24Product] - 2016-10-13 ##
- Init.
- Added descriptions, doc.

View File

@@ -0,0 +1,8 @@
# Zbiór wspólnych bibliotek/klas dla wszystkich wtyczek sklepowych Przelewy24 #
### Minimalne wymagania ###
- PHP 5.2+
- SOAP
- cURL

View File

@@ -0,0 +1,9 @@
<?php
if (!defined('PRZELEWY24_LIB_ROOT')) {
define('PRZELEWY24_LIB_ROOT', dirname(__FILE__));
}
require_once PRZELEWY24_LIB_ROOT . DIRECTORY_SEPARATOR . 'interfaces' . DIRECTORY_SEPARATOR . 'Przelewy24Interface.php';
require_once PRZELEWY24_LIB_ROOT . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'Przelewy24Product.php';
require_once PRZELEWY24_LIB_ROOT . DIRECTORY_SEPARATOR . 'installer' . DIRECTORY_SEPARATOR . 'Przelewy24Installer.php';

View File

@@ -0,0 +1,79 @@
<?php
if (!class_exists('Przelewy24Product', false)) {
class Przelewy24Product implements Przelewy24Interface
{
private $translations;
public function __construct(array $translations = array())
{
$this->setTranslations($translations);
}
/**
* Prepare cart items for form trnRegister.
*
* Read more: /docs/przelewy24product.md
*/
public function prepareCartItems($amount, array $items = array(), $shipping = 0)
{
$cartItems = array();
if (empty($items)) {
return $cartItems;
}
$amount = (int)$amount;
$shipping = (int)$shipping;
$number = 0;
$sumProductsPrice = 0;
$joinName = '';
foreach ($items as $item) {
$number++;
$cartItems['p24_name_' . $number] = substr(strip_tags($item['name']), 0, 127);
$cartItems['p24_description_' . $number] = substr(strip_tags($item['description']), 0, 127);
$cartItems['p24_quantity_' . $number] = (int)$item['quantity'];
$cartItems['p24_price_' . $number] = (int)$item['price'];
$cartItems['p24_number_' . $number] = (int)$item['number'];
$joinName .= strip_tags($item['name']) . ', ';
$sumProductsPrice += ((int)$item['quantity'] * (int)$item['price']);
}
if ($amount > $shipping + $sumProductsPrice) {
$number++;
$cartItems['p24_name_' . $number] = $this->translations['virtual_product_name'];
$cartItems['p24_description_' . $number] = '';
$cartItems['p24_quantity_' . $number] = 1;
$cartItems['p24_price_' . $number] = $amount - ($shipping + $sumProductsPrice);
$cartItems['p24_number_' . $number] = 0;
} else if ($amount < $shipping + $sumProductsPrice) {
$cartItems = array();
$number = 1;
$joinName = $this->translations['cart_as_product'] . ' [' . trim($joinName, ', ') . ']';
$cartItems['p24_name_' . $number] = substr($joinName, 0, 127);
$cartItems['p24_description_' . $number] = '';
$cartItems['p24_quantity_' . $number] = 1;
$cartItems['p24_price_' . $number] = $amount - $shipping;
$cartItems['p24_number_' . $number] = 0;
}
// when is correct
return $cartItems;
}
public function setTranslations(array $translations = array())
{
$this->translations = $translations;
// set default values
if (empty($this->translations['virtual_product_name'])) {
$this->translations['virtual_product_name'] = 'Różnica';
}
if (empty($this->translations['cart_as_product'])) {
$this->translations['cart_as_product'] = 'Zamówienie';
}
}
}
}

View File

@@ -0,0 +1,124 @@
<?php
if (!class_exists('Przelewy24Installer', false)) {
class Przelewy24Installer implements Przelewy24Interface
{
private $translations;
private $sliderEnabled = true;
private $pages = array();
public function __construct($sliderEnabled = true, array $translations = array())
{
$this->sliderEnabled = $sliderEnabled;
$this->setTranslations($translations);
}
public function setTranslations(array $translations = array())
{
$this->translations = $translations;
// set default values
if (empty($this->translations['php_version'])) {
$this->translations['php_version'] = 'Wersja PHP min. 5.2';
}
if (empty($this->translations['curl_version'])) {
$this->translations['curl_enabled'] = 'Włączone rozszerzenie PHP cURL (php_curl.dll)';
}
if (empty($this->translations['soap_enabled'])) {
$this->translations['soap_enabled'] = 'Włączone rozszerzenie PHP SOAP (php_soap.dll)';
}
if (empty($this->translations['merchant_id'])) {
$this->translations['merchant_id'] = 'ID sprzedawcy';
}
if (empty($this->translations['shop_id'])) {
$this->translations['shop_id'] = 'ID sklepu';
}
if (empty($this->translations['crc_key'])) {
$this->translations['crc_key'] = 'Klucz CRC';
}
if (empty($this->translations['api_key'])) {
$this->translations['api_key'] = 'Klucz API';
}
}
public function addPages(array $pages = array())
{
$this->pages = array_values($pages);
}
public function renderInstallerSteps()
{
if (!$this->sliderEnabled || empty($this->pages) || !is_array($this->pages)) {
return '';
}
$requirements = $this->checkRequirements();
$params = array(
'requirements' => $requirements,
'translations' => $this->translations
);
$maxSteps = 0;
$data = array(
'steps' => array()
);
foreach ($this->pages as $page) {
$page = (int)$page;
if ($page > 0) {
$step = $this->loadStep($page, $params);
$data['steps'][$page] = $step;
$maxSteps++;
}
}
if ($maxSteps === 0) {
return '';
}
$data['maxSteps'] = $maxSteps;
return $this->loadTemplate('installer', $data);
}
private function loadStep($number, $params = null)
{
$step = $this->loadTemplate('step' . $number, $params);
$step = $this->removeNewLines($step);
return $step;
}
private function removeNewLines($string)
{
return trim(str_replace(PHP_EOL, ' ', $string));
}
private function loadTemplate($view, $data = null)
{
extract(array("content" => $data));
ob_start();
$viewFile = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'theme' . DIRECTORY_SEPARATOR . "$view.tpl.php";
if (file_exists($viewFile)) {
include $viewFile;
} else {
throw new Exception('View not exist in ' . get_class($this));
}
$content = ob_get_clean();
return $content;
}
private function checkRequirements()
{
$data = array(
'php' => array(
'test' => (version_compare(PHP_VERSION, '5.2.0') > 0),
'label' => $this->translations['php_version']
),
'curl' => array(
'test' => function_exists('curl_version'),
'label' => $this->translations['curl_enabled']
),
);
return $data;
}
}
}

Some files were not shown because too many files have changed in this diff Show More