Browse Source

代码规范

master
VIVIMAN 3 years ago
parent
commit
a1eef16017
  1. 2
      gui_wails01_learn/.gitattributes
  2. 9
      gui_wails01_learn/.gitignore
  3. 21
      gui_wails01_learn/LICENSE
  4. 67
      gui_wails01_learn/Makefile
  5. BIN
      gui_wails01_learn/appicon.png
  6. BIN
      gui_wails01_learn/assets/appicon.png
  7. 65
      gui_wails01_learn/backend/api/rpc.go
  8. 237
      gui_wails01_learn/backend/app.go
  9. 210
      gui_wails01_learn/backend/assemblywrapper.go
  10. 252
      gui_wails01_learn/backend/buildchain.go
  11. 441
      gui_wails01_learn/backend/cmd/update/main.go
  12. 393
      gui_wails01_learn/backend/dashboard.go
  13. 123
      gui_wails01_learn/backend/lcm.go
  14. 167
      gui_wails01_learn/backend/login.go
  15. 4
      gui_wails01_learn/backend/models/address.go
  16. 10
      gui_wails01_learn/backend/models/path.go
  17. 19
      gui_wails01_learn/backend/models/txhistory.go
  18. 41
      gui_wails01_learn/backend/models/wallet.go
  19. 166
      gui_wails01_learn/backend/settings.go
  20. 374
      gui_wails01_learn/backend/transactions.go
  21. 188
      gui_wails01_learn/backend/utils.go
  22. 542
      gui_wails01_learn/backend/wallet.go
  23. 4
      gui_wails01_learn/build.bat
  24. 89
      gui_wails01_learn/docs/faq.md
  25. 21
      gui_wails01_learn/frontend/.gitignore
  26. 5
      gui_wails01_learn/frontend/babel.config.js
  27. 20364
      gui_wails01_learn/frontend/package-lock.json
  28. 82
      gui_wails01_learn/frontend/package.json
  29. 1
      gui_wails01_learn/frontend/package.json.md5
  30. 303
      gui_wails01_learn/frontend/src/App.vue
  31. 1081
      gui_wails01_learn/frontend/src/assets/css/themify-icons.css
  32. 202
      gui_wails01_learn/frontend/src/assets/fonts/LICENSE.txt
  33. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.eot
  34. 3451
      gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.svg
  35. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.ttf
  36. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.woff
  37. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.woff2
  38. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.eot
  39. 803
      gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.svg
  40. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.ttf
  41. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.woff
  42. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.woff2
  43. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.eot
  44. 4649
      gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.svg
  45. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.ttf
  46. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.woff
  47. BIN
      gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.woff2
  48. BIN
      gui_wails01_learn/frontend/src/assets/fonts/glyphicons-halflings-regular.448c34a.woff2
  49. BIN
      gui_wails01_learn/frontend/src/assets/fonts/glyphicons-halflings-regular.e18bbf6.ttf
  50. BIN
      gui_wails01_learn/frontend/src/assets/fonts/glyphicons-halflings-regular.f4769f9.eot
  51. BIN
      gui_wails01_learn/frontend/src/assets/fonts/glyphicons-halflings-regular.fa27723.woff
  52. BIN
      gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.eot
  53. 308
      gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.svg
  54. BIN
      gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.ttf
  55. BIN
      gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff
  56. BIN
      gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff2
  57. BIN
      gui_wails01_learn/frontend/src/assets/fonts/themify.eot
  58. 362
      gui_wails01_learn/frontend/src/assets/fonts/themify.svg
  59. BIN
      gui_wails01_learn/frontend/src/assets/fonts/themify.ttf
  60. BIN
      gui_wails01_learn/frontend/src/assets/fonts/themify.woff
  61. BIN
      gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Black.png
  62. BIN
      gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Sm-Black.png
  63. BIN
      gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Sm-Black2.png
  64. BIN
      gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Sm-White.png
  65. BIN
      gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Sm-White2.png
  66. BIN
      gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-White.png
  67. BIN
      gui_wails01_learn/frontend/src/assets/img/blockchain.jpg
  68. BIN
      gui_wails01_learn/frontend/src/assets/img/dotz.png
  69. BIN
      gui_wails01_learn/frontend/src/assets/img/faces/face-0.jpg
  70. BIN
      gui_wails01_learn/frontend/src/assets/img/nodes.jpeg
  71. BIN
      gui_wails01_learn/frontend/src/assets/img/nodes.jpg
  72. BIN
      gui_wails01_learn/frontend/src/assets/img/nodes2.jpg
  73. BIN
      gui_wails01_learn/frontend/src/assets/img/nodes2_dark.jpg
  74. BIN
      gui_wails01_learn/frontend/src/assets/img/nodes_dark.jpeg
  75. BIN
      gui_wails01_learn/frontend/src/assets/img/protocol-2.png
  76. BIN
      gui_wails01_learn/frontend/src/assets/img/spots.png
  77. BIN
      gui_wails01_learn/frontend/src/assets/img/spots4.png
  78. 20
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_animated.scss
  79. 20
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_bordered-pulled.scss
  80. 21
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_core.scss
  81. 6
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_fixed-width.scss
  82. 1388
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_icons.scss
  83. 23
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_larger.scss
  84. 18
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_list.scss
  85. 56
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_mixins.scss
  86. 24
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_rotated-flipped.scss
  87. 5
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_screen-reader.scss
  88. 2062
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_shims.scss
  89. 31
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_stacked.scss
  90. 1405
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/_variables.scss
  91. 22
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/brands.scss
  92. 16
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/fontawesome.scss
  93. 23
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/regular.scss
  94. 24
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/solid.scss
  95. 6
      gui_wails01_learn/frontend/src/assets/sass/font_awesome/v4-shims.scss
  96. 47
      gui_wails01_learn/frontend/src/assets/sass/paper-dashboard.scss
  97. 68
      gui_wails01_learn/frontend/src/assets/sass/paper/_alerts.scss
  98. 228
      gui_wails01_learn/frontend/src/assets/sass/paper/_buttons.scss
  99. 269
      gui_wails01_learn/frontend/src/assets/sass/paper/_cards.scss
  100. 229
      gui_wails01_learn/frontend/src/assets/sass/paper/_chartist.scss

2
gui_wails01_learn/.gitattributes

@ -0,0 +1,2 @@
*.css linguist-vendored
*.scss linguist-vendored

9
gui_wails01_learn/.gitignore

@ -0,0 +1,9 @@
mollywallet
mollywallet.exe
nohup.out
mollywallet-res.syso
mollywallet.exe.manifest
mollywallet.rc
build
.DS_Store
/.idea/

21
gui_wails01_learn/LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-Present Vito
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

67
gui_wails01_learn/Makefile

@ -0,0 +1,67 @@
bold := $(shell tput bold)
sgr0 := $(shell tput sgr0)
help:
@printf "\nBelow commands have been made available to ease up Molly Wallet development.\n\n"
@printf "Molly Wallet App: \n"
@printf " $(bold)run_dev_env$(sgr0) - Starts up the dev enviornment on http://localhost:8080\n"
@printf " $(bold)build_app$(sgr0) - Compiles the Molly Wallet to the build folder\n"
@printf " $(bold)buid_app_production$(sgr0) - Builds a production build for the OS it's running on\n"
@printf " $(bold)cross_compile_app$(sgr0) - Compiling for every OS and Platform to the build directory\n\n"
@printf "Update Module: \n"
@printf " $(bold)build_update_module$(sgr0) - Builds the update module to the ~/.dag folder\n"
@printf " $(bold)run_update_module$(sgr0) - Builds and runs the update module\n"
@printf " $(bold)cross_compile_update_module$(sgr0) - Compiling for every OS and Platform to the build directory\n\n"
@printf "General: \n"
@printf " $(bold)all$(sgr0) - Builds and compiles both the wallet and the Update Module\n"
@printf " $(bold)cross_compile_all$(sgr0) - Builds and compiles both the wallet and the Update Module for all Platforms\n\n"
@printf " $(bold)clean$(sgr0) - Cleans up old builds from the build directory\n\n"
run_dev_env:
@echo "Starting up frontend dev env on http://localhost:8080..."
$(shell wails serve) \
$(shell cd frontend && npm run serve)
build_app:
@echo "Building Molly Wallet binary to build folder..."
wails build
buid_app_production:
@echo "Building app for production..."
wails build -f -p
cross_compile_app:
@echo "Compiling for every OS and Platform..."
wails build -x darwin/amd64
wails build -x windows/amd64
wails build -x linux/amd64
build_update_module:
@echo "Building update module binary to ~/.dag"
go build -o ~/.dag/update backend/cmd/update/main.go
run_update_module:
@echo "Compiling and running the update module"
go run backend/cmd/update/main.go
cross_compile_update_module:
@echo "Compiling for every OS and Platform..."
GOOS=linux GOARCH=amd64 go build -o build/update-linux-amd backend/cmd/update/main.go
GOOS=windows GOARCH=amd64 go build -o build/update-windows-amd64 backend/cmd/update/main.go
GOOS=darwin GOARCH=amd64 go build -o build/main-darwin-amd64 backend/cmd/update/main.go
clean:
@echo "Cleaning up build directory..."
@rm -rf build
all: build_app build_update_module
cross_compile_all: cross_compile_app cross_compile_update_module

BIN
gui_wails01_learn/appicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
gui_wails01_learn/assets/appicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

65
gui_wails01_learn/backend/api/rpc.go

@ -0,0 +1,65 @@
package api
import (
"fmt"
"net"
"net/http"
"net/rpc"
"os"
)
type RPCEndpoints int
type Signal struct {
PID int
Msg string
}
// InitRPCServer initializes the RPC server that listens to incoming LCM tasks
// by the RPC clients
func InitRPCServer() error {
endpoints := new(RPCEndpoints)
// Publish the receivers methods
err := rpc.Register(endpoints)
if err != nil {
return fmt.Errorf("format of service Task isn't correct. Reason: %v", err)
}
// Register a HTTP handler
rpc.HandleHTTP()
// Listen to TPC connections on port 36866
listener, err := net.Listen("tcp", ":36866")
if err != nil {
return fmt.Errorf("Listen error: %v", err)
}
errs := make(chan error)
// Start accept incoming HTTP connections
go func() {
err = http.Serve(listener, nil)
if err != nil {
errs <- fmt.Errorf("Error serving: %v", err)
return
}
}()
select {
case err := <-errs:
if err != nil {
return err
}
default:
return nil
}
return nil
}
func (rpc *RPCEndpoints) ShutDown(sig Signal, response *Signal) error {
pid := os.Getpid()
*response = Signal{pid, "Shutting down application"}
// time.Sleep(3 * time.Second)
return nil
}

237
gui_wails01_learn/backend/app.go

@ -0,0 +1,237 @@
package app
import (
"encoding/json"
"io"
"os"
"os/user"
"github.com/jinzhu/gorm"
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/wailsapp/wails"
"github.com/grvlle/constellation_wallet/backend/api"
"github.com/grvlle/constellation_wallet/backend/models"
)
// WalletApplication holds all application specific objects
// such as the Client/Server event bus and logger
type WalletApplication struct {
Version string
RT *wails.Runtime
log *logrus.Logger
wallet models.Wallet
DB *gorm.DB
killSignal chan struct{}
Network struct {
URL string
Handles struct {
Send string // Takes TX Object, returns TX Hash (200)
Transaction string // Takes TX Object, returns TX Hash (200)
Balance string // Polls the wallets available balance
}
BlockExplorer struct {
URL string
Handles struct {
Transactions string // Takes TX Hash, returns TX info
Checkpoints string // Takes Checkpoint block hash, returns checkpoint block info
Snapshots string // Takes SnapshotHash, returns info
CollectTX string // Takes DAG address, returns tx objects
}
}
}
paths struct {
HomeDir string
DAGDir string
TMPDir string
EncryptedDir string
EmptyTXFile string
PrevTXFile string
LastTXFile string
AddressFile string
ImageDir string
Java string
}
KeyStoreAccess bool
TransactionFinished bool
TransactionFailed bool
UserLoggedIn bool
NewUser bool
WalletImported bool
FirstTX bool
SecondTX bool
WidgetRunning struct {
PassKeysToFrontend bool
DashboardWidgets bool
}
WalletCLI struct {
URL string
Version string
}
}
// WailsShutdown is called when the application is closed
func (a *WalletApplication) WailsShutdown() {
a.wallet = models.Wallet{}
close(a.killSignal) // Kills the Go Routines
a.DB.Close()
}
// WailsInit initializes the Client and Server side bindings
func (a *WalletApplication) WailsInit(runtime *wails.Runtime) error {
var err error
a.log = logrus.New()
err = a.initDirectoryStructure()
if err != nil {
a.log.Errorln("Unable to set up directory structure. Reason: ", err)
}
a.initLogger()
err = api.InitRPCServer()
if err != nil {
a.log.Panicf("Unable to initialize RPC Server. Reason: %v", err)
}
a.log.Infoln("RPC Server initialized.")
a.UserLoggedIn = false
a.NewUser = false
a.TransactionFinished = true
a.RT = runtime
a.killSignal = make(chan struct{}) // Used to kill go routines and hand back system resources
a.wallet.Currency = "USD" // Set default currency
a.WalletCLI.URL = "https://github.com/Constellation-Labs/constellation/releases/download"
a.WalletCLI.Version = "2.6.0"
a.Version = "1.2.0"
a.DB, err = gorm.Open("sqlite3", a.paths.DAGDir+"/store.db")
if err != nil {
a.log.Panicln("failed to connect database", err)
}
// Migrate the schema
a.DB.AutoMigrate(&models.Wallet{}, &models.TXHistory{}, &models.Path{})
a.detectJavaPath()
a.initMainnetConnection()
a.newReleaseAvailable()
return nil
}
// initLogger writes logs to STDOUT and a.paths.DAGDir/wallet.log
func (a *WalletApplication) initLogger() {
logFile, err := os.OpenFile(a.paths.DAGDir+"/wallet.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
if err != nil {
a.log.Fatal("Unable to create log file.")
}
mw := io.MultiWriter(os.Stdout, logFile)
a.log.SetOutput(mw)
a.log.SetFormatter(&log.TextFormatter{
ForceColors: true,
FullTimestamp: true,
})
}
// Initializes the Directory Structure and stores the paths to the WalletApplication struct.
func (a *WalletApplication) initDirectoryStructure() error {
user, err := user.Current()
if err != nil {
return err
}
a.paths.HomeDir = user.HomeDir // Home directory of the user
a.paths.DAGDir = a.paths.HomeDir + "/.dag" // DAG directory for configuration files and wallet specific data
a.paths.TMPDir = a.paths.DAGDir + "/tmp"
a.paths.LastTXFile = a.paths.TMPDir + "/last_tx"
a.paths.PrevTXFile = a.paths.TMPDir + "/prev_tx"
a.paths.EmptyTXFile = a.paths.TMPDir + "/genesis_tx"
a.paths.ImageDir = "./frontend/src/assets/img/" // Image Folder
a.log.Info("DAG Directory: ", a.paths.DAGDir)
err = a.directoryCreator(a.paths.DAGDir, a.paths.TMPDir)
if err != nil {
return err
}
return nil
}
// initMainnetConnection populates the WalletApplication struct with mainnet data
func (a *WalletApplication) initMainnetConnection() {
a.Network.URL = "http://lb.constellationnetwork.io:9000" // Temp
a.Network.Handles.Send = "/send"
a.Network.Handles.Transaction = "/transaction"
a.Network.Handles.Balance = "/address/"
a.Network.BlockExplorer.URL = "https://xju69fets2.execute-api.us-west-1.amazonaws.com/cl-block-explorer-mainnet"
a.Network.BlockExplorer.Handles.Transactions = "/transactions/"
a.Network.BlockExplorer.Handles.Checkpoints = "/checkpoints/"
a.Network.BlockExplorer.Handles.Snapshots = "/snapshots/"
a.Network.BlockExplorer.Handles.CollectTX = "/transactions?sender="
}
// APIError reported by the blockexplerer/loadbalancer are reported in the following format
// {"error": "Cannot find transactions for sender"}
type APIError struct {
Error string
}
// verifyAPIResponse takes API response converted to a byte array and checks if the API returned
// an error. If it did, it'll return the error message.
func (a *WalletApplication) verifyAPIResponse(r []byte) (bool, string) {
APIErr := APIError{}
if string(r[3:8]) == "error" {
err := json.Unmarshal(r, &APIErr)
if err != nil {
a.log.Errorln("Unable to parse API error. Reason: ", err)
}
return false, APIErr.Error
}
return true, ""
}
func (a *WalletApplication) sendSuccess(msg string) {
if len(msg) > 200 {
msg = string(msg[:200]) // Restrict error size for frontend
a.RT.Events.Emit("success", msg)
return
}
a.RT.Events.Emit("success", msg)
}
func (a *WalletApplication) sendWarning(msg string) {
if len(msg) > 200 {
msg = string(msg[:200]) // Restrict error size for frontend
a.RT.Events.Emit("warning", msg)
return
}
a.RT.Events.Emit("warning", msg)
}
func (a *WalletApplication) sendError(msg string, err error) {
var errStr string
if err != nil {
b := []byte(err.Error())
if len(b) > 80 {
errStr = string(b[:80]) // Restrict error size for frontend
} else if len(b) < 80 {
errStr = string(b)
} else {
errStr = ""
}
a.RT.Events.Emit("error_handling", msg, errStr+" ...")
} else {
a.RT.Events.Emit("error_handling", msg+" ...")
}
}

210
gui_wails01_learn/backend/assemblywrapper.go

@ -0,0 +1,210 @@
package app
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"runtime"
"strconv"
"time"
)
/* AssemblyWrapper contains the code that is interacting with the wallet assembly provided
by the Constellation Engineering team. The code is interfacing with the wallet assembly using
the CLI */
func (a *WalletApplication) runWalletCMD(tool string, scalaFunc string, scalaArgs ...string) error {
var main string
if runtime.GOOS == "windows" {
main = a.paths.Java
} else {
main = "java"
}
cmds := []string{"-jar", a.paths.DAGDir + "/cl-" + tool + ".jar", scalaFunc}
args := append(cmds, scalaArgs...)
cmd := exec.Command(main, args...)
a.log.Infoln("Running command: ", cmd)
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out // Captures STDOUT
cmd.Stderr = &stderr // Captures STDERR
err := cmd.Run()
if err != nil {
errFormatted := fmt.Sprint(err) + ": " + stderr.String()
return errors.New(errFormatted)
}
fmt.Println(out.String())
a.log.Debugln(cmd)
return nil
}
// WalletKeystoreAccess is true if the user can unlock the .p12 keystore
// and key using storepass and keypass
func (a *WalletApplication) WalletKeystoreAccess() bool {
a.log.Infoln("Checking Keystore Access...")
rescueStdout := os.Stdout
r, w, err := os.Pipe()
if err != nil {
a.log.Errorln("Unable to pipe STDOUT, Reason: ", err)
a.sendError("Unable to pipe STDOUT, Reason: ", err)
}
os.Stdout = w
err = a.runWalletCMD("wallet", "show-address", "--keystore="+a.wallet.KeyStorePath, "--alias="+a.wallet.WalletAlias, "--env_args=true")
if err != nil {
a.log.Warn("KeyStore Access Rejected!")
a.LoginError("Access Denied. Please make sure that you have typed in the correct credentials.")
a.KeyStoreAccess = false
return a.KeyStoreAccess
}
// STDOUT is captured here
w.Close()
dagAddress, err := ioutil.ReadAll(r)
if err != nil {
a.log.Errorln("Unable to read address from STDOUT", err)
a.sendError("Unable to read address from STDOUT", err)
}
// if STDOUT prefix of show-address output isn't DAG
if err == nil && a.wallet.Address != "" && string(dagAddress[:40]) == a.wallet.Address {
a.KeyStoreAccess = true
a.log.Info("KeyStore Access Granted!")
return a.KeyStoreAccess
}
os.Stdout = rescueStdout
a.KeyStoreAccess = false
a.log.Warn("KeyStore Access Rejected!")
a.LoginError("Access Denied. Please make sure that you have typed in the correct credentials.")
return a.KeyStoreAccess
}
// GenerateDAGAddress generates a new wallet address and stores it in memory
// java -cp constellation-assembly-1.0.12.jar org.constellation.util.wallet.GenerateAddress --pub_key_str=<base64 hash of pubkey> --store_path=<path to file where address will be stored>
func (a *WalletApplication) GenerateDAGAddress() string {
a.log.Infoln("Creating DAG Address from Public Key...")
rescueStdout := os.Stdout
r, w, err := os.Pipe()
if err != nil {
a.log.Errorln("Unable to pipe STDOUT, Reason: ", err)
a.sendError("Unable to pipe STDOUT, Reason: ", err)
return ""
}
os.Stdout = w
err = a.runWalletCMD("wallet", "show-address", "--keystore="+a.wallet.KeyStorePath, "--alias="+a.wallet.WalletAlias, "--env_args=true")
if err != nil {
a.sendError("Unable to generate wallet address. Reason:", err)
a.log.Errorf("Unable to generate wallet address. Reason: %s", err.Error())
return ""
}
w.Close()
dagAddress, err := ioutil.ReadAll(r)
if err != nil {
a.log.Errorln("Unable to read address from STDOUT", err)
a.sendError("Unable to read address from STDOUT", err)
}
os.Stdout = rescueStdout
a.wallet.Address = string(dagAddress[:40])
return a.wallet.Address
}
// CheckAndFetchWalletCLI will download the cl-wallet dependencies from
// the official Constellation Repo
func (a *WalletApplication) CheckAndFetchWalletCLI() bool {
keytoolPath := a.paths.DAGDir + "/cl-keytool.jar"
walletPath := a.paths.DAGDir + "/cl-wallet.jar"
keytoolExists := a.fileExists(keytoolPath)
walletExists := a.fileExists(walletPath)
if keytoolExists && walletExists {
return true
}
if keytoolExists {
a.log.Info(keytoolPath + " file exists. Skipping downloading")
} else {
if err := a.fetchWalletJar("cl-keytool.jar", keytoolPath); err != nil {
a.log.Errorln("Unable to fetch or store cl-keytool.jar", err)
return false
}
}
if walletExists {
a.log.Info(walletPath + " file exists. Skipping downloading")
} else {
if err := a.fetchWalletJar("cl-wallet.jar", walletPath); err != nil {
a.log.Errorln("Unable to fetch or store cl-wallet.jar", err)
return false
}
}
if a.fileExists(keytoolPath) && a.fileExists(walletPath) {
return true
} else {
return false
}
}
// produceTXObject will put an actual transaction on the network. This is called from the
// transactions.go file, more specifically the sendTransaction func. This in turn is triggered
// from the frontend (Transactions.vue) and the tx func. note you can either pass a priv key like
// or pass in a path to an encrypted .p12 file
// java -jar cl-wallet.jar create-transaction --keystore testkey.p12 --alias alias --storepass storepass --keypass keypass -d DAG6o9dcxo2QXCuJS8wnrR944YhFBpwc2jsh5j8f -p prev_tx -f new_tx --fee 0 --amount 1
func (a *WalletApplication) produceTXObject(amount int64, fee int64, address, newTX, prevTX string) {
// Convert to string
amountStr := strconv.FormatInt(amount, 10)
// feeStr := strconv.FormatInt(fee, 10)
// amountNorm, err := normalizeAmounts(amount)
// if err != nil {
// a.log.Errorln("Unable to normalize amounts when producing tx object. Reason: ", err)
// a.sendError("Unable to send transaction. Don't worry, your funds are safe. Please report this issue. Reason: ", err)
// return
// }
feeNorm, err := normalizeAmounts(fee)
if err != nil {
a.log.Errorln("Unable to normalize amounts when producing tx object. Reason: ", err)
a.sendError("Unable to send transaction. Don't worry, your funds are safe. Please report this issue. Reason: ", err)
return
}
// newTX is the full command to sign a new transaction
err = a.runWalletCMD("wallet", "create-transaction", "--keystore="+a.wallet.KeyStorePath, "--normalized", "--alias="+a.wallet.WalletAlias, "--amount="+amountStr, "--fee="+feeNorm, "-d="+address, "-f="+newTX, "-p="+prevTX, "--env_args=true")
if err != nil {
a.sendError("Unable to send transaction. Don't worry, your funds are safe. Please report this issue. Reason: ", err)
a.log.Errorln("Unable to send transaction. Reason: ", err)
return
}
time.Sleep(1 * time.Second) // Will sleep for 1 sec between TXs to prevent spamming.
}
// CreateEncryptedKeyStore is called ONLY when a NEW wallet is created. This
// will create a new password protected encrypted keypair stored in user selected location
// java -jar cl-keytool.jar --keystore testkey.p12 --alias alias --storepass storepass --keypass keypass
func (a *WalletApplication) CreateEncryptedKeyStore() error {
err := a.runWalletCMD("keytool", "--keystore="+a.wallet.KeyStorePath, "--alias="+a.wallet.WalletAlias, "--env_args=true")
if err != nil {
a.LoginError("Unable to write encrypted keys to filesystem.")
a.log.Errorf("Unable to write encrypted keys to filesystem. Reason: %s", err.Error())
return err
}
return nil
}

252
gui_wails01_learn/backend/buildchain.go

@ -0,0 +1,252 @@
package app
import (
"encoding/json"
"io/ioutil"
"net/http"
"github.com/grvlle/constellation_wallet/backend/models"
)
// formTXChain retains the order of the blockchain across all accounts.
// Also calls the methods to create block objects (write json to file),
// and the method that pushes them to the network(HTTP POST).
// To retain order, formTXChain will poll the last sent TX for it's Failed state.
// if the last TX failed, it'll switch up the order to account for that not to break the chain.
// This means that all failed attempts at creating a block is also stored in the DB with
// a Failed state.
func (a *WalletApplication) formTXChain(amount int64, fee int64, address string, ptxObj *Transaction, ltxObj *Transaction) {
statusLastTX := models.TXHistory{}
if err := a.DB.Last(&statusLastTX).Error; err != nil {
a.log.Warnln("No previous TX detected for this wallet. Reason: ", err)
}
if statusLastTX.Failed {
a.log.Warnln("Previous Transaction has a failed state. Adapting...", statusLastTX.Failed)
}
// Queries the number of previous transactions for this wallet.
numberOfTX := a.DB.Model(&a.wallet).Association("TXHistory").Count()
// First TX does not contain a TXref
if numberOfTX == 0 {
a.log.Infoln("Detected that this is the first TX sent from this key.")
a.produceTXObject(amount, fee, address, a.paths.LastTXFile, a.paths.EmptyTXFile)
a.sendTransaction(a.paths.LastTXFile)
return
}
a.log.Infoln("Number of previous TX's detected: ", numberOfTX)
// Manually control the second TX, to ensure the following order
if numberOfTX == 1 {
// If the first transaction failed, enforce the order.
if statusLastTX.Failed {
a.log.Warnln("Detected that the previous transaction failed.")
a.produceTXObject(amount, fee, address, a.paths.LastTXFile, a.paths.EmptyTXFile)
a.sendTransaction(a.paths.LastTXFile)
return
}
// Check for edge case where PrevTXFile has already been written and needs to be referenced.
// This occurs when a wallet with 1 previous tx has been imported.
prevTXFileContents := a.loadTXFromFile(a.paths.PrevTXFile)
if a.WalletImported && prevTXFileContents != "" {
a.log.Warnln("One previous transaction has been imported. Using that as reference.")
a.produceTXObject(amount, fee, address, a.paths.LastTXFile, a.paths.PrevTXFile)
a.sendTransaction(a.paths.LastTXFile)
return
}
a.produceTXObject(amount, fee, address, a.paths.PrevTXFile, a.paths.LastTXFile)
a.sendTransaction(a.paths.PrevTXFile)
return
}
// Returns the TX object that has the highest ordinal (the highest determines if it's to be referenced or reference the other tx)
newTX := a.determineBlockOrder(ptxObj, ltxObj)
// If the last TX is in failed state, we reset the order.
if newTX == a.paths.PrevTXFile && statusLastTX.Failed {
a.produceTXObject(amount, fee, address, a.paths.LastTXFile, a.paths.PrevTXFile)
a.sendTransaction(a.paths.LastTXFile)
return
}
if newTX != a.paths.PrevTXFile && !statusLastTX.Failed {
a.produceTXObject(amount, fee, address, a.paths.LastTXFile, a.paths.PrevTXFile)
a.sendTransaction(a.paths.LastTXFile)
return
}
a.produceTXObject(amount, fee, address, a.paths.PrevTXFile, a.paths.LastTXFile)
a.sendTransaction(a.paths.PrevTXFile)
}
func (a *WalletApplication) determineBlockOrder(ptxObj, ltxObj *Transaction) string {
// The higher ordinal will always be the TX carrying the TX Ref.
a.log.Info("Last TX Ordinal: ", ltxObj.LastTxRef.Ordinal, " Previous TX Ordinal: ", ptxObj.LastTxRef.Ordinal)
if ltxObj.LastTxRef.Ordinal > ptxObj.LastTxRef.Ordinal {
return a.paths.PrevTXFile
}
return a.paths.LastTXFile
}
// convertToTXObject takes the Path to the prev_tx and last_tx files and returns a
// pointer to two workable objects.
func (a *WalletApplication) convertToTXObject(ptx, ltx string) (*Transaction, *Transaction) {
var ptxObj Transaction
var ltxObj Transaction
rbytes := []byte(ptx)
lbytes := []byte(ltx)
err := json.Unmarshal(rbytes, &ptxObj)
if err != nil {
a.log.Warnln("TX Object: ", string(rbytes), err)
}
err = json.Unmarshal(lbytes, &ltxObj)
if err != nil {
a.log.Warnln("TX Object: ", string(rbytes), err)
}
return &ptxObj, &ltxObj
}
/* Called upon wallet import */
// TXReference is used to parse the previous tx of an imported wallet.
type TXReference struct {
Hash string `json:"hash"`
Amount int64 `json:"amount"`
Receiver string `json:"receiver"`
Sender string `json:"sender"`
Fee int `json:"fee"`
IsDummy bool `json:"isDummy"`
LastTransactionRef struct {
PrevHash string `json:"prevHash"`
Ordinal int `json:"ordinal"`
} `json:"lastTransactionRef"`
SnapshotHash string `json:"snapshotHash"`
CheckpointBlock string `json:"checkpointBlock"`
TransactionOriginal struct {
Edge struct {
ObservationEdge struct {
Parents []struct {
HashReference string `json:"hashReference"`
HashType string `json:"hashType"`
BaseHash string `json:"baseHash"`
} `json:"parents"`
Data struct {
HashReference string `json:"hashReference"`
HashType string `json:"hashType"`
BaseHash string `json:"baseHash"`
} `json:"data"`
} `json:"observationEdge"`
SignedObservationEdge struct {
SignatureBatch struct {
Hash string `json:"hash"`
Signatures []struct {
Signature string `json:"signature"`
ID struct {
Hex string `json:"hex"`
} `json:"id"`
} `json:"signatures"`
} `json:"signatureBatch"`
} `json:"signedObservationEdge"`
Data struct {
Amount int64 `json:"amount"`
LastTxRef struct {
PrevHash string `json:"prevHash"`
Ordinal int `json:"ordinal"`
} `json:"lastTxRef"`
Fee interface{} `json:"fee"`
Salt int64 `json:"salt"`
} `json:"data"`
} `json:"edge"`
LastTxRef struct {
PrevHash string `json:"prevHash"`
Ordinal int `json:"ordinal"`
} `json:"lastTxRef"`
IsDummy bool `json:"isDummy"`
IsTest bool `json:"isTest"`
} `json:"transactionOriginal"`
}
// rebuildTxChainState will query the blockexplorer for a transacion and write it to a.paths.PrevTXFile.
// This will allow an imported wallet to reference the last transaction sent.
func (a *WalletApplication) rebuildTxChainState(lastTXHash string) error {
a.log.Info("Sending API call to block explorer on: " + a.Network.BlockExplorer.Handles.Transactions)
resp, err := http.Get(a.Network.BlockExplorer.URL + a.Network.BlockExplorer.Handles.Transactions + lastTXHash)
if err != nil {
a.log.Errorln("Failed to send HTTP request. Reason: ", err)
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Delete(&a.wallet).Error; err != nil {
a.log.Errorln("Unable to delete wallet upon failed import. Reason: ", err)
return err
}
a.LoginError("Unable to collect previous TX's from blockexplorer. Please check your internet connection.")
return err
}
defer resp.Body.Close()
if resp.Body != nil {
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
a.LoginError("Unable to collect previous TX's from blockexplorer. Please try again later.")
a.log.Errorln("Unable to collect previous TX's from blockexplorer. Reason: ", err)
}
ok, error := a.verifyAPIResponse(bodyBytes)
// Blockexplorer returns below string when no previous transactions are found
if !ok && error != "Cannot find transaction" {
a.log.Errorln("API returned the following error", error)
// If unable to import last transaction, remove wallet from DB and logout.
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Delete(&a.wallet).Error; err != nil {
a.log.Errorln("Unable to delete wallet upon failed import. Reason: ", err)
return err
}
a.log.Panicln("Unable to import previous transactions") // TODO: logout user from wallet
a.LoginError("The wallet import failed. Please check your internet connection and try again.")
return err
}
// Parsing JSON object to TXReference ->
lastTX := TXReference{}
err = json.Unmarshal(bodyBytes, &lastTX)
if err != nil {
a.log.Errorln("Unable to fetch TX history from block explorer. Reason: ", err)
a.sendError("Unable to fetch TX history from block explorer. Reason: ", err)
return err
}
// Marshal so that we can unmarshat into tx object ->
b, err := json.Marshal(lastTX.TransactionOriginal)
if err != nil {
a.log.Errorln("Unable to parse last transaction hash. Reason: ", err)
a.sendError("Unable to fetch TX history from block explorer. Reason: ", err)
return err
}
// Populating tx object ->
tx := Transaction{}
err = json.Unmarshal(b, &tx)
if err != nil {
a.log.Errorln("Unable to parse last transaction hash. Reason: ", err)
a.sendError("Unable to fetch TX history from block explorer. Reason: ", err)
return err
}
// Converting to json
txBytes, err := json.Marshal(tx)
if err != nil {
a.log.Errorln("Unable to parse last transaction hash. Reason: ", err)
a.sendError("Unable to fetch TX history from block explorer. Reason: ", err)
return err
}
err = WriteToFile(a.paths.PrevTXFile, txBytes)
if err != nil {
return err
}
}
return nil
}

441
gui_wails01_learn/backend/cmd/update/main.go

@ -0,0 +1,441 @@
package main
import (
"crypto/sha256"
"encoding/hex"
"flag"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/rpc"
"os"
"os/exec"
"path"
"runtime"
"strings"
"time"
"github.com/artdarek/go-unzip"
log "github.com/sirupsen/logrus"
)
func init() {
// initialize update.log file and set log output to file
file, err := os.OpenFile(path.Join(getDefaultDagFolderPath(), "update.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err == nil {
log.SetOutput(file)
} else {
log.Info("Failed to log to file, using default stderr")
}
// Only log the warning severity or above.
log.SetLevel(log.InfoLevel)
}
// Update type contains the update processes mandatory data
type Update struct {
clientRPC *rpc.Client
downloadURL string
dagFolderPath *string
oldMollyBinaryPath *string
newVersion *string
triggerUpdate *bool
}
// Signal is used for IPC with MollyWallet
type Signal struct {
PID int
Msg string
}
type unzippedContents struct {
newMollyBinaryPath string
updateBinaryPath string
}
func main() {
var update Update
update.downloadURL = "https://github.com/grvlle/constellation_wallet/releases/download"
// MollyWallet provides the below data when an update is triggered
update.dagFolderPath = flag.String("init_dag_path", getDefaultDagFolderPath(), "Enter the directory path to dag folder")
update.oldMollyBinaryPath = flag.String("init_molly_path", "", "Enter the directory path where the molly binary is located")
update.newVersion = flag.String("new_version", "", "Enter the new semantic version. E.g 1.2.3")
update.triggerUpdate = flag.Bool("upgrade", false, "Upgrade molly wallet binary")
flag.Parse()
update.Run()
}
// Run is the main method that runs the full update.
func (u *Update) Run() {
var err error
// Clean up old update artifacts
err = u.CleanUp()
if err != nil {
log.Fatalf("Unable to clear previous local state: %v", err)
}
// Create a TCP connection to localhost on port 36866
u.clientRPC, err = rpc.DialHTTP("tcp", "localhost:36866")
if err != nil {
log.Fatal("Connection error: ", err)
}
log.Infof("Successfully established RPC connection with Molly Wallet")
defer u.clientRPC.Close()
zippedArchive, err := u.DownloadAppBinary()
if err != nil {
log.Fatalf("Unable to download v%s of Molly Wallet: %v", *u.newVersion, err)
}
ok, err := u.VerifyChecksum(zippedArchive)
if err != nil || !ok {
log.Fatalf("Checksum missmatch. Corrupted download: %v", err)
}
contents, err := unzipArchive(zippedArchive, *u.dagFolderPath)
if err != nil {
log.Fatalf("Unable to unzip contents: %v", err)
}
err = u.BackupApp()
if err != nil {
log.Fatalf("Unable to Backup Molly Wallet: %v", err)
}
err = u.TerminateAppService()
if err != nil {
log.Errorf("Unable to terminate Molly Wallet: %v", err)
err = u.RestoreBackup()
if err != nil {
log.Fatal("Unable to restore backup: %v", err)
}
}
err = u.ReplaceAppBinary(contents)
if err != nil {
log.Errorf("Unable to overwrite old installation: %v", err)
err = u.RestoreBackup()
if err != nil {
log.Fatalf("Unable to restore backup: %v", err)
}
}
err = u.LaunchAppBinary()
if err != nil {
log.Errorf("Unable to start up Molly after update: %v", err)
err = u.RestoreBackup()
if err != nil {
log.Fatalf("Unable to restore backup: %v", err)
}
}
err = u.CleanUp()
if err != nil {
log.Fatalf("Unable to clear previous local state: %v", err)
}
}
// DownloadAppBinary downloads the latest Molly Wallet zip from github releases and returns the path to it
func (u *Update) DownloadAppBinary() (string, error) {
filename := "mollywallet.zip"
osBuild, _ := getUserOS() // returns linux, windows, darwin or unsupported as well as the file extension (e.g ".exe")
if osBuild == "unsupported" {
return "", fmt.Errorf("the OS is not supported")
}
url := u.downloadURL + "/v" + *u.newVersion + "-" + osBuild + "/" + filename
// e.g https://github.com/grvlle/constellation_wallet/releases/download/v1.1.9-linux/mollywallet.zip
log.Infof("Constructed the following URL: %s", url)
filePath := path.Join(*u.dagFolderPath, filename)
err := downloadFile(url, filePath)
if err != nil {
return "", fmt.Errorf("unable to download remote checksum: %v", err)
}
return filePath, nil
}
// VerifyChecksum takes a file path and will check the file sha256 checksum against the checksum included
// in the downlaod returns false if there's a missmatch
func (u *Update) VerifyChecksum(filePathZip string) (bool, error) {
// Download checksum
filename := "checksum.sha256"
osBuild, _ := getUserOS() // returns linux, windows, darwin or unsupported as well as the file extension (e.g ".exe")
if osBuild == "unsupported" {
return false, fmt.Errorf("the OS is not supported")
}
url := u.downloadURL + "/v" + *u.newVersion + "-" + osBuild + "/" + filename
// e.g https://github.com/grvlle/constellation_wallet/releases/download/v1.1.9-linux/checksum.sha256
log.Infof("Constructed the following URL: %s", url)
filePath := path.Join(*u.dagFolderPath, filename)
err := downloadFile(url, filePath)
if err != nil {
return false, fmt.Errorf("unable to download remote checksum: %v", err)
}
// Read the contents of the downloaded file (remoteChecksum)
content, err := ioutil.ReadFile(filePath)
if err != nil {
return false, err
}
lines := strings.Split(string(content), "\n")
remoteChecksum := lines[0]
log.Infof("Remote file checksum: %v", remoteChecksum)
// Collect the checksum of the downloaded zip (localChecksum)
f, err := os.Open(filePathZip)
if err != nil {
return false, err
}
defer f.Close()
hasher := sha256.New()
if _, err := io.Copy(hasher, f); err != nil {
return false, err
}
localChecksum := hex.EncodeToString(hasher.Sum(nil))
log.Infof("Local file checksum: %v", localChecksum)
return remoteChecksum == localChecksum, nil
}
// TerminateAppService will send an RPC to mollywallet to terminate the application
func (u *Update) TerminateAppService() error {
sig := Signal{0, "Terminate Molly Wallet. Begining Update..."}
var response Signal
err := u.clientRPC.Call("RPCEndpoints.ShutDown", sig, &response)
if err != nil {
return err
}
proc, err := os.FindProcess(response.PID)
if err != nil {
log.Panicf("%v", err)
}
err = proc.Kill()
if err != nil {
return err
}
return nil
}
// BackupApp backs up the old binary in case of a failed update.
func (u *Update) BackupApp() error {
_, fileExt := getUserOS()
// Create backup folder in ~/.dag
err := os.Mkdir(*u.dagFolderPath+"/backup", 0755)
if err != nil {
return fmt.Errorf("unable to create backup folder: %v", err)
}
// Copy the old Molly Wallet binary into ~/.dag/backup/
err = copy(*u.oldMollyBinaryPath, *u.dagFolderPath+"/backup/mollywallet"+fileExt)
if err != nil {
return fmt.Errorf("unable to backup old Molly installation: %v", err)
}
return nil
}
// ReplaceAppBinary replaces the old update module and molly binary with the newly downloaded ones.
func (u *Update) ReplaceAppBinary(contents *unzippedContents) error {
// Replace old molly binary with the new one
_, fileExt := getUserOS()
err := copy(contents.newMollyBinaryPath, *u.oldMollyBinaryPath)
if err != nil {
for i := 5; i > 0; i-- {
time.Sleep(time.Duration(i) * time.Second)
err = copy(contents.newMollyBinaryPath, *u.oldMollyBinaryPath)
if err == nil {
break
} else if err != nil && i == 0 {
return fmt.Errorf("unable to overwrite old molly binary: %v", err)
}
}
}
// Replace old update binary with the new one
if fileExists(contents.updateBinaryPath) {
err = copy(contents.updateBinaryPath, *u.dagFolderPath+"/update"+fileExt)
if err != nil {
return fmt.Errorf("unable to copy update binary to .dag folder: %v", err)
}
}
return nil
}
// LaunchAppBinary executes the new molly binary
func (u *Update) LaunchAppBinary() error {
cmd := exec.Command(*u.oldMollyBinaryPath)
err := cmd.Start()
if err != nil {
return fmt.Errorf("unable to execute run command for Molly Wallet: %v", err)
}
return nil
}
// RestoreBackup restores the backed up files
func (u *Update) RestoreBackup() error {
log.Infoln("Restoring Backup...")
// Copy the old Molly Wallet binary from ~/.dag/backup/ to the old path
_, fileExt := getUserOS()
err := copy(*u.dagFolderPath+"/backup/mollywallet"+fileExt, *u.oldMollyBinaryPath)
if err != nil {
return fmt.Errorf("unable to overwrite old molly binary: %v", err)
}
// Copy update binary from ~/.dag/backup/update -> ~/.dag/update
if fileExists(*u.dagFolderPath + "/backup/update" + fileExt) {
err = copy(*u.dagFolderPath+"/backup/update"+fileExt, *u.dagFolderPath+"/update"+fileExt)
if err != nil {
return fmt.Errorf("unable to copy update binary to .dag folder: %v", err)
}
}
log.Infoln("Backup successfully restored.")
return nil
}
// CleanUp removes uneccesary artifacts from the update process
func (u *Update) CleanUp() error {
if fileExists(*u.dagFolderPath + "/mollywallet.zip") {
err := os.Remove(*u.dagFolderPath + "/mollywallet.zip")
if err != nil {
return err
}
}
if fileExists(*u.dagFolderPath + "/backup") {
err := os.RemoveAll(*u.dagFolderPath + "/backup")
if err != nil {
return err
}
}
if fileExists(*u.dagFolderPath + "/new_build") {
err := os.RemoveAll(*u.dagFolderPath + "/new_build")
if err != nil {
return err
}
}
return nil
}
func downloadFile(url, filePath string) error {
tmpFilePath := filePath + ".tmp"
out, err := os.Create(tmpFilePath)
if err != nil {
return err
}
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
if _, err = io.Copy(out, resp.Body); err != nil {
return err
}
out.Close() // Close file to rename
if err = os.Rename(tmpFilePath, filePath); err != nil {
return err
}
return nil
}
func getDefaultDagFolderPath() string {
userDir, err := os.UserHomeDir()
if err != nil {
log.Errorf("Unable to detect UserHomeDir: %v", err)
return ""
}
return userDir + "/.dag"
}
func fileExists(path string) bool {
_, err := os.Stat(path)
if os.IsNotExist(err) {
return false
}
return !os.IsNotExist(err)
}
func copy(src string, dst string) error {
// Read all content of src to data
data, err := ioutil.ReadFile(src)
if err != nil {
return err
}
// Write data to dst
err = ioutil.WriteFile(dst, data, 0755)
if err != nil {
return err
}
return nil
}
// Unzips archive to dstPath, returns path to wallet binary
func unzipArchive(zippedArchive, dstPath string) (*unzippedContents, error) {
uz := unzip.New(zippedArchive, dstPath+"/"+"new_build/")
err := uz.Extract()
if err != nil {
return nil, err
}
_, fileExt := getUserOS()
contents := &unzippedContents{
newMollyBinaryPath: dstPath + "/" + "new_build/mollywallet" + fileExt,
updateBinaryPath: dstPath + "/" + "new_build/update" + fileExt,
}
return contents, err
}
// getUserOS returns the users OS as well as the file extension of executables for said OS
func getUserOS() (string, string) {
var osBuild string
var fileExt string
switch os := runtime.GOOS; os {
case "darwin":
osBuild = "darwin"
fileExt = ""
case "linux":
osBuild = "linux"
fileExt = ""
case "windows":
osBuild = "windows"
fileExt = ".exe"
default:
osBuild = "unsupported"
fileExt = ""
}
return osBuild, fileExt
}

393
gui_wails01_learn/backend/dashboard.go

@ -0,0 +1,393 @@
package app
import (
"encoding/json"
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"strconv"
"time"
"github.com/wailsapp/wails"
)
const (
dummyValue = 1000
updateIntervalToken = 30 // Seconds
updateIntervalCurrency = 50 // Seconds
updateIntervalBlocks = 5 // Seconds
updateIntervalPieChart = 60 // Seconds
)
// ChartData contains all the datapoints for the Charts
// on the Dashboard.
type ChartData struct {
NodesOnline struct {
Labels []string `json:"labels"`
Series []int `json:"series"`
} `json:"nodes_online"`
Transactions struct {
Labels []string `json:"labels"`
SeriesOne []int `json:"series_one"`
SeriesTwo []int `json:"series_two"`
} `json:"transactions"`
Throughput struct {
Labels []string `json:"labels"`
SeriesOne []int `json:"series_one"`
SeriesTwo []int `json:"series_two"`
} `json:"throughput"`
}
// ChartDataInit initializes the ChartData struct with datapoints for
// the charts in the wallet. These are stored on the fs as chart_data.json
func (a *WalletApplication) ChartDataInit() *ChartData {
cd := &ChartData{}
cd.NodesOnline.Labels = []string{"30%", "20%", "50%"}
cd.NodesOnline.Series = []int{30, 20, 50}
cd.Transactions.Labels = []string{
"Jan ",
"Feb ",
"Mar ",
"Apr ",
"Mai ",
"Jun ",
"Jul ",
"Aug ",
"Sep ",
"Oct ",
"Nov ",
"Dec "}
cd.Transactions.SeriesOne = []int{542, 543, 520, 680, 653, 753, 326, 434, 568, 610, 756, 895}
cd.Transactions.SeriesTwo = []int{230, 293, 380, 480, 503, 553, 600, 664, 698, 710, 736, 795}
cd.Throughput.Labels = []string{
"9AM",
"12AM",
"3PM",
"6PM",
"9PM",
"12PM",
"3AM",
"6AM"}
cd.Throughput.SeriesOne = []int{287, 385, 490, 562, 594, 626, 698, 895, 952}
cd.Throughput.SeriesTwo = []int{67, 152, 193, 240, 387, 435, 535, 642, 744}
// Init chart widgets with data.
go func() {
select {
case <-a.killSignal:
return
default:
for i := 0; i < 2; i++ {
a.RT.Events.Emit("tx_stats", cd.Transactions.SeriesOne, cd.Transactions.SeriesTwo, cd.Transactions.Labels)
a.RT.Events.Emit("node_stats", cd.NodesOnline.Series, cd.NodesOnline.Labels)
a.RT.Events.Emit("network_stats", cd.Throughput.SeriesOne, cd.Throughput.SeriesTwo, cd.Throughput.Labels)
time.Sleep(1 * time.Second)
}
}
}()
return cd
}
// Populates the Nodes Online pie chart with data from the block explorer.
func (a *WalletApplication) nodeStats(cd *ChartData) {
go func() {
for {
select {
case <-a.killSignal:
return
default:
// Will populate the chart with random data
for i := range cd.NodesOnline.Series {
cd.NodesOnline.Series[i] = rand.Intn(dummyValue)
}
a.RT.Events.Emit("node_stats", cd.NodesOnline.Series, cd.NodesOnline.Labels)
UpdateCounter(updateIntervalPieChart, "chart_counter", time.Second, a.RT)
time.Sleep(updateIntervalPieChart * time.Second)
}
}
}()
}
func (a *WalletApplication) txStats(cd *ChartData) {
go func() {
for {
select {
case <-a.killSignal:
return
default:
// Will populate the chart with random data
for i := range cd.Transactions.SeriesOne {
cd.Transactions.SeriesOne[i] = rand.Intn(dummyValue)
}
for i := range cd.Transactions.SeriesTwo {
cd.Transactions.SeriesTwo[i] = rand.Intn(dummyValue)
}
a.RT.Events.Emit("tx_stats", cd.Transactions.SeriesOne, cd.Transactions.SeriesTwo, cd.Transactions.Labels)
//UpdateCounter(updateIntervalPieChart, "chart_counter", time.Second, a.RT)
time.Sleep(updateIntervalPieChart * time.Second)
}
}
}()
}
func (a *WalletApplication) networkStats(cd *ChartData) {
go func() {
for {
select {
case <-a.killSignal:
return
default:
// Will populate the chart with random data
for i := range cd.Throughput.SeriesOne {
cd.Throughput.SeriesOne[i] = rand.Intn(dummyValue)
}
for i := range cd.Throughput.SeriesTwo {
cd.Throughput.SeriesTwo[i] = rand.Intn(dummyValue)
}
a.RT.Events.Emit("network_stats", cd.Throughput.SeriesOne, cd.Throughput.SeriesTwo, cd.Throughput.Labels)
//UpdateCounter(updateIntervalPieChart, "chart_counter", time.Second, a.RT)
time.Sleep(updateIntervalPieChart * time.Second)
}
}
}()
}
// BlockAmount is a temporary function
func (a *WalletApplication) blockAmount() {
var randomNumber int
go func() {
for {
select {
case <-a.killSignal:
return
default:
randomNumber = rand.Intn(dummyValue)
a.RT.Events.Emit("blocks", randomNumber)
UpdateCounter(updateIntervalBlocks, "block_counter", time.Second, a.RT)
time.Sleep(updateIntervalBlocks * time.Second)
}
}
}()
}
func (a *WalletApplication) pollTokenBalance() {
go func() {
retryCounter := 1
for {
select {
case <-a.killSignal:
return
default:
time.Sleep(time.Duration(retryCounter) * time.Second) // Incremental backoff
for retryCounter <= 20 && a.wallet.Address != "" {
balance, err := a.GetTokenBalance()
if err != nil {
retryCounter++
break
}
a.log.Infoln("Current Balance: ", balance)
a.wallet.Balance, a.wallet.AvailableBalance, a.wallet.TotalBalance = balance, balance, balance
a.RT.Events.Emit("token", a.wallet.Balance, a.wallet.AvailableBalance, a.wallet.TotalBalance)
UpdateCounter(updateIntervalToken, "token_counter", time.Second, a.RT)
time.Sleep(updateIntervalToken * time.Second)
}
}
}
}()
}
// pricePoller polls the min-api.cryptocompare REST API for DAG token value.
// Once polled, it'll Emit the token value to Dashboard.vue for full token
// balance evaluation against USD.
func (a *WalletApplication) pricePoller() {
const (
apiKey string = "17b10afdddc411087e2140ec91bd73d88d0c20294541838b192255fc574b1cb7"
ticker string = "DAG"
url string = "https://min-api.cryptocompare.com/data/pricemulti?fsyms=" + ticker + "&tsyms=BTC,USD,EUR&api_key=" + apiKey
)
go func() {
retryCounter := 1
time.Sleep(3 * time.Second) // Give some space to pollTokenBalance
for {
select {
case <-a.killSignal:
return
default:
a.wallet.TokenPrice.DAG.USD = 0
a.wallet.TokenPrice.DAG.EUR = 0
a.wallet.TokenPrice.DAG.BTC = 0
time.Sleep(time.Duration(retryCounter) * time.Second) // Incremental backoff
for retryCounter <= 20 && a.wallet.Balance != 0 {
a.log.Infoln("Contacting token evaluation API on: " + url + ticker)
resp, err := http.Get(url)
if err != nil {
a.log.Warnln("Unable to poll token evaluation. Reason: ", err) // Log this
retryCounter++
break
}
if resp == nil {
retryCounter++
a.log.Errorln("Killing pollTokenBalance after 10 failed attempts to get balance from mainnet, Reason: ", err)
a.sendWarning("Unable to showcase token USD evaluation. Please check your internet connectivity and restart the wallet application.")
break
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
retryCounter++
a.sendError("Unable to read HTTP resonse from Token API. Reason: ", err)
a.log.Warnln("Unable to read HTTP resonse from Token API. Reason: ", err)
break
}
err = json.Unmarshal([]byte(body), &a.wallet.TokenPrice)
if err != nil {
retryCounter++
a.sendError("Unable to display token price. Reason: ", err)
a.log.Warnln("Unable to display token price. Reason:", err)
break
}
if a.wallet.Balance != 0 && a.wallet.TokenPrice.DAG.USD == 0 {
a.log.Infoln("Contacting alternate token evaluation API")
a.wallet.TokenPrice.DAG.USD, a.wallet.TokenPrice.DAG.BTC, err = getTokenPriceAlternateRoute()
if err != nil {
a.log.Errorln("Failed to fetch token metrics using alternate endpoint. Reason: ", err)
if retryCounter == 10 || retryCounter == 15 || retryCounter == 20 {
warn := fmt.Sprintf("No data recieved from Token Price API. Will try again in %v seconds.", retryCounter)
a.sendWarning(warn)
}
retryCounter++
break
}
}
a.log.Infof("Collected token price in USD: %v", a.wallet.TokenPrice.DAG.USD)
a.log.Infof("Collected token price in EUR: %v", a.wallet.TokenPrice.DAG.EUR)
a.log.Infof("Collected token price in BTC: %v", a.wallet.TokenPrice.DAG.BTC)
totalCurrencyBalance := 0.0
if a.wallet.Currency == "USD" {
totalCurrencyBalance = float64(a.wallet.Balance) * a.wallet.TokenPrice.DAG.USD
} else if a.wallet.Currency == "EUR" {
totalCurrencyBalance = float64(a.wallet.Balance) * a.wallet.TokenPrice.DAG.EUR
} else if a.wallet.Currency == "BTC" {
totalCurrencyBalance = float64(a.wallet.Balance) * a.wallet.TokenPrice.DAG.BTC
}
a.RT.Events.Emit("totalValue", a.wallet.Currency, totalCurrencyBalance)
UpdateCounter(updateIntervalCurrency, "value_counter", time.Second, a.RT)
time.Sleep(updateIntervalCurrency * time.Second)
}
}
}
}()
}
// StoreTermsOfServiceStateDB stores the Terms of Service state in the user DB
func (a *WalletApplication) StoreTermsOfServiceStateDB(termsOfService bool) bool {
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Update("TermsOfService", termsOfService).Error; err != nil {
a.log.Errorln("Unable to store termsOfService state. Reason: ", err)
a.sendError("Unable to store termsOfService state persistently. Reason: ", err)
return false
}
return true
}
type tokenPriceAlt struct {
Code string `json:"code"`
Data struct {
Sequence string `json:"sequence"`
BestAsk string `json:"bestAsk"`
Size string `json:"size"`
Price string `json:"price"`
BestBidSize string `json:"bestBidSize"`
Time int64 `json:"time"`
BestBid string `json:"bestBid"`
BestAskSize string `json:"bestAskSize"`
} `json:"data"`
}
// getTokenPriceAlternateRoute will kick in in case the main token poller API will return
// broken payload.
func getTokenPriceAlternateRoute() (float64, float64, error) {
var tokenpriceUSD, tokenpriceBTC float64
var err error
tpa := new(tokenPriceAlt)
const (
url = "https://api.kucoin.com/api/v1/market/orderbook/level1?symbol="
usdTicker = "DAG-USDT"
btcTicker = "DAG-BTC"
)
tickers := []string{usdTicker, btcTicker}
for _, tick := range tickers {
resp, err := http.Get(url + tick)
if err != nil {
return 0, 0, err
}
// Example resp: {"code":"200000","data":
// {"sequence":"1583079038860","bestAsk":"0.01058",
// "size":"73908.9903","price":"0.01058",
// "bestBidSize":"403.157","time":1589605888009,
// "bestBid":"0.010539","bestAskSize":"79091.0097"}}
if resp == nil {
return 0, 0, err
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return 0, 0, err
}
err = json.Unmarshal(bodyBytes, &tpa)
if err != nil {
return 0, 0, err
}
s := tpa.Data.Price
balance, err := strconv.ParseFloat(s, 64)
if err != nil {
return 0, 0, err
}
switch {
case tick == usdTicker:
tokenpriceUSD = balance
case tick == btcTicker:
tokenpriceBTC = balance
}
}
return tokenpriceUSD, tokenpriceBTC, err
}
// UpdateCounter will count up from the last time a card was updated.
func UpdateCounter(countFrom int, counter string, unit time.Duration, runtime *wails.Runtime) {
go func() {
for i := countFrom; i > 0; i-- {
runtime.Events.Emit(counter, i)
time.Sleep(unit)
continue
}
}()
}

123
gui_wails01_learn/backend/lcm.go

@ -0,0 +1,123 @@
package app
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
"runtime"
)
type UpdateWallet struct {
currentVersion string
newVersion string
mollyBinaryPath string
dagFolderPath string
app *WalletApplication
}
func (u *UpdateWallet) Run() {
var err error
u.currentVersion = u.app.Version
u.newVersion = u.GetLatestRelease()
u.mollyBinaryPath, err = os.Executable()
if err != nil {
u.app.log.Errorln("Unable to collect the path of the molly wallet binary. Reason: ", err)
}
u.dagFolderPath = u.app.paths.DAGDir
err = u.TriggerUpdate()
if err != nil {
u.app.log.Errorln("Unable to Update Molly Wallet. Reason: ", err)
u.app.sendError("Unable to Update Molly Wallet. Reason: ", err)
}
}
func (u *UpdateWallet) TriggerUpdate() error {
_, fileExt := getUserOS()
main := u.dagFolderPath + "/update" + fileExt
args := []string{"-init_dag_path=" + u.dagFolderPath, "-init_molly_path=" + u.mollyBinaryPath, "-new_version=" + u.newVersion, "-upgrade=" + "true"}
cmd := exec.Command(main, args...)
u.app.log.Infoln("Running command: ", cmd)
var stderr bytes.Buffer
cmd.Stderr = &stderr // Captures STDERR
err := cmd.Run()
if err != nil {
errFormatted := fmt.Sprint(err) + ": " + stderr.String()
return errors.New(errFormatted)
}
return nil
}
func (u *UpdateWallet) GetLatestRelease() string {
const (
url = "https://api.github.com/repos/grvlle/constellation_wallet/releases/latest"
)
resp, err := http.Get(url)
if err != nil {
u.app.log.Errorln("Failed to send HTTP request. Reason: ", err)
return ""
}
if resp == nil {
u.app.log.Errorln("Killing pollTokenBalance after 10 failed attempts to get balance from mainnet, Reason: ", err)
u.app.sendWarning("Unable to showcase current balance. Please check your internet connectivity and restart the wallet application.")
return ""
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
u.app.log.Warn("Unable to update token balance. Reason: ", err)
return ""
}
var result map[string]interface{}
// Unmarshal or Decode the JSON to the interface.
err = json.Unmarshal(bodyBytes, &result)
if err != nil {
return ""
}
release := result["tag_name"]
bytes := []byte(release.(string))
version := string(bytes[1:6])
return version
}
// getUserOS returns the users OS as well as the file extension of executables for said OS
func getUserOS() (string, string) {
var osBuild string
var fileExt string
switch os := runtime.GOOS; os {
case "darwin":
osBuild = "darwin"
fileExt = ""
case "linux":
osBuild = "linux"
fileExt = ""
case "windows":
osBuild = "windows"
fileExt = ".exe"
default:
osBuild = "unsupported"
fileExt = ""
}
return osBuild, fileExt
}

167
gui_wails01_learn/backend/login.go

@ -0,0 +1,167 @@
package app
import (
"os"
"runtime"
"strings"
"github.com/grvlle/constellation_wallet/backend/models"
"golang.org/x/crypto/bcrypt"
)
// LoginError takes a string and pushes it to the login screen as an errror
func (a *WalletApplication) LoginError(errMsg string) {
if errMsg != "" {
a.RT.Events.Emit("login_error", errMsg, true)
}
}
// Login is called from the FE when a user logs in with a wallet object
// already in the DB
func (a *WalletApplication) Login(keystorePath, keystorePassword, keyPassword, alias string) bool {
alias = strings.ToLower(alias)
a.wallet = models.Wallet{
KeyStorePath: keystorePath,
WalletAlias: alias}
if runtime.GOOS == "windows" && !a.javaInstalled() {
a.LoginError("Unable to detect your Java path. Please make sure that Java has been installed.")
return false
}
if !a.TransactionFinished {
a.log.Warn("Cannot login to another wallet during a pending transaction.")
a.LoginError("Cannot login to another wallet during a pending transaction.")
return false
}
if keystorePath == "" {
a.LoginError("Please provide a path to the KeyStore file.")
return false
}
if !a.passwordsProvided(keystorePassword, keyPassword, alias) {
a.log.Warnln("One or more passwords were not provided.")
return false
}
os.Setenv("CL_STOREPASS", keystorePassword)
os.Setenv("CL_KEYPASS", keyPassword)
if err := a.DB.First(&a.wallet, "wallet_alias = ?", alias).Error; err != nil {
a.log.Errorln("Unable to query database object for existing wallet. Reason: ", err)
return a.ImportWallet(keystorePath, keystorePassword, keyPassword, alias)
}
if !a.WalletKeystoreAccess() {
a.LoginError("Access Denied. Please make sure that you have typed in the correct credentials.")
return false
}
if !a.NewUser {
a.DB.Model(&a.wallet).Update("KeystorePath", keystorePath)
a.log.Infoln("PrivateKey path: ", keystorePath)
}
// Check password strings against salted hashes stored in DB. Also make sure KeyStore has been accessed.
if a.CheckAccess(keystorePassword, a.wallet.KeystorePasswordHash) && a.CheckAccess(keyPassword, a.wallet.KeyPasswordHash) && a.KeyStoreAccess {
a.UserLoggedIn = true
// os.Setenv("CL_STOREPASS", keystorePassword)
// os.Setenv("CL_KEYPASS", keyPassword)
} else {
a.UserLoggedIn = false
a.LoginError("Access Denied. Please make sure that you have typed in the correct credentials.")
}
if a.UserLoggedIn && a.KeyStoreAccess && !a.NewUser {
err := a.initWallet(keystorePath)
if err != nil {
a.UserLoggedIn = false
}
}
a.NewUser = false
return a.UserLoggedIn
}
// CheckTermsOfService is called from the FE to check the termsOfService has been accepted
func (a *WalletApplication) CheckTermsOfService() bool {
return a.wallet.TermsOfService
}
// LogOut will reset the wallet UI and clear the wallet objects
func (a *WalletApplication) LogOut() bool {
if a.TransactionFinished {
a.UserLoggedIn = false
a.wallet = models.Wallet{}
return true
}
a.sendWarning("Cannot log out while transaction is processing. Please try again.")
return false
}
// ImportKey is called from the frontend when browsing the fs for a keyfile
func (a *WalletApplication) ImportKey() string {
var keyfile = a.RT.Dialog.SelectFile()
if keyfile == "" {
a.LoginError("Access Denied. No key path detected.")
return ""
}
if keyfile[len(keyfile)-4:] != ".p12" {
a.LoginError("Access Denied. Not a key file.")
return ""
}
a.log.Info("Path to imported key: " + keyfile)
return keyfile
}
// SelectDirToStoreKey is called from the FE when creating a new keyfile
func (a *WalletApplication) SelectDirToStoreKey() string {
var keyfile = a.RT.Dialog.SelectSaveFile()
if len(keyfile) <= 0 {
a.LoginError("No valid path were provided. Please try again.")
return ""
}
if keyfile[len(keyfile)-4:] != ".p12" {
keyfile = keyfile + ".p12"
return keyfile
}
return keyfile
}
// GenerateSaltedHash converts plain text to a salted hash
func (a *WalletApplication) GenerateSaltedHash(s string) (string, error) {
saltedBytes := []byte(s)
hashedBytes, err := bcrypt.GenerateFromPassword(saltedBytes, bcrypt.DefaultCost)
if err != nil {
return "", err
}
hash := string(hashedBytes[:])
return hash, nil
}
// CheckAccess verifies that the user has entered the correct password
func (a *WalletApplication) CheckAccess(password, passwordHash string) bool {
err := a.Compare(password, passwordHash)
if err != nil {
a.log.Warnln("User tried to login with the wrong credentials!")
return false
}
a.log.Infoln("Password check OK")
return true
}
// Compare compares a string with a salted hash
func (a *WalletApplication) Compare(s, hash string) error {
incoming := []byte(s)
existing := []byte(hash)
return bcrypt.CompareHashAndPassword(existing, incoming)
}

4
gui_wails01_learn/backend/models/address.go

@ -0,0 +1,4 @@
package models
// Address holds the DAG address
type Address string

10
gui_wails01_learn/backend/models/path.go

@ -0,0 +1,10 @@
package models
// Path carries the file paths
type Path struct {
ID uint `json:"id"`
Alias string `json:"alias"`
LastTXFile string
PrevTXFile string
EmptyTXFile string
}

19
gui_wails01_learn/backend/models/txhistory.go

@ -0,0 +1,19 @@
package models
// TXHistory stores inidividual transactions
type TXHistory struct {
ID uint `json:"id"`
Alias string `json:"alias"`
Amount int64 `json:"amount"`
Sender string `json:"sender"`
Receiver string `json:"receiver"`
Fee int64 `json:"fee"`
Hash string `json:"hash"`
LastTransactionRef struct {
Hash string `json:"prevHash"`
Ordinal int `json:"ordinal"`
} `json:"lastTransactionRef"`
TS string `json:"date"`
Status string `json:"status"`
Failed bool
}

41
gui_wails01_learn/backend/models/wallet.go

@ -0,0 +1,41 @@
package models
import (
"time"
_ "github.com/jinzhu/gorm/dialects/sqlite"
)
// Wallet holds all wallet information.
type Wallet struct {
ID uint `gorm:"AUTO_INCREMENT"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
Path Path `gorm:"foreignkey:Alias"`
KeystorePasswordHash string
KeyPasswordHash string
KeyStorePath string
WalletAlias string `gorm:"primary_key;unique"`
Addresses []Address `sql:"-"`
TXHistory []TXHistory `gorm:"foreignkey:Alias"`
ProfilePicture string
WalletTag string
DarkMode bool
Currency string
TermsOfService bool
Balance float64 `json:"balance"`
AvailableBalance float64 `json:"available_balance"`
Nonce float64 `json:"nonce"`
TotalBalance float64 `json:"total_balance"`
Delegated float64 `json:"delegated"`
Deposit float64 `json:"deposit"`
Address string `json:"address"`
TokenPrice struct {
DAG struct {
BTC float64 `json:"BTC,omitempty"`
USD float64 `json:"USD,omitempty"`
EUR float64 `json:"EUR,omitempty"`
} `json:"DAG"`
} `json:"token_price"`
}

166
gui_wails01_learn/backend/settings.go

@ -0,0 +1,166 @@
package app
import (
"image"
"image/jpeg"
"io"
"os"
"strings"
)
// UploadImage will forward the image path of the selected image.
func (a *WalletApplication) UploadImage() string {
filePath := a.RT.Dialog.SelectFile()
splitPath := strings.Split(filePath, "/")
filename := splitPath[len(splitPath)-1]
a.log.Info("Path to user uploaded image: " + filePath)
err := CopyFile(filePath, a.paths.ImageDir+filename)
if err != nil && filePath != "" {
a.log.Errorln("Unable to copy image. ", err)
a.sendError("Unable to change Image. ", err)
return "None"
}
file, err := os.Open(filePath)
if err != nil && filePath != "" {
a.log.Errorln("Unable to open image. ", err)
a.sendError("Unable to find Image on the path provided. ", err)
return "None"
}
defer file.Close()
img, _, err := image.DecodeConfig(file)
if err != nil {
a.log.Info("Attempting to decode as JPEG")
img, err = jpeg.DecodeConfig(file)
if err != nil {
a.log.Errorln("Unable to decode image configuration", err)
a.sendError("Unable to change Image. ", err)
return "None"
}
}
a.log.Info("Uploaded image resolution is set to ", img.Height, "x", img.Width)
if img.Height >= 201 || img.Width >= 201 {
a.log.Warnf("Image resolution is too big. Cannot be bigger than 200x200 ")
return "None"
}
a.StoreImagePathInDB(filename)
return filename
}
// GetImagePath is called from the Login.Vue. It'll query the DB for the user's profile picture
// and return it to the FE to be displayed.
func (a *WalletApplication) GetImagePath() string {
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Error; err != nil {
a.log.Errorln("Unable to query the DB record for the Image path. Reason: ", err)
a.sendError("Unable to query the DB record for the Image path. Reason: ", err)
return ""
}
a.log.Infoln("Profile Picture selected: ", a.wallet.ProfilePicture)
return a.wallet.ProfilePicture
}
// StoreImagePathInDB stores the path to where the profile picture is located in the database
func (a *WalletApplication) StoreImagePathInDB(path string) bool {
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Update("ProfilePicture", path).Error; err != nil {
a.log.Errorln("Unable to update the DB record with the Image path. Reason: ", err)
a.sendError("Unable to update the DB record with the Image path. Reason: ", err)
return false
}
return true
}
// GetWalletTag is called from the Login.Vue
func (a *WalletApplication) GetWalletTag() string {
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Error; err != nil {
a.log.Errorln("Unable to query the DB record for the Image path. Reason: ", err)
a.sendError("Unable to query the DB record for the Image path. Reason: ", err)
}
a.log.Infoln("Wallet Tag selected: ", a.wallet.WalletTag)
return a.wallet.WalletTag
}
// StoreWalletLabelInDB takes a wallet label string entered by a user and stores it in the database
func (a *WalletApplication) StoreWalletLabelInDB(walletTag string) bool {
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Update("WalletTag", walletTag).Error; err != nil {
a.log.Errorln("Unable to update the DB record with the wallet tag. Reason: ", err)
a.sendError("Unable to update the DB record with the wallet tag. Reason: ", err)
return false
}
return true
}
// GetUserTheme is called from the Login.Vue
func (a *WalletApplication) GetUserTheme() bool {
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Error; err != nil {
a.log.Errorln("Unable to query the DB record for the Image path. Reason: ", err)
a.sendError("Unable to query the DB record for the Image path. Reason: ", err)
}
if a.wallet.DarkMode {
a.log.Infoln("Dark mode enabled")
}
return a.wallet.DarkMode
}
// StoreDarkModeStateDB stores the darkmode state in the user DB
func (a *WalletApplication) StoreDarkModeStateDB(darkMode bool) bool {
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Update("DarkMode", darkMode).Error; err != nil {
a.log.Errorln("Unable to store darkmode state. Reason: ", err)
a.sendError("Unable to store darkmode state persistently. Reason: ", err)
return false
}
return true
}
// StoreCurrencyStateDB stores the currency state in the user DB
func (a *WalletApplication) StoreCurrencyStateDB(currency string) bool {
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Update("Currency", currency).Error; err != nil {
a.log.Errorln("Unable to store currency state. Reason: ", err)
a.sendError("Unable to store currency state persistently. Reason: ", err)
return false
}
totalCurrencyBalance := 0.0
if a.wallet.Currency == "USD" {
totalCurrencyBalance = float64(a.wallet.Balance) * a.wallet.TokenPrice.DAG.USD
} else if a.wallet.Currency == "EUR" {
totalCurrencyBalance = float64(a.wallet.Balance) * a.wallet.TokenPrice.DAG.EUR
} else if a.wallet.Currency == "BTC" {
totalCurrencyBalance = float64(a.wallet.Balance) * a.wallet.TokenPrice.DAG.BTC
}
a.RT.Events.Emit("totalValue", a.wallet.Currency, totalCurrencyBalance)
return true
}
// UpdateMolly is called from the frontend and triggers the application update
func (a *WalletApplication) UpdateMolly() {
update := new(UpdateWallet)
update.app = a
update.Run()
}
// CopyFile the src file to dst. Any existing file will be overwritten and will not
// copy file attributes.
func CopyFile(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return out.Close()
}

374
gui_wails01_learn/backend/transactions.go

@ -0,0 +1,374 @@
package app
import (
"bufio"
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"os"
"time"
"github.com/grvlle/constellation_wallet/backend/models"
)
// Transaction contains all tx information
type Transaction struct {
Edge struct {
ObservationEdge struct {
Parents []struct {
HashReference string `json:"hashReference"`
HashType string `json:"hashType"`
BaseHash string `json:"baseHash"`
} `json:"parents"`
Data struct {
HashReference string `json:"hashReference"`
HashType string `json:"hashType"`
BaseHash string `json:"baseHash"`
} `json:"data"`
} `json:"observationEdge"`
SignedObservationEdge struct {
SignatureBatch struct {
Hash string `json:"hash"`
Signatures []struct {
Signature string `json:"signature"`
ID struct {
Hex string `json:"hex"`
} `json:"id"`
} `json:"signatures"`
} `json:"signatureBatch"`
} `json:"signedObservationEdge"`
Data struct {
Amount int64 `json:"amount"`
LastTxRef struct {
PrevHash string `json:"prevHash"`
Ordinal int `json:"ordinal"`
} `json:"lastTxRef"`
Fee int64 `json:"fee,omitempty"`
Salt int64 `json:"salt"`
} `json:"data"`
} `json:"edge"`
LastTxRef struct {
PrevHash string `json:"prevHash"`
Ordinal int `json:"ordinal"`
} `json:"lastTxRef"`
IsDummy bool `json:"isDummy"`
IsTest bool `json:"isTest"`
}
/* Send a transaction */
// TriggerTXFromFE will initate a new transaction triggered from the frontend.
func (a *WalletApplication) TriggerTXFromFE(amount float64, fee float64, address string) bool {
amountConverted := int64(amount * 1e8)
feeConverted := int64(fee * 1e8)
a.PrepareTransaction(amountConverted, feeConverted, address)
for !a.TransactionFinished {
time.Sleep(1 * time.Second)
}
return a.TransactionFailed
}
// PrepareTransaction is triggered from the frontend (Transaction.vue) and will initialize a new tx.
// methods called are defined in buildchain.go
func (a *WalletApplication) PrepareTransaction(amount int64, fee int64, address string) {
balance, err := a.GetTokenBalance()
if err != nil {
a.log.Errorln("Error when querying wallet balance. Reason: ", err)
a.sendWarning("Unable to poll balance for wallet. Please try again later.")
a.TransactionFailed = true
return
}
if amount+fee > int64(balance*1e8) {
a.log.Warnf("Trying to send: %d", amount+fee)
a.log.Warnf("Insufficient Balance: %d", int64(balance*1e8))
a.sendWarning("Insufficent Balance.")
a.TransactionFailed = true
return
}
if a.TransactionFinished {
a.TransactionFinished = false
// Asynchronously inform FE of TX state in wallet.
go func() {
for !a.TransactionFinished {
a.RT.Events.Emit("tx_in_transit", a.TransactionFinished)
time.Sleep(1 * time.Second)
}
a.RT.Events.Emit("tx_in_transit", a.TransactionFinished)
}()
ptx := a.loadTXFromFile(a.paths.PrevTXFile)
ltx := a.loadTXFromFile(a.paths.LastTXFile)
ptxObj, ltxObj := a.convertToTXObject(ptx, ltx)
a.formTXChain(amount, fee, address, ptxObj, ltxObj)
}
}
func (a *WalletApplication) putTXOnNetwork(tx *Transaction) (bool, string) {
a.log.Info("Attempting to communicate with mainnet on: " + a.Network.URL + a.Network.Handles.Transaction)
/* TEMPORARILY COMMENTED OUT */
a.log.Warnln("TX Ordinal:", tx.Edge.Data.LastTxRef.Ordinal)
bytesRepresentation, err := json.Marshal(tx)
if err != nil {
a.log.Errorln("Unable to parse JSON data for transaction", err)
a.sendError("Unable to parse JSON data for transaction", err)
return false, ""
}
resp, err := http.Post(a.Network.URL+a.Network.Handles.Transaction, "application/json", bytes.NewBuffer(bytesRepresentation))
if err != nil {
a.log.Errorln("Failed to send HTTP request. Reason: ", err)
a.sendError("Unable to send request to mainnet. Please check your internet connection. Reason: ", err)
return false, ""
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
a.log.Errorln(string(bodyBytes))
a.log.Errorln("Failed to read the response body. Reason: ", err)
}
bodyString := string(bodyBytes[1:65])
a.log.Infoln("The bytesize of the request body: ", len(bodyBytes))
if len(bodyBytes) == 66 {
a.log.Info("Transaction Hash: ", bodyString)
a.TxPending(bodyString)
a.log.Infoln("Transaction has been successfully sent to the network.")
a.sendSuccess("Transaction successfully sent!")
return true, bodyString
}
a.log.Warn(bodyString)
a.sendWarning("Unable to put transaction on the network. Reason: " + bodyString)
return false, ""
}
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
a.log.Errorln(err)
}
bodyString := string(bodyBytes)
a.sendError("Unable to communicate with mainnet. Reason: "+bodyString, err)
a.log.Errorln("Unable to put TX on the network. HTTP Code: " + string(resp.StatusCode) + " - " + bodyString)
return false, ""
}
func (a *WalletApplication) sendTransaction(txFile string) *models.TXHistory {
txObject := a.loadTXFromFile(txFile)
tx := &Transaction{}
bytes := []byte(txObject)
err := json.Unmarshal(bytes, &tx)
if err != nil {
a.sendError("Unable to parse the last transaction. Reason:", err)
a.log.Errorf("Unable to parse contents of last_tx. Reason: %s", err)
return nil
}
// Put TX object on network
TXSuccessfullyPutOnNetwork, hash := a.putTXOnNetwork(tx)
if TXSuccessfullyPutOnNetwork {
txData := &models.TXHistory{
Amount: tx.Edge.Data.Amount,
Receiver: tx.Edge.ObservationEdge.Parents[1].HashReference,
Fee: tx.Edge.Data.Fee,
Hash: hash,
TS: time.Now().Format("Jan _2 15:04:05"),
Status: "Pending",
Failed: false,
}
a.storeTX(txData)
a.RT.Events.Emit("new_transaction", txData) // Pass the tx to the frontend as a new transaction.
a.TransactionFinished = true
a.TransactionFailed = false
return txData
}
txData := &models.TXHistory{
Amount: tx.Edge.Data.Amount,
Receiver: tx.Edge.ObservationEdge.Parents[1].HashReference,
Fee: tx.Edge.Data.Fee,
Hash: hash,
TS: time.Now().Format("Jan _2 15:04:05"),
Status: "Error",
Failed: true,
}
a.log.Errorln("TX Failed, storing with failed state.")
a.storeTX(txData)
a.TransactionFinished = true
a.TransactionFailed = true
return txData
}
func (a *WalletApplication) storeTX(txData *models.TXHistory) {
if txData == nil {
return
}
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Association("TXHistory").Append(txData).Error; err != nil {
a.log.Errorln("Unable to update the DB record with the new TX. Reason: ", err)
a.sendError("Unable to update the DB record with the new TX. Reason: ", err)
}
a.log.Infoln("Successfully stored tx in DB")
}
// loadTXFromFile takes a file, scans it and returns it in an object
func (a *WalletApplication) loadTXFromFile(txFile string) string {
var txObjects string
fi, err := os.Stat(txFile)
if err != nil {
a.log.Errorln("Unable to stat last_tx. Reason: ", err)
a.sendError("Unable to stat last_tx. Reason: ", err)
return ""
}
// get the size
size := fi.Size()
if size <= 0 {
a.log.Info("TX file is empty.")
return ""
}
file, err := os.Open(txFile) // acct
if err != nil {
a.log.Errorln("Unable to open TX file. Reason: ", err)
a.sendError("Unable to read last tx. Aborting... Reason: ", err)
return ""
}
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
txObjects = scanner.Text()
}
defer file.Close()
return txObjects
}
/* Query TX */
// TxProcessed will query the last transaction. If no answer is returned, it means it's processed and the
// method will return true.
func (a *WalletApplication) TxProcessed(TXHash string) bool {
a.log.Info("Communicating with mainnet on: " + a.Network.URL + a.Network.Handles.Transaction + "/" + TXHash)
resp, err := http.Get(a.Network.URL + a.Network.Handles.Transaction + "/" + TXHash)
if err != nil {
a.log.Errorln("Failed to send HTTP request. Reason: ", err)
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Delete(&a.wallet).Error; err != nil {
a.log.Errorln("Unable to delete wallet upon failed import. Reason: ", err)
return false
}
a.log.Errorln("Unable to verify transaction status. Please check your internet connection.")
return false
}
defer resp.Body.Close()
if resp.Body == nil {
return false
}
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false
}
// Declared an empty interface
var result map[string]interface{}
// Unmarshal or Decode the JSON to the interface.
err = json.Unmarshal(bodyBytes, &result)
if err != nil {
return false
}
if result["cbBaseHash"] != nil {
a.log.Infoln("CheckPoint Hash :", result["cbBaseHash"])
return true
}
// null response means it's snapshotted
return string(bodyBytes) == "null"
}
type txStatus struct {
Complete string
Pending string
Error string
}
// TxPending takes a TX Hash and updates the frontend with the current status (Pending/Error/Complete)
func (a *WalletApplication) TxPending(TXHash string) {
status := &txStatus{
Complete: "Complete",
Pending: "Pending",
Error: "Error",
}
consensus := 0
select {
case <-a.killSignal:
return
default:
go func() bool {
for retryCounter := 0; retryCounter < 30; retryCounter++ {
processed := a.TxProcessed(TXHash)
if !processed {
a.log.Warnf("Transaction %v pending", TXHash)
a.RT.Events.Emit("tx_pending", status.Pending)
time.Sleep(time.Duration(retryCounter) * time.Second) // Increase polling interval
if retryCounter == 29 {
// Register failed transaction
a.sendWarning("Unable to get verification of processed transaction from the network. Please try again later.")
a.log.Errorf("Unable to get status from the network on transaction: %s", TXHash)
a.RT.Events.Emit("tx_pending", status.Error)
if err := a.DB.Table("tx_histories").Where("hash = ?", TXHash).Updates(map[string]interface{}{"status": status.Error, "failed": true}).Error; err != nil {
a.log.Errorln("Unable to query database object for the imported wallet. Reason: ", err)
a.LoginError("Unable to query database object for the imported wallet.")
return false
}
a.RT.Events.Emit("update_tx_history", []models.TXHistory{}) // Clear TX history
a.initTXFromDB()
return false
}
consensus = 0 // Reset consensus
}
if processed && consensus != 3 {
consensus++
a.log.Infof("TX status check has reached consensus %v/3", consensus)
time.Sleep(1 * time.Second)
}
if processed && consensus == 3 { // Need five consecetive confirmations that TX has been processed.
break
}
}
a.log.Infof("Transaction %v has been successfully processed", TXHash)
a.sendSuccess("Transaction " + TXHash[:30] + "... has been successfully processed")
if err := a.DB.Table("tx_histories").Where("hash = ?", TXHash).UpdateColumn("status", status.Complete).Error; err != nil {
a.log.Errorln("Unable to query database object for the imported wallet. Reason: ", err)
a.LoginError("Unable to query database object for the imported wallet.")
return false
}
a.RT.Events.Emit("tx_pending", status.Complete)
a.RT.Events.Emit("update_tx_history", []models.TXHistory{}) // Clear TX history
a.initTXFromDB()
return true
}()
}
}

188
gui_wails01_learn/backend/utils.go

@ -0,0 +1,188 @@
package app
import (
"bytes"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/dustin/go-humanize"
)
// newReleaseAvailable generates a notification to FE everytime a new release on
// GitHub doesn't match a.Version.
func (a *WalletApplication) newReleaseAvailable() {
update := new(UpdateWallet)
update.app = a
currentRelease := a.Version
a.log.Infoln("Checking for new releases...")
go func() {
for i := 200; i > 0; i-- {
newRelease := update.GetLatestRelease()
if currentRelease != newRelease {
a.log.Infoln("There's a newer release available")
a.RT.Events.Emit("new_release", newRelease)
}
time.Sleep(time.Duration(i) * time.Second)
}
}()
}
func (a *WalletApplication) javaInstalled() bool {
var javaInstalled bool
if a.paths.Java[len(a.paths.Java)-9:] != "javaw.exe" {
javaInstalled = false
} else {
javaInstalled = true
}
return javaInstalled
}
func (a *WalletApplication) detectJavaPath() {
if runtime.GOOS == "windows" {
var jwPath string
cmd := exec.Command("cmd", "/c", "where", "java")
a.log.Infoln("Running command: ", cmd)
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out // Captures STDOUT
cmd.Stderr = &stderr // Captures STDERR
err := cmd.Run()
if err != nil {
errFormatted := fmt.Sprint(err) + ": " + stderr.String()
a.log.Errorf(errFormatted)
a.LoginError("Unable to find Java Installation")
a.paths.Java = "No valid path detected"
return
}
jPath := out.String() // May contain multiple
if jPath == "" {
a.LoginError("Unable to find Java Installation")
a.paths.Java = "No valid path detected"
return
}
s := strings.Split(strings.Replace(jPath, "\r\n", "\n", -1), "\n")
jwPath = string(s[0][:len(s[0])-4]) + "w.exe" // Shifting to javaw.exe
if s[1] != "" {
jwPath = string(s[1][:len(s[1])-4]) + "w.exe" // Shifting to javaw.exe
a.log.Info("Detected a secondary java path. Using that over the first one.")
}
a.log.Infoln("Java path selected: " + jwPath)
a.log.Debugln(cmd)
a.paths.Java = jwPath
}
}
//normalizeAmounts takes amount/fee in int64 and normalizes it. Example: passing 821500000000 will return 8215
func normalizeAmounts(i int64) (string, error) {
f := fmt.Sprintf("%.8f", float64(i)/1e8)
return f, nil
}
// TempFileName creates temporary file names for the transaction files
func (a *WalletApplication) TempFileName(prefix string) string {
randBytes := make([]byte, 16)
rand.Read(randBytes)
return filepath.Join(a.paths.TMPDir, prefix+hex.EncodeToString(randBytes))
}
// WriteCounter stores dl state of the cl binaries
type WriteCounter struct {
Total uint64
LastEmit uint64
Filename string
a *WalletApplication
}
// Write emits the download progress of the CL binaries to the frontend
func (wc *WriteCounter) Write(p []byte) (int, error) {
n := len(p)
wc.Total += uint64(n)
if (wc.Total - wc.LastEmit) > uint64(800) {
wc.a.RT.Events.Emit("downloading", wc.Filename, humanize.Bytes(wc.Total))
wc.LastEmit = wc.Total
}
return n, nil
}
func (a *WalletApplication) fetchWalletJar(filename string, filepath string) error {
url := a.WalletCLI.URL + "/v" + a.WalletCLI.Version + "/" + filename
a.log.Info(url)
out, err := os.Create(filepath + ".tmp")
if err != nil {
return err
}
resp, err := http.Get(url)
if err != nil {
out.Close()
return err
}
defer resp.Body.Close()
counter := &WriteCounter{}
counter.a = a
counter.Filename = filename
counter.LastEmit = uint64(0)
if _, err = io.Copy(out, io.TeeReader(resp.Body, counter)); err != nil {
out.Close()
return err
}
out.Close()
if err = os.Rename(filepath+".tmp", filepath); err != nil {
return err
}
return nil
}
func (a *WalletApplication) directoryCreator(directories ...string) error {
for _, d := range directories {
err := os.MkdirAll(d, os.ModePerm)
if err != nil {
return err
}
}
return nil
}
func (a *WalletApplication) fileExists(path string) bool {
info, err := os.Stat(path)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
// WriteToFile will print any string of text to a file safely by
// checking for errors and syncing at the end.
func WriteToFile(filename string, data []byte) error {
err := ioutil.WriteFile(filename, data, 0666)
if err != nil {
return err
}
return nil
}

542
gui_wails01_learn/backend/wallet.go

@ -0,0 +1,542 @@
package app
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"runtime"
"strconv"
"strings"
"time"
"github.com/grvlle/constellation_wallet/backend/models"
)
// ImportWallet is triggered when a user logs into a new Molly wallet for the first time
func (a *WalletApplication) ImportWallet(keystorePath, keystorePassword, keyPassword, alias string) bool {
alias = strings.ToLower(alias)
a.wallet = models.Wallet{
KeyStorePath: keystorePath,
WalletAlias: alias,
Currency: "USD"}
if runtime.GOOS == "windows" && !a.javaInstalled() {
a.LoginError("Unable to detect your Java path. Please make sure that Java has been installed.")
return false
}
if !a.TransactionFinished {
a.log.Warn("Cannot Import wallet in a pending transaction.")
a.LoginError("Cannot import a new wallet while there's a pending transaction.")
return false
}
if keystorePath == "" {
a.LoginError("Please provide a path to the KeyStore file.")
return false
}
if !a.passwordsProvided(keystorePassword, keyPassword, alias) {
a.log.Warnln("One or more passwords were not provided.")
return false
}
os.Setenv("CL_STOREPASS", keystorePassword)
os.Setenv("CL_KEYPASS", keyPassword)
a.wallet.Address = a.GenerateDAGAddress()
a.KeyStoreAccess = a.WalletKeystoreAccess()
if a.KeyStoreAccess {
if !a.DB.NewRecord(&a.wallet) {
keystorePasswordHashed, err := a.GenerateSaltedHash(keystorePassword)
if err != nil {
a.log.Errorln("Unable to generate password hash. Reason: ", err)
a.LoginError("Unable to generate password hash.")
return false
}
keyPasswordHashed, err := a.GenerateSaltedHash(keyPassword)
if err != nil {
a.log.Errorln("Unable to generate password hash. Reason: ", err)
a.LoginError("Unable to generate password hash.")
return false
}
if err := a.DB.Create(&a.wallet).Error; err != nil {
a.log.Errorln("Unable to create database object for the imported wallet. Reason: ", err)
a.LoginError("Unable to create database object for the imported wallet. Maybe it has already been imported? Try to login.")
return false
}
a.paths.LastTXFile = a.TempFileName("tx-")
a.paths.PrevTXFile = a.TempFileName("tx-")
a.paths.EmptyTXFile = a.TempFileName("tx-")
err = a.createTXFiles()
if err != nil {
a.log.Fatalln("Unable to create TX files. Check fs permissions. Reason: ", err)
a.sendError("Unable to create TX files. Check fs permissions. Reason: ", err)
}
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Update("Path", models.Path{LastTXFile: a.paths.LastTXFile, PrevTXFile: a.paths.PrevTXFile, EmptyTXFile: a.paths.EmptyTXFile}).Error; err != nil {
a.log.Errorln("Unable to update the DB record with the tmp tx-paths. Reason: ", err)
a.sendError("Unable to update the DB record with the tmp tx-paths. Reason: ", err)
}
if err := a.DB.Where("wallet_alias = ?", a.wallet.WalletAlias).First(&a.wallet).Updates(&models.Wallet{KeyStorePath: keystorePath, KeystorePasswordHash: keystorePasswordHashed, KeyPasswordHash: keyPasswordHashed}).Error; err != nil {
a.log.Errorln("Unable to query database object for the imported wallet. Reason: ", err)
a.LoginError("Unable to query database object for the imported wallet.")
return false
}
a.UserLoggedIn = false
a.NewUser = true
a.WalletImported = true
err = a.initWallet(keystorePath)
if err != nil {
a.log.Errorln("Failed to initialize wallet. Reason: ", err)
// If unable to import previous transactions, remove wallet from DB and logout.
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Delete(&a.wallet).Error; err != nil {
a.log.Errorln("Unable to delete wallet upon failed import. Reason: ", err)
return false
}
return false
}
return true
} else if a.DB.NewRecord(&a.wallet) { // There may already be an existing DB record in some circumstances.
a.DB.First(&a.wallet)
a.UserLoggedIn = false
a.NewUser = false
a.WalletImported = true
err := a.initWallet(a.wallet.KeyStorePath)
if err != nil {
a.log.Errorln("Faled to initialize wallet. Reason: ", err)
return false
}
return true
}
}
return false
}
// CreateWallet is called when creating a new wallet in frontend component Login.vue
func (a *WalletApplication) CreateWallet(keystorePath, keystorePassword, keyPassword, alias, label string) bool {
alias = strings.ToLower(alias)
if runtime.GOOS == "windows" && !a.javaInstalled() {
a.LoginError("Unable to detect your Java path. Please make sure that Java has been installed.")
return false
}
if !a.TransactionFinished {
a.log.Warn("Cannot Create wallet in a pending transaction.")
a.LoginError("Cannot create a new wallet while there's a pending transaction.")
return false
}
if keystorePath == "" {
a.LoginError("Please provide a path to store the KeyStore file.")
return false
}
if !a.passwordsProvided(keystorePassword, keyPassword, alias) {
a.log.Warnln("One or more passwords were not provided.")
return false
}
if alias == "" {
alias = a.wallet.WalletAlias
}
os.Setenv("CL_STOREPASS", keystorePassword)
os.Setenv("CL_KEYPASS", keyPassword)
keystorePasswordHashed, err := a.GenerateSaltedHash(keystorePassword)
if err != nil {
a.log.Errorln("Unable to generate password hash. Reason: ", err)
a.sendError("Unable to generate password hash. Reason: ", err)
return false
}
keyPasswordHashed, err := a.GenerateSaltedHash(keyPassword)
if err != nil {
a.log.Errorln("Unable to generate password hash. Reason: ", err)
a.sendError("Unable to generate password hash. Reason: ", err)
return false
}
a.wallet = models.Wallet{
KeyStorePath: keystorePath,
KeystorePasswordHash: keystorePasswordHashed,
KeyPasswordHash: keyPasswordHashed,
WalletAlias: alias,
WalletTag: label}
if !a.DB.NewRecord(&a.wallet) {
if err := a.DB.Create(&a.wallet).Error; err != nil {
a.log.Errorln("Unable to create database object for new wallet. Reason: ", err)
a.LoginError("Unable to create new wallet. Alias already exists.")
return false
}
if err := a.DB.Where("wallet_alias = ?", alias).First(&a.wallet).Updates(&models.Wallet{KeyStorePath: keystorePath, KeystorePasswordHash: keystorePasswordHashed, KeyPasswordHash: keyPasswordHashed}).Error; err != nil {
a.log.Errorln("Unable to query database object for new wallet after wallet creation. Reason: ", err)
a.sendError("Unable to query database object for new wallet after wallet creation. Reason: ", err)
return false
}
err = a.CreateEncryptedKeyStore()
if err != nil {
return false
}
a.wallet.Address = a.GenerateDAGAddress()
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Update("Address", a.wallet.Address).Error; err != nil {
a.log.Errorln("Unable to update db object new wallet, with the DAG address. Reason: ", err)
a.sendError("Unable to update db object new wallet, with the DAG address. Reason. Reason: ", err)
}
a.KeyStoreAccess = a.WalletKeystoreAccess()
if a.KeyStoreAccess {
a.paths.LastTXFile = a.TempFileName("tx-")
a.paths.PrevTXFile = a.TempFileName("tx-")
a.paths.EmptyTXFile = a.TempFileName("tx-")
err := a.createTXFiles()
if err != nil {
a.log.Fatalln("Unable to create TX files. Check fs permissions. Reason: ", err)
a.sendError("Unable to create TX files. Check fs permissions. Reason: ", err)
}
if err := a.DB.Where("wallet_alias = ?", a.wallet.WalletAlias).First(&a.wallet).Update("Path", models.Path{LastTXFile: a.paths.LastTXFile, PrevTXFile: a.paths.PrevTXFile, EmptyTXFile: a.paths.EmptyTXFile}).Error; err != nil {
a.log.Errorln("Unable to update the DB record with the tmp tx-paths. Reason: ", err)
a.sendError("Unable to update the DB record with the tmp tx-paths. Reason: ", err)
}
a.UserLoggedIn = false
a.FirstTX = true
a.NewUser = true
a.initNewWallet()
return true
}
} else {
a.LoginError("Unable to create new wallet. Alias already exists.")
}
return false
}
// initWallet initializes a new wallet. This is called from login.vue
// only when a new wallet is created.
func (a *WalletApplication) initNewWallet() {
a.StoreImagePathInDB("faces/face-0.jpg")
//a.initTransactionHistory()
a.passKeysToFrontend()
if !a.WidgetRunning.DashboardWidgets {
a.initDashboardWidgets()
}
a.log.Infoln("A New wallet has been created successfully!")
}
// initExistingWallet queries the database for the user wallet and pushes
// the information to the front end components.
func (a *WalletApplication) initWallet(keystorePath string) error {
if a.NewUser {
err := a.initTXFromBlockExplorer()
if err != nil {
return err
}
a.StoreImagePathInDB("faces/face-0.jpg")
} else if !a.NewUser {
a.initTXFromDB() // Disregard upon import
a.initTXFilePath() // Update paths from DB.
}
a.RT.Events.Emit("wallet_init", a.wallet.TermsOfService, a.wallet.Currency)
if !a.WidgetRunning.DashboardWidgets {
a.initDashboardWidgets()
}
if !a.WidgetRunning.PassKeysToFrontend {
a.passKeysToFrontend()
}
a.log.Infoln("User has logged into the wallet")
return nil
}
func (a *WalletApplication) initDashboardWidgets() {
// Initializes a struct containing all Chart Data on the dashboard
chartData := a.ChartDataInit()
// Below methods are continously updating the client side modules.
a.pollTokenBalance()
a.nodeStats(chartData)
a.txStats(chartData)
a.networkStats(chartData)
a.blockAmount()
a.pricePoller()
a.WidgetRunning.DashboardWidgets = true
}
func (a *WalletApplication) createTXFiles() error {
files := []string{a.paths.LastTXFile, a.paths.PrevTXFile, a.paths.EmptyTXFile}
for _, f := range files {
file, err := os.Create(f)
if err != nil {
return err
}
defer file.Close()
}
return nil
}
// ImportKeys is called from the frontend to use a file dialog to select key file.
func (a *WalletApplication) ImportKeys() error {
filename := a.RT.Dialog.SelectFile()
a.log.Info("Path to keys that user wants to import: " + filename)
return nil
}
// ExportKeys is called from the frontend to use a file dialog to select directory
// where user wants to export the keys to.
func (a *WalletApplication) ExportKeys() error {
filename := a.RT.Dialog.SelectDirectory()
a.log.Info("File user wants to save to: " + filename)
return nil
}
func (a *WalletApplication) initTXFilePath() {
paths := &a.wallet.Path
if err := a.DB.Model(&a.wallet).Where("alias = ?", a.wallet.WalletAlias).Association("Path").Find(&paths).Error; err != nil {
a.log.Fatal("Unable to initialize TX filepaths. Reason: ", err)
a.sendError("Unable to initialize TX filepaths. Reason: ", err)
return
}
if a.wallet.Path.LastTXFile == "" && a.wallet.Path.PrevTXFile == "" {
a.log.Fatal("Unable to initialize TX filepaths. Both are empty after DB query.")
}
a.paths.LastTXFile = a.wallet.Path.LastTXFile
a.paths.PrevTXFile = a.wallet.Path.PrevTXFile
a.paths.EmptyTXFile = a.wallet.Path.EmptyTXFile
}
func (a *WalletApplication) initTXFromDB() {
if err := a.DB.Model(&a.wallet).Where("alias = ?", a.wallet.WalletAlias).Association("TXHistory").Find(&a.wallet.TXHistory).Error; err != nil {
a.log.Error("Unable to initialize historic transactions from DB. Reason: ", err)
a.sendError("Unable to initialize historic transactions from DB. Reason: ", err)
return
}
allTX := []models.TXHistory{}
for i, tx := range a.wallet.TXHistory {
allTX = append([]models.TXHistory{tx}, allTX...) // prepend to reverse list for FE
if a.wallet.TXHistory[i].Status == "Pending" {
a.TxPending(a.wallet.TXHistory[i].Hash)
}
}
a.RT.Events.Emit("update_tx_history", allTX) // Pass the tx to the frontend as a new transaction.
}
// initTXFromBlockExplorer is called when an existing wallet is imported.
func (a *WalletApplication) initTXFromBlockExplorer() error {
a.log.Info("Sending API call to block explorer on: " + a.Network.BlockExplorer.URL + a.Network.BlockExplorer.Handles.CollectTX + a.wallet.Address)
resp, err := http.Get(a.Network.BlockExplorer.URL + a.Network.BlockExplorer.Handles.CollectTX + a.wallet.Address)
if err != nil {
a.log.Errorln("Failed to send HTTP request. Reason: ", err)
a.LoginError("Unable to collect previous transactions from blockexplorer.")
return err
}
defer resp.Body.Close()
if resp.Body != nil {
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
a.LoginError("Unable to collect previous transactions from blockexplorer. Try again later.")
a.log.Errorln("Unable to collect previous transactions from blockexplorer. Reason: ", err)
return err
}
ok, error := a.verifyAPIResponse(bodyBytes)
// Blockexplorer returns below string when no previous transactions are found
if !ok && error != "Cannot find transactions for sender" {
a.log.Errorln("API returned the following error", error)
a.LoginError("The wallet import failed. Please check your internet connection and try again.")
return errors.New(error)
}
// If no previous transactions for imported wallet - proceed
if !ok && error == "Cannot find transactions for sender" {
a.log.Info("Unable to detect any previous transactions.")
return nil
}
allTX := []models.TXHistory{}
err = json.Unmarshal(bodyBytes, &allTX)
if err != nil {
a.log.Errorln("Unable to fetch TX history from block explorer. Reason: ", err)
a.sendError("Unable to fetch TX history from block explorer. Reason: ", err)
return err
}
// Reverse order
for i := len(allTX)/2 - 1; i >= 0; i-- {
opp := len(allTX) - 1 - i
allTX[i], allTX[opp] = allTX[opp], allTX[i]
}
a.log.Infof("Successfully collected %d previous transactions. Updating local state...", len(allTX))
for i, tx := range allTX {
txData := &models.TXHistory{
Amount: tx.Amount,
Receiver: tx.Receiver,
Fee: tx.Fee,
Hash: tx.Hash,
TS: time.Now().Format("Jan _2 15:04:05") + " (imported)",
Status: "Complete",
Failed: false,
}
a.storeTX(txData)
a.RT.Events.Emit("new_transaction", txData)
if i+1 == len(allTX) {
err := a.rebuildTxChainState(tx.Hash)
if err != nil {
a.log.Errorln(err)
// If unable to import previous transactions, remove wallet from DB and logout.
//TODO: logout
if err := a.DB.Model(&a.wallet).Where("wallet_alias = ?", a.wallet.WalletAlias).Delete(&a.wallet).Error; err != nil {
a.log.Errorln("Unable to delete wallet upon failed import. Reason: ", err)
return err
}
a.log.Panicln("Unable to import previous transactions")
a.LoginError("Unable to collect previous TX's from blockexplorer. Please try again later.")
}
}
}
} else {
a.log.Info("Unable to detect any previous transactions.")
return nil
}
return nil
}
// PassKeysToFrontend emits the keys to the settings.Vue component on a
// 5 second interval
func (a *WalletApplication) passKeysToFrontend() {
if a.wallet.KeyStorePath != "" && a.wallet.Address != "" {
go func() {
for {
a.RT.Events.Emit("wallet_keys", a.wallet.Address)
time.Sleep(5 * time.Second)
}
}()
a.WidgetRunning.PassKeysToFrontend = true
} else {
a.WidgetRunning.PassKeysToFrontend = false
}
}
func (a *WalletApplication) passwordsProvided(keystorePassword, keyPassword, alias string) bool {
if keystorePassword == "" {
a.LoginError("Please provide a Key Store password.")
return false
} else if keyPassword == "" {
a.LoginError("Please provide a Key Password.")
return false
} else if alias == "" {
a.LoginError("An Alias has not been provided.")
return false
}
return true
}
// GetTokenBalance polls and parses the token balance of a wallet and returns it as a float64.
func (a *WalletApplication) GetTokenBalance() (float64, error) {
a.log.Debug("Contacting mainnet on: " + a.Network.URL + a.Network.Handles.Balance + " Sending the following payload: " + a.wallet.Address)
resp, err := http.Get(a.Network.URL + a.Network.Handles.Balance + a.wallet.Address)
if err != nil {
a.log.Errorln("Failed to send HTTP request. Reason: ", err)
return 0, err
}
if resp == nil {
a.log.Errorln("Killing pollTokenBalance after 10 failed attempts to get balance from mainnet, Reason: ", err)
a.sendWarning("Unable to showcase current balance. Please check your internet connectivity and restart the wallet application.")
return 0, err
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
a.log.Warn("Unable to update token balance. Reason: ", err)
return 0, err
}
var result map[string]interface{}
// Unmarshal or Decode the JSON to the interface.
err = json.Unmarshal(bodyBytes, &result)
if err != nil {
return 0, err
}
s := result["balance"]
if s == "" {
s = "0" // Empty means zero
}
a.log.Infoln("Parsed the following balance: ", s)
b, ok := s.(float64)
if !ok {
if err != nil {
a.log.Warnln("Unable to parse balance. Reason:", err)
}
return 0, err
}
f := fmt.Sprintf("%.2f", b/1e8) // Reverse normalized float
a.log.Infoln("Normalized the following balance: ", f)
balance, err := strconv.ParseFloat(f, 64)
if err != nil {
a.log.Warnln("Unable to type cast string to float for token balance poller. Check your internet connectivity")
return 0, err
}
a.log.Infoln("Returning the following balance: ", balance)
return balance, nil
}

4
gui_wails01_learn/build.bat

@ -0,0 +1,4 @@
# go build -ldflags="-s -w -H=windowsgui" main.go
cd frontend
npm install && npm run build && cd ../ && wails build

89
gui_wails01_learn/docs/faq.md

@ -0,0 +1,89 @@
# Molly Wallet FAQ
This is an attempt to address the most Frequently Asked Questions around the Molly Wallet in hopes of easing the community into leveraging the Desktop Wallet for $DAG to securely store their tokens.
The Molly Wallet is still in the early phases of development with the first stable, mainnet connected build released to the general public mere days ago (at the time of writing this). This means that the way we're distributing the application, and some of the manual steps required will be improved upon with time.
## General Questions
#### Q: Where can I download the Molly Wallet?
**A:** https://github.com/grvlle/constellation_wallet/releases
#### Q: Why can't I login to my wallet?
**A:** You can always reset the Molly Wallet, simply by closing the application, removing your `.dag` folder, starting the application and re-importing your key. See the below sections under your OS of choice for how to locate the `.dag` folder.
#### Q: What does the IMPORT feature do on the login screen?
**A:** The Import feature exists to make it possible to access your wallet key from different computers. This only has to be done once on any computer, and it'll sync your transactions with the mainnet, and update the wallet with your previous transactions.
Once imported, you will access your funds by simply login into the wallet.
#### Q: How do I create a new wallet?
**A:** Select the create wallet button on the login screen and it'll let you browse to a location in which you wish to store your keyfile.p12. Remember to give it a name, and select save.
After that you need to provide the keyfile with authentication, populate the remaining fields and click create. Then the keyfile.p12 will be saved to the location you specified, and you can use that to access your funds through Molly Wallet.
I will organize the questions based on the OS the wallet is installed upon.
## Windows
#### Q: Why am I getting an error when sending transaction?
**A:** This is most likely because you've used an older testnet build of the wallet with testnet artifacts interfering with your mainnet wallet. In order to fix this you need to remove the `.dag` folder that is located in your `C:/Users/<username>/` directory. Once done, feel free to import your wallet again and you should be good to go.
#### Q: I am getting `Unable to detect your Java path, make sure Java has been installed` when trying to login or create/import a wallet.
***A:*** This is either because [OpenJDK v9](https://java.com/) and [JRE](https://www.oracle.com/java/technologies/javase-jre8-downloads.html) hasn't been installed, or because the enviornment paths haven't been set up correctly.
For Molly Wallet to be able to detect the installation directory of Java, the `JAVA_HOME` enviornmental variable needs t
o be set. The Java path also has to be included in the `Path` variable.
Search for enviornment variables in windows search and select *Edit the system enviornment variables*, then set the JAVA
paths like in the below image.
[![env](https://i.ibb.co/Br1M31s/envvars.png)](https://constellationnetwork.io/technology/molly-wallet/)
#### Q: How to open a ``.rar`` file?
[![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/dr0g_Ux7_8M/0.jpg)](https://www.youtube.com/watch?v=dr0g_Ux7_8M)
#### Q: I am running Windows 7 (or earlier) - can I run Molly Wallet?
**A:** The answer is maybe. It's not officially supported, so probably not.
## MacOS
#### Q: Why am I getting an error when sending transaction?
**A:** This is most likely because you've used an older testnet build of the wallet with testnet artifacts interfering with your mainnet wallet. In order to fix this you need to remove the `.dag` folder that is located in your `$HOME` (if you don't know what this is, see [this article](https://www.cnet.com/how-to/how-to-find-your-macs-home-folder-and-add-it-to-finder/)) path. Once done, feel free to import your wallet again and you should be good to go.
#### Q: Why am I getting `The application 'Molly - Constellation Desktop Wallet` can't be opened?
![env](https://i.ibb.co/VWw30HN/a123555f-0881-4ae8-9b1d-7dd36d4d6802.jpg)
**A:** This is because the application is compressed and archived. You need to use a software called [Unarchiver](https://theunarchiver.com/).
After you've downloaded that, right click on the .zip file and select "open with" and then choose "Unarchiver" instead of the default program. It'll unzip and you'll be able to run it.
#### Q: Why is my Molly Wallet download not downloaded as a .zip file?
**A:** On some systems, Safari will automatically unzip the contents. We do not want that, we want to leverage the [Unarchiver](https://theunarchiver.com/). Here's a guide [how to disable automatic unzipping](https://www.addictivetips.com/mac-os/stop-automatically-unzipping-files-in-safari/) of files in Safari. Once that has been disabled, redownload Molly Wallet from the [official website](https://constellationnetwork.io/technology/molly-wallet/) and use [Unarchiver](https://theunarchiver.com/) to extract the contents.
## Linux
#### Q: Why does it say `Alias not found` when trying to import/login/create wallet?
**A:** This is probably due to Java missing on the system. For now, I've only implemented means of detecting that on Windows. So please, if you're using a debian based distribution, download `openjdk-8` from aptitude.
#### Q: Why am I getting an error when sending transaction?
**A:** This is most likely because you've used an older testnet build of the wallet with testnet artifacts interfering with your mainnet wallet. In order to fix this you need to remove the `.dag` folder that is located in your `$HOME` path. Once done, feel free to import your wallet again and you should be good to go.
## Java
#### Q: Why is Java needed?
**A:** The wallet binary that I'm integrating Molly Wallet against has been built by the Constellation Core team in a programming language called *Scala*. This is a functional programming language that runs on JVM (Java virtual machine). Thus Java becomes a dependency.

21
gui_wails01_learn/frontend/.gitignore

@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*

5
gui_wails01_learn/frontend/babel.config.js

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/app'
]
}

20364
gui_wails01_learn/frontend/package-lock.json

File diff suppressed because it is too large

82
gui_wails01_learn/frontend/package.json

@ -0,0 +1,82 @@
{
"name": "my_project",
"author": "vito<gralle89@gmail.com>",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@types/vuelidate": "^0.7.13",
"@wailsapp/runtime": "^1.0.11",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"bootstrap": "^4.4.1",
"chartist": "^0.11.4",
"core-js": "^2.6.11",
"es6-promise": "^4.2.8",
"jquery": "^3.5.0",
"node-sass": "^4.13.1",
"popper.js": "^1.16.1",
"sass-loader": "^8.0.2",
"serialize-javascript": "^2.1.2",
"update": "^0.7.4",
"vue": "^2.6.11",
"vue-clickaway": "^2.2.2",
"vue-js-toggle-button": "^1.3.3",
"vue-loading-spinner": "^1.0.11",
"vue-notifyjs": "^0.4.3",
"vue-progressbar": "^0.7.5",
"vue-router": "^3.1.6",
"vue-select": "^3.10.3",
"vue-spinner": "^1.0.3",
"vue-spinner-component": "^1.0.5",
"idle-vue": "^2.0.5",
"sweetalert2": "^9.10.12",
"@sweetalert2/theme-bootstrap-4": "^3.1.4",
"vuelidate": "^0.7.5",
"vuex": "^3.1.3",
"webpack": "^4.42.0",
"yarn": "^1.22.4"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.12.1",
"@vue/cli-plugin-eslint": "^3.12.1",
"@vue/cli-service": "^4.3.1",
"acorn": "^6.4.1",
"babel-eslint": "^10.1.0",
"eslint": "^5.8.0",
"eslint-plugin-vue": "^5.0.0",
"eventsource-polyfill": "^0.9.6",
"json-loader": "^0.5.7",
"kind-of": "^6.0.3",
"minimist": "^1.2.3",
"prerender-spa-plugin": "^3.4.0",
"vue-template-compiler": "^2.6.11",
"webpack-hot-middleware": "^2.24.3"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}

1
gui_wails01_learn/frontend/package.json.md5

@ -0,0 +1 @@
422408393369741cd5b0a4a730a7a0a1

303
gui_wails01_learn/frontend/src/App.vue

@ -0,0 +1,303 @@
<template>
<div :class="darkMode ? 'theme--dark' : 'theme--light'">
<vue-progress-bar></vue-progress-bar>
<div :class="{'nav-open': $sidebar.showSidebar}">
<notifications></notifications>
<router-view></router-view>
</div>
<page-overlay text="Applying Update. Please wait..." :isActive="overlay" />
</div>
</template>
<script>
import {mapState} from 'vuex'
import ErrorNotification from "./pages/Notifications/ErrorMessage";
import WarningNotification from "./pages/Notifications/Warning";
import SuccessNotification from "./pages/Notifications/Success";
import NewRelease from "./pages/Notifications/NewRelease";
import Swal from "sweetalert2/dist/sweetalert2";
export default {
components: {
},
computed: {
...mapState('app', ['isLoggedIn', 'downloading']),
...mapState('wallet', ['darkMode'])
},
data() {
return {
overlay: false
};
},
onIdle() {
let timerInterval, closeInSeconds = 10
const swalPopup = Swal.mixin({
customClass: {
container: this.darkMode
? "theme--dark"
: "theme--light"
}
});
if (this.isLoggedIn) {
swalPopup.fire({
title: "You have been idle for 5 minutes.",
html: "To keep your Molly wallet safe from unauthorised access it will automatically logout in <b>10</b> seconds",
showConfirmButton: false,
showCancelButton: false,
timer: closeInSeconds * 1000,
timerProgressBar: true,
onBeforeOpen: () => {
Swal.showLoading();
timerInterval = setInterval(() => {
closeInSeconds--;
const content = Swal.getContent();
if (content) {
const b = content.querySelector('b');
if (b) {
b.textContent = closeInSeconds;
}
}
}, 1000)
},
onClose: () => {
clearInterval(timerInterval)
}
}).then(() => {
if (this.$store.state.idleVue.isIdle) {
window.backend.WalletApplication.LogOut().then(txFinishedState => {
if (txFinishedState) {
this.logout();
}
}), (this.random = "1");
}
});
}
},
mounted() {
// Backend Errors
window.wails.Events.On("error_handling", (m, err) => {
this.$store.commit('app/setErrorMessage', m + err);
this.$notifications.clear();
setTimeout(() => {
this.$notifications.clear();
}, 60000);
this.$notify({
component: ErrorNotification,
timeout: 50000,
icon: "fa fa-times",
horizontalAlign: "right",
verticalAlign: "top",
type: "danger",
onClick: () => {
this.$notifications.clear();
}
});
});
window.wails.Events.On("warning", m => {
this.$store.commit('app/setWarningMessage', m);
this.$notifications.clear();
setTimeout(() => {
this.$notifications.clear();
}, 60000);
this.$notify({
component: WarningNotification,
timeout: 50000,
icon: "fa fa-times",
horizontalAlign: "right",
verticalAlign: "top",
type: "warning",
onClick: () => {
this.$notifications.clear();
}
});
});
window.wails.Events.On("success", m => {
this.$store.commit('app/setSuccessMessage', m);
this.$notifications.clear();
setTimeout(() => {
this.$notifications.clear();
}, 60000);
this.$notify({
component: SuccessNotification,
timeout: 50000,
icon: "fa fa-check",
horizontalAlign: "right",
verticalAlign: "top",
type: "success",
onClick: () => {
this.$notifications.clear();
}
});
});
window.wails.Events.On("new_release", m => {
this.$store.commit('app/setNewRelease', m);
var self = this;
this.$notifications.clear();
this.$notify({
component: NewRelease,
timeout: 500000,
icon: "fa fa-info",
horizontalAlign: "right",
verticalAlign: "bottom",
type: "info",
onClick: () => {
const swalPopup = Swal.mixin({
customClass: {
container: this.darkMode
? "theme--dark"
: "theme--light"
}
});
swalPopup.fire({
title: "Update Molly Wallet",
html: "Do you want to update your Molly Wallet? Selecting update will download the latest build and apply the update. <br><br> <b>The application will restart once update is complete. </b>",
showCloseButton: true,
showCancelButton: true,
focusConfirm: false,
confirmButtonText:
'<i class="fa fa-thumbs-up"></i> <b>Update</b>',
confirmButtonAriaLabel: "Text",
cancelButtonText:
'Cancel',
cancelButtonAriaLabel: "Cancel"
}).then(result => {
if (result.value) {
self.$Progress.start(2000);
self.overlay = true;
window.backend.WalletApplication.UpdateMolly()
self.$notifications.clear();
}
});
}
});
});
window.wails.Events.On("login_error", (m, err) => {
this.$store.commit('app/setLoginErrorMessage', m);
this.$store.commit('app/setDisplayLoginError', err);
setTimeout(() => {
this.$store.commit('app/setDisplayLoginError', false);
}, 10000);
});
// Transactions.vue sockets
window.wails.Events.On("update_tx_history", txHistoryFull => {
if (Object.entries(txHistoryFull).length != 0) {
this.$store.commit({type: 'transaction/updateFullTxHistory', txHistoryFull});
}
});
window.wails.Events.On("tx_in_transit", txFinished => {
this.$store.commit('transaction/setTxFinished', txFinished);
});
window.wails.Events.On("new_transaction", txObject => {
this.$store.commit("transaction/updateTxHistory", txObject);
});
window.wails.Events.On("tx_pending", txStatus => {
this.$store.commit("transaction/updateTxStatus", txStatus);
});
window.wails.Events.On("downloading", (filename, size) => {
if (this.downloading.filename !== filename) {
this.$store.commit('app/setDownloadFileName', filename);
}
this.$store.commit('app/setDownloadFileSize', size);
});
// Login.vue sockets
// window.wails.Events.On("registeredLogin", event => {});
// Dashboard.vue sockets
window.wails.Events.On("token", (amount, available, total) => {
this.$store.commit('wallet/setTokenAmount', amount);
this.$store.commit('wallet/setAvailableBalance', available);
this.$store.commit('wallet/setTotalBalance', total);
});
window.wails.Events.On("blocks", number => {
this.$store.commit('dashboard/setBlocks', number);
});
window.wails.Events.On("totalValue", (currency, value) => {
this.$store.commit('wallet/setCurrency', currency);
this.$store.commit('wallet/setTotalValue', value);
});
window.wails.Events.On("token_counter", count => {
this.$store.commit('dashboard/setTokenCounter', count);
});
window.wails.Events.On("value_counter", valueCount => {
this.$store.commit('dashboard/setValueCounter', valueCount);
});
window.wails.Events.On("block_counter", blockCount => {
this.$store.commit('dashboard/setBlockCounter', blockCount);
});
window.wails.Events.On("chart_counter", pieChartCount => {
this.$store.commit('dashboard/setChartCounter', pieChartCount);
});
window.wails.Events.On("node_stats", (series, labels) => {
if (Object.entries(series).length != 0 &&
Object.entries(labels).length != 0) {
this.$store.commit({type: 'dashboard/setNodeOnlineChart', series, labels});
}
});
window.wails.Events.On("tx_stats", (seriesOne, seriesTwo, labels) => {
if (Object.entries(seriesOne).length != 0 &&
Object.entries(seriesTwo).length != 0 &&
Object.entries(labels).length != 0) {
this.$store.commit({type: 'dashboard/setTransactionStatsChart', seriesOne, seriesTwo, labels});
}
});
window.wails.Events.On("network_stats", (seriesOne, seriesTwo, labels) => {
if (Object.entries(seriesOne).length != 0 &&
Object.entries(seriesTwo).length != 0 &&
Object.entries(labels).length != 0) {
this.$store.commit({type: 'dashboard/setNetworkStatsChart', seriesOne, seriesTwo, labels});
}
});
// Settings.vue sockets
window.wails.Events.On("wallet_keys", address => {
this.$store.commit('wallet/setAddress', address);
});
}
};
</script>
<style lang="scss">
.vue-notifyjs.notifications {
.alert {
z-index: 10000;
font-size: 0.875rem;
}
.alert[data-notify="container"] {
width: 21.875rem;
}
.alert-icon {
margin-left: -0.5em;
margin-top: -0.5em;
}
.list-move {
transition: transform 0.3s, opacity 0.4s;
}
.list-item {
display: inline-block;
margin-right: 0.625em;
}
.list-enter-active {
transition: transform 0.2s ease-in, opacity 0.4s ease-in;
}
.list-leave-active {
transition: transform 1s ease-out, opacity 0.4s ease-out;
}
.list-enter {
opacity: 0;
transform: scale(1.1);
}
.list-leave-to {
opacity: 0;
transform: scale(1.2, 0.7);
}
}
</style>

1081
gui_wails01_learn/frontend/src/assets/css/themify-icons.css

File diff suppressed because it is too large

202
gui_wails01_learn/frontend/src/assets/fonts/LICENSE.txt

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.eot

Binary file not shown.

3451
gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.svg

File diff suppressed because it is too large

After

Width:  |  Height:  |  Size: 676 KiB

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.ttf

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.woff

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-brands-400.woff2

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.eot

Binary file not shown.

803
gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.svg

@ -0,0 +1,803 @@
<?xml version="1.0" standalone="no"?>
<!--
Font Awesome Free 5.10.1 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<!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" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20190112 at Fri Aug 2 14:42:17 2019
By Robert Madole
Copyright (c) Font Awesome
</metadata>
<defs>
<font id="FontAwesome5Free-Regular" horiz-adv-x="512" >
<font-face
font-family="Font Awesome 5 Free Regular"
font-weight="400"
font-stretch="normal"
units-per-em="512"
panose-1="2 0 5 3 0 0 0 0 0 0"
ascent="448"
descent="-64"
bbox="-0.0663408 -64.0662 640.01 448.1"
underline-thickness="25"
underline-position="-51"
unicode-range="U+0020-F5C8"
/>
<missing-glyph />
<glyph glyph-name="heart" unicode="&#xf004;"
d="M458.4 383.7c75.2998 -63.4004 64.0996 -166.601 10.5996 -221.3l-175.4 -178.7c-10 -10.2002 -23.2998 -15.7998 -37.5996 -15.7998c-14.2002 0 -27.5996 5.69922 -37.5996 15.8994l-175.4 178.7c-53.5996 54.7002 -64.5996 157.9 10.5996 221.2
c57.8008 48.7002 147.101 41.2998 202.4 -15c55.2998 56.2998 144.6 63.5996 202.4 15zM434.8 196.2c36.2002 36.8994 43.7998 107.7 -7.2998 150.8c-38.7002 32.5996 -98.7002 27.9004 -136.5 -10.5996l-35 -35.7002l-35 35.7002
c-37.5996 38.2998 -97.5996 43.1992 -136.5 10.5c-51.2002 -43.1006 -43.7998 -113.5 -7.2998 -150.7l175.399 -178.7c2.40039 -2.40039 4.40039 -2.40039 6.80078 0z" />
<glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="576"
d="M528.1 276.5c26.2002 -3.7998 36.7002 -36.0996 17.7002 -54.5996l-105.7 -103l25 -145.5c4.5 -26.3008 -23.1992 -45.9004 -46.3994 -33.7002l-130.7 68.7002l-130.7 -68.7002c-23.2002 -12.2998 -50.8994 7.39941 -46.3994 33.7002l25 145.5l-105.7 103
c-19 18.5 -8.5 50.7998 17.7002 54.5996l146.1 21.2998l65.2998 132.4c11.7998 23.8994 45.7002 23.5996 57.4004 0l65.2998 -132.4zM388.6 135.7l100.601 98l-139 20.2002l-62.2002 126l-62.2002 -126l-139 -20.2002l100.601 -98l-23.7002 -138.4l124.3 65.2998
l124.3 -65.2998z" />
<glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="448"
d="M313.6 144c74.2002 0 134.4 -60.2002 134.4 -134.4v-25.5996c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v25.5996c0 74.2002 60.2002 134.4 134.4 134.4c28.7998 0 42.5 -16 89.5996 -16s60.9004 16 89.5996 16zM400 -16v25.5996
c0 47.6006 -38.7998 86.4004 -86.4004 86.4004c-14.6992 0 -37.8994 -16 -89.5996 -16c-51.2998 0 -75 16 -89.5996 16c-47.6006 0 -86.4004 -38.7998 -86.4004 -86.4004v-25.5996h352zM224 160c-79.5 0 -144 64.5 -144 144s64.5 144 144 144s144 -64.5 144 -144
s-64.5 -144 -144 -144zM224 400c-52.9004 0 -96 -43.0996 -96 -96s43.0996 -96 96 -96s96 43.0996 96 96s-43.0996 96 -96 96z" />
<glyph glyph-name="clock" unicode="&#xf017;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM317.8 96.4004l-84.8994 61.6992
c-3.10059 2.30078 -4.90039 5.90039 -4.90039 9.7002v164.2c0 6.59961 5.40039 12 12 12h32c6.59961 0 12 -5.40039 12 -12v-141.7l66.7998 -48.5996c5.40039 -3.90039 6.5 -11.4004 2.60059 -16.7998l-18.8008 -25.9004c-3.89941 -5.2998 -11.3994 -6.5 -16.7998 -2.59961z
" />
<glyph glyph-name="list-alt" unicode="&#xf022;"
d="M464 416c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h416zM458 16c3.31152 0 6 2.68848 6 6v340c0 3.31152 -2.68848 6 -6 6h-404c-3.31152 0 -6 -2.68848 -6 -6v-340
c0 -3.31152 2.68848 -6 6 -6h404zM416 108v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM416 204v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12
v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM416 300v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM164 288c0 -19.8818 -16.1182 -36 -36 -36
s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 192c0 -19.8818 -16.1182 -36 -36 -36s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 96c0 -19.8818 -16.1182 -36 -36 -36s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36z" />
<glyph glyph-name="flag" unicode="&#xf024;"
d="M336.174 368c35.4668 0 73.0195 12.6914 108.922 28.1797c31.6406 13.6514 66.9043 -9.65723 66.9043 -44.1162v-239.919c0 -16.1953 -8.1543 -31.3057 -21.7129 -40.1631c-26.5762 -17.3643 -70.0693 -39.9814 -128.548 -39.9814c-68.6084 0 -112.781 32 -161.913 32
c-56.5674 0 -89.957 -11.2803 -127.826 -28.5566v-83.4434c0 -8.83691 -7.16309 -16 -16 -16h-16c-8.83691 0 -16 7.16309 -16 16v406.438c-14.3428 8.2998 -24 23.7979 -24 41.5615c0 27.5693 23.2422 49.71 51.2012 47.8965
c22.9658 -1.49023 41.8662 -19.4717 44.4805 -42.3379c0.177734 -1.52441 0.321289 -4.00781 0.321289 -5.54199c0 -4.30176 -1.10352 -11.1035 -2.46289 -15.1846c22.418 8.68555 49.4199 15.168 80.7207 15.168c68.6084 0 112.781 -32 161.913 -32zM464 112v240
c-31.5059 -14.6338 -84.5547 -32 -127.826 -32c-59.9111 0 -101.968 32 -161.913 32c-41.4365 0 -80.4766 -16.5879 -102.261 -32v-232c31.4473 14.5967 84.4648 24 127.826 24c59.9111 0 101.968 -32 161.913 -32c41.4365 0 80.4775 16.5879 102.261 32z" />
<glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="384"
d="M336 448c26.5098 0 48 -21.4902 48 -48v-464l-192 112l-192 -112v464c0 26.5098 21.4902 48 48 48h288zM336 19.5703v374.434c0 3.31348 -2.68555 5.99609 -6 5.99609h-276c-3.31152 0 -6 -2.68848 -6 -6v-374.43l144 84z" />
<glyph glyph-name="image" unicode="&#xf03e;"
d="M464 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h416zM458 48c3.31152 0 6 2.68848 6 6v276c0 3.31152 -2.68848 6 -6 6h-404c-3.31152 0 -6 -2.68848 -6 -6v-276
c0 -3.31152 2.68848 -6 6 -6h404zM128 296c22.0908 0 40 -17.9092 40 -40s-17.9092 -40 -40 -40s-40 17.9092 -40 40s17.9092 40 40 40zM96 96v48l39.5137 39.5146c4.6875 4.68652 12.2852 4.68652 16.9717 0l39.5146 -39.5146l119.514 119.515
c4.6875 4.68652 12.2852 4.68652 16.9717 0l87.5146 -87.5146v-80h-320z" />
<glyph glyph-name="edit" unicode="&#xf044;" horiz-adv-x="576"
d="M402.3 103.1l32 32c5 5 13.7002 1.5 13.7002 -5.69922v-145.4c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h273.5c7.09961 0 10.7002 -8.59961 5.7002 -13.7002l-32 -32c-1.5 -1.5 -3.5 -2.2998 -5.7002 -2.2998h-241.5v-352h352
v113.5c0 2.09961 0.799805 4.09961 2.2998 5.59961zM558.9 304.9l-262.601 -262.601l-90.3994 -10c-26.2002 -2.89941 -48.5 19.2002 -45.6006 45.6006l10 90.3994l262.601 262.601c22.8994 22.8994 59.8994 22.8994 82.6992 0l43.2002 -43.2002
c22.9004 -22.9004 22.9004 -60 0.100586 -82.7998zM460.1 274l-58.0996 58.0996l-185.8 -185.899l-7.2998 -65.2998l65.2998 7.2998zM524.9 353.7l-43.2002 43.2002c-4.10059 4.09961 -10.7998 4.09961 -14.7998 0l-30.9004 -30.9004l58.0996 -58.0996l30.9004 30.8994
c4 4.2002 4 10.7998 -0.0996094 14.9004z" />
<glyph glyph-name="times-circle" unicode="&#xf057;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM357.8 254.2l-62.2002 -62.2002l62.2002 -62.2002
c4.7002 -4.7002 4.7002 -12.2998 0 -17l-22.5996 -22.5996c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-62.2002 62.2002l-62.2002 -62.2002c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-22.5996 22.5996c-4.7002 4.7002 -4.7002 12.2998 0 17l62.2002 62.2002l-62.2002 62.2002
c-4.7002 4.7002 -4.7002 12.2998 0 17l22.5996 22.5996c4.7002 4.7002 12.2998 4.7002 17 0l62.2002 -62.2002l62.2002 62.2002c4.7002 4.7002 12.2998 4.7002 17 0l22.5996 -22.5996c4.7002 -4.7002 4.7002 -12.2998 0 -17z" />
<glyph glyph-name="check-circle" unicode="&#xf058;"
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 392c-110.549 0 -200 -89.4678 -200 -200c0 -110.549 89.4678 -200 200 -200c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200z
M396.204 261.733c4.66699 -4.70508 4.63672 -12.3037 -0.0673828 -16.9717l-172.589 -171.204c-4.70508 -4.66797 -12.3027 -4.63672 -16.9697 0.0683594l-90.7812 91.5156c-4.66797 4.70605 -4.63672 12.3047 0.0683594 16.9717l22.7188 22.5361
c4.70508 4.66699 12.3027 4.63574 16.9697 -0.0693359l59.792 -60.2773l141.353 140.216c4.70508 4.66797 12.3027 4.6377 16.9697 -0.0673828z" />
<glyph glyph-name="question-circle" unicode="&#xf059;"
d="M256 440c136.957 0 248 -111.083 248 -248c0 -136.997 -111.043 -248 -248 -248s-248 111.003 -248 248c0 136.917 111.043 248 248 248zM256 -8c110.569 0 200 89.4697 200 200c0 110.529 -89.5088 200 -200 200c-110.528 0 -200 -89.5049 -200 -200
c0 -110.569 89.4678 -200 200 -200zM363.244 247.2c0 -67.0518 -72.4209 -68.084 -72.4209 -92.8633v-6.33691c0 -6.62695 -5.37305 -12 -12 -12h-45.6475c-6.62695 0 -12 5.37305 -12 12v8.65918c0 35.7451 27.1006 50.0342 47.5791 61.5156
c17.5615 9.84473 28.3242 16.541 28.3242 29.5791c0 17.2461 -21.999 28.6934 -39.7842 28.6934c-23.1885 0 -33.8936 -10.9775 -48.9424 -29.9697c-4.05664 -5.11914 -11.46 -6.07031 -16.666 -2.12402l-27.8232 21.0986
c-5.10742 3.87207 -6.25098 11.0654 -2.64453 16.3633c23.627 34.6934 53.7217 54.1846 100.575 54.1846c49.0713 0 101.45 -38.3037 101.45 -88.7998zM298 80c0 -23.1592 -18.8408 -42 -42 -42s-42 18.8408 -42 42s18.8408 42 42 42s42 -18.8408 42 -42z" />
<glyph glyph-name="eye" unicode="&#xf06e;" horiz-adv-x="576"
d="M288 304c0.0927734 0 0.244141 0.000976562 0.336914 0.000976562c61.6641 0 111.71 -50.0469 111.71 -111.711c0 -61.6631 -50.0459 -111.71 -111.71 -111.71s-111.71 50.0469 -111.71 111.71c0 8.71289 1.95898 22.5781 4.37305 30.9502
c6.93066 -3.94141 19.0273 -7.18457 27 -7.24023c30.9121 0 56 25.0879 56 56c-0.0556641 7.97266 -3.29883 20.0693 -7.24023 27c8.42383 2.62207 22.4189 4.8623 31.2402 5zM572.52 206.6c1.9209 -3.79883 3.47949 -10.3379 3.47949 -14.5947
s-1.55859 -10.7959 -3.47949 -14.5947c-54.1992 -105.771 -161.59 -177.41 -284.52 -177.41s-230.29 71.5898 -284.52 177.4c-1.9209 3.79883 -3.47949 10.3379 -3.47949 14.5947s1.55859 10.7959 3.47949 14.5947c54.1992 105.771 161.59 177.41 284.52 177.41
s230.29 -71.5898 284.52 -177.4zM288 48c98.6602 0 189.1 55 237.93 144c-48.8398 89 -139.27 144 -237.93 144s-189.09 -55 -237.93 -144c48.8398 -89 139.279 -144 237.93 -144z" />
<glyph glyph-name="eye-slash" unicode="&#xf070;" horiz-adv-x="640"
d="M634 -23c3.31738 -2.65137 6.00977 -8.25098 6.00977 -12.498c0 -3.10449 -1.57715 -7.58984 -3.51953 -10.0117l-10 -12.4902c-2.65234 -3.31152 -8.24707 -6 -12.4902 -6c-3.09961 0 -7.58008 1.57227 -10 3.50977l-598 467.49
c-3.31738 2.65137 -6.00977 8.25098 -6.00977 12.498c0 3.10449 1.57715 7.58984 3.51953 10.0117l10 12.4902c2.65234 3.31152 8.24707 6 12.4902 6c3.09961 0 7.58008 -1.57227 10 -3.50977zM296.79 301.53c6.33496 1.35059 16.7324 2.45801 23.21 2.46973
c60.4805 0 109.36 -47.9102 111.58 -107.85zM343.21 82.46c-6.33496 -1.34375 -16.7334 -2.44629 -23.21 -2.45996c-60.4697 0 -109.35 47.9102 -111.58 107.84zM320 336c-19.8799 0 -39.2803 -2.7998 -58.2197 -7.09961l-46.4102 36.29
c32.9199 11.8096 67.9297 18.8096 104.63 18.8096c122.93 0 230.29 -71.5898 284.57 -177.4c1.91992 -3.79883 3.47949 -10.3379 3.47949 -14.5947s-1.55957 -10.7959 -3.47949 -14.5947c-11.7197 -22.7598 -35.4189 -56.4092 -52.9004 -75.1104l-37.7402 29.5
c14.333 15.0156 34.0449 41.9854 44 60.2002c-48.8398 89 -139.279 144 -237.93 144zM320 48c19.8896 0 39.2803 2.7998 58.2197 7.08984l46.4102 -36.2803c-32.9199 -11.7598 -67.9297 -18.8096 -104.63 -18.8096c-122.92 0 -230.28 71.5898 -284.51 177.4
c-1.9209 3.79883 -3.47949 10.3379 -3.47949 14.5947s1.55859 10.7959 3.47949 14.5947c11.7168 22.7568 35.4111 56.4014 52.8896 75.1006l37.7402 -29.5c-14.3467 -15.0107 -34.0811 -41.9756 -44.0498 -60.1904c48.8496 -89 139.279 -144 237.93 -144z" />
<glyph glyph-name="calendar-alt" unicode="&#xf073;" horiz-adv-x="448"
d="M148 160h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM256 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
c6.59961 0 12 -5.40039 12 -12v-40zM352 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM256 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM160 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM352 76c0 -6.59961 -5.40039 -12 -12 -12h-40
c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40
c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="comment" unicode="&#xf075;"
d="M256 416c141.4 0 256 -93.0996 256 -208s-114.6 -208 -256 -208c-32.7998 0 -64 5.2002 -92.9004 14.2998c-29.0996 -20.5996 -77.5996 -46.2998 -139.1 -46.2998c-9.59961 0 -18.2998 5.7002 -22.0996 14.5c-3.80078 8.7998 -2 19 4.59961 26
c0.5 0.400391 31.5 33.7998 46.4004 73.2002c-33 35.0996 -52.9004 78.7002 -52.9004 126.3c0 114.9 114.6 208 256 208zM256 48c114.7 0 208 71.7998 208 160s-93.2998 160 -208 160s-208 -71.7998 -208 -160c0 -42.2002 21.7002 -74.0996 39.7998 -93.4004
l20.6006 -21.7998l-10.6006 -28.0996c-5.5 -14.5 -12.5996 -28.1006 -19.8994 -40.2002c23.5996 7.59961 43.1992 18.9004 57.5 29l19.5 13.7998l22.6992 -7.2002c25.3008 -8 51.7002 -12.0996 78.4004 -12.0996z" />
<glyph glyph-name="folder" unicode="&#xf07b;"
d="M464 320c26.5098 0 48 -21.4902 48 -48v-224c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h146.74c8.49023 0 16.6299 -3.37012 22.6299 -9.37012l54.6299 -54.6299h192zM464 48v224h-198.62
c-8.49023 0 -16.6299 3.37012 -22.6299 9.37012l-54.6299 54.6299h-140.12v-288h416z" />
<glyph glyph-name="folder-open" unicode="&#xf07c;" horiz-adv-x="576"
d="M527.9 224c37.6992 0 60.6992 -41.5 40.6992 -73.4004l-79.8994 -128c-8.7998 -14.0996 -24.2002 -22.5996 -40.7002 -22.5996h-400c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h160l64 -64h160c26.5 0 48 -21.5 48 -48v-48h47.9004zM48 330v-233.4l62.9004 104.2
c8.69922 14.4004 24.2998 23.2002 41.0996 23.2002h280v42c0 3.2998 -2.7002 6 -6 6h-173.9l-64 64h-134.1c-3.2998 0 -6 -2.7002 -6 -6zM448 48l80 128h-378.8l-77.2002 -128h376z" />
<glyph glyph-name="chart-bar" unicode="&#xf080;"
d="M396.8 96c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v230.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-230.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM204.8 96
c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v198.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-198.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM300.8 96
c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v134.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-134.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM496 48c8.83984 0 16 -7.16016 16 -16v-16
c0 -8.83984 -7.16016 -16 -16 -16h-464c-17.6699 0 -32 14.3301 -32 32v336c0 8.83984 7.16016 16 16 16h16c8.83984 0 16 -7.16016 16 -16v-320h448zM108.8 96c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v70.4004c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004
c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-70.4004c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004z" />
<glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="576"
d="M532 61.7998c15.2998 -30.7002 37.4004 -54.5 37.7998 -54.7998c6.2998 -6.7002 8 -16.5 4.40039 -25c-3.7002 -8.5 -12 -14 -21.2002 -14c-53.5996 0 -96.7002 20.2998 -125.2 38.7998c-19 -4.39941 -39 -6.7998 -59.7998 -6.7998
c-86.2002 0 -159.9 40.4004 -191.3 97.7998c-9.7002 1.2002 -19.2002 2.7998 -28.4004 4.90039c-28.5 -18.6006 -71.7002 -38.7998 -125.2 -38.7998c-9.19922 0 -17.5996 5.5 -21.1992 14c-3.7002 8.5 -1.90039 18.2998 4.39941 25
c0.400391 0.399414 22.4004 24.1992 37.7002 54.8994c-27.5 27.2002 -44 61.2002 -44 98.2002c0 88.4004 93.0996 160 208 160c86.2998 0 160.3 -40.5 191.8 -98.0996c99.7002 -11.8008 176.2 -77.9004 176.2 -157.9c0 -37.0996 -16.5 -71.0996 -44 -98.2002zM139.2 154.1
l19.7998 -4.5c16 -3.69922 32.5 -5.59961 49 -5.59961c86.7002 0 160 51.2998 160 112s-73.2998 112 -160 112s-160 -51.2998 -160 -112c0 -28.7002 16.2002 -50.5996 29.7002 -64l24.7998 -24.5l-15.5 -31.0996c-2.59961 -5.10059 -5.2998 -10.1006 -8 -14.8008
c14.5996 5.10059 29 12.3008 43.0996 21.4004zM498.3 96c13.5 13.4004 29.7002 35.2998 29.7002 64c0 49.2002 -48.2998 91.5 -112.7 106c0.299805 -3.2998 0.700195 -6.59961 0.700195 -10c0 -80.9004 -78 -147.5 -179.3 -158.3
c29.0996 -29.6006 77.2998 -49.7002 131.3 -49.7002c16.5 0 33 1.90039 49 5.59961l19.9004 4.60059l17.0996 -11.1006c14.0996 -9.09961 28.5 -16.2998 43.0996 -21.3994c-2.69922 4.7002 -5.39941 9.7002 -8 14.7998l-15.5 31.0996z" />
<glyph glyph-name="star-half" unicode="&#xf089;" horiz-adv-x="576"
d="M288 62.7002v-54.2998l-130.7 -68.6006c-23.3994 -12.2998 -50.8994 7.60059 -46.3994 33.7002l25 145.5l-105.7 103c-19 18.5 -8.5 50.7998 17.7002 54.5996l146.1 21.2002l65.2998 132.4c5.90039 11.8994 17.2998 17.7998 28.7002 17.7998v-68.0996l-62.2002 -126
l-139 -20.2002l100.601 -98l-23.7002 -138.4z" />
<glyph glyph-name="lemon" unicode="&#xf094;"
d="M484.112 420.111c28.1221 -28.123 35.9434 -68.0039 19.0215 -97.0547c-23.0576 -39.584 50.1436 -163.384 -82.3311 -295.86c-132.301 -132.298 -256.435 -59.3594 -295.857 -82.3291c-29.0459 -16.917 -68.9219 -9.11426 -97.0576 19.0205
c-28.1221 28.1221 -35.9434 68.0029 -19.0215 97.0547c23.0566 39.5859 -50.1436 163.386 82.3301 295.86c132.308 132.309 256.407 59.3496 295.862 82.332c29.0498 16.9219 68.9307 9.09863 97.0537 -19.0234zM461.707 347.217
c13.5166 23.2031 -27.7578 63.7314 -50.4883 50.4912c-66.6025 -38.7939 -165.646 45.5898 -286.081 -74.8457c-120.444 -120.445 -36.0449 -219.472 -74.8447 -286.08c-13.542 -23.2471 27.8145 -63.6953 50.4932 -50.4883
c66.6006 38.7949 165.636 -45.5996 286.076 74.8428c120.444 120.445 36.0449 219.472 74.8447 286.08zM291.846 338.481c1.37012 -10.96 -6.40332 -20.957 -17.3643 -22.3271c-54.8467 -6.85547 -135.779 -87.7871 -142.636 -142.636
c-1.37305 -10.9883 -11.3984 -18.7334 -22.3262 -17.3643c-10.9609 1.37012 -18.7344 11.3652 -17.3643 22.3262c9.16211 73.2852 104.167 168.215 177.364 177.364c10.9531 1.36816 20.9561 -6.40234 22.3262 -17.3633z" />
<glyph glyph-name="credit-card" unicode="&#xf09d;" horiz-adv-x="576"
d="M527.9 416c26.5996 0 48.0996 -21.5 48.0996 -48v-352c0 -26.5 -21.5 -48 -48.0996 -48h-479.801c-26.5996 0 -48.0996 21.5 -48.0996 48v352c0 26.5 21.5 48 48.0996 48h479.801zM54.0996 368c-3.2998 0 -6 -2.7002 -6 -6v-42h479.801v42c0 3.2998 -2.7002 6 -6 6
h-467.801zM521.9 16c3.2998 0 6 2.7002 6 6v170h-479.801v-170c0 -3.2998 2.7002 -6 6 -6h467.801zM192 116v-40c0 -6.59961 -5.40039 -12 -12 -12h-72c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h72c6.59961 0 12 -5.40039 12 -12zM384 116v-40
c0 -6.59961 -5.40039 -12 -12 -12h-136c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h136c6.59961 0 12 -5.40039 12 -12z" />
<glyph glyph-name="hdd" unicode="&#xf0a0;" horiz-adv-x="576"
d="M567.403 212.358c5.59668 -8.04688 8.59668 -17.6113 8.59668 -27.4121v-136.946c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v136.946c0 8.30957 3.85156 20.5898 8.59668 27.4121l105.08 151.053
c7.90625 11.3652 25.5596 20.5889 39.4033 20.5889h0.000976562h269.838h0.000976562c13.8438 0 31.4971 -9.22363 39.4033 -20.5889zM153.081 336l-77.9131 -112h425.664l-77.9131 112h-269.838zM528 48v128h-480v-128h480zM496 112c0 -17.6729 -14.3271 -32 -32 -32
s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32zM400 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32z" />
<glyph glyph-name="hand-point-right" unicode="&#xf0a4;"
d="M428.8 310.4c45.0996 0 83.2002 -38.1016 83.2002 -83.2002c0 -45.6162 -37.7646 -83.2002 -83.2002 -83.2002h-35.6475c-1.41602 -6.36719 -4.96875 -16.252 -7.92969 -22.0645c2.50586 -22.0059 -3.50293 -44.9775 -15.9844 -62.791
c-1.14062 -52.4863 -37.3984 -91.1445 -99.9404 -91.1445h-21.2988c-60.0635 0 -98.5117 40 -127.2 40h-2.67871c-5.74707 -4.95215 -13.5361 -8 -22.1201 -8h-64c-17.6729 0 -32 12.8936 -32 28.7998v230.4c0 15.9062 14.3271 28.7998 32 28.7998h64.001
c8.58398 0 16.373 -3.04785 22.1201 -8h2.67871c6.96387 0 14.8623 6.19336 30.1816 23.6689l0.128906 0.148438l0.130859 0.145508c8.85645 9.93652 18.1162 20.8398 25.8506 33.2529c18.7051 30.2471 30.3936 78.7842 75.707 78.7842c56.9277 0 92 -35.2861 92 -83.2002
v-0.0839844c0 -6.21777 -0.974609 -16.2148 -2.17578 -22.3154h86.1768zM428.8 192c18.9756 0 35.2002 16.2246 35.2002 35.2002c0 18.7002 -16.7754 35.2002 -35.2002 35.2002h-158.399c0 17.3242 26.3994 35.1992 26.3994 70.3994c0 26.4004 -20.625 35.2002 -44 35.2002
c-8.79395 0 -20.4443 -32.7119 -34.9258 -56.0996c-9.07422 -14.5752 -19.5244 -27.2256 -30.7988 -39.875c-16.1094 -18.374 -33.8359 -36.6328 -59.0752 -39.5967v-176.753c42.79 -3.7627 74.5088 -39.6758 120 -39.6758h21.2988
c40.5244 0 57.124 22.1973 50.6006 61.3252c14.6113 8.00098 24.1514 33.9785 12.9248 53.625c19.3652 18.2246 17.7871 46.3809 4.9502 61.0498h91.0254zM88 64c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
<glyph glyph-name="hand-point-left" unicode="&#xf0a5;"
d="M0 227.2c0 45.0986 38.1006 83.2002 83.2002 83.2002h86.1758c-1.3623 6.91016 -2.17578 14.374 -2.17578 22.3994c0 47.9141 35.0723 83.2002 92 83.2002c45.3135 0 57.002 -48.5371 75.7061 -78.7852c7.73438 -12.4121 16.9951 -23.3154 25.8506 -33.2529
l0.130859 -0.145508l0.128906 -0.148438c15.3213 -17.4746 23.2197 -23.668 30.1836 -23.668h2.67871c5.74707 4.95215 13.5361 8 22.1201 8h64c17.6729 0 32 -12.8936 32 -28.7998v-230.4c0 -15.9062 -14.3271 -28.7998 -32 -28.7998h-64
c-8.58398 0 -16.373 3.04785 -22.1201 8h-2.67871c-28.6885 0 -67.1367 -40 -127.2 -40h-21.2988c-62.542 0 -98.8008 38.6582 -99.9404 91.1445c-12.4814 17.8135 -18.4922 40.7852 -15.9844 62.791c-2.96094 5.8125 -6.51367 15.6973 -7.92969 22.0645h-35.6465
c-45.4355 0 -83.2002 37.584 -83.2002 83.2002zM48 227.2c0 -18.9756 16.2246 -35.2002 35.2002 -35.2002h91.0244c-12.8369 -14.6689 -14.415 -42.8252 4.9502 -61.0498c-11.2256 -19.6465 -1.68652 -45.624 12.9248 -53.625
c-6.52246 -39.1279 10.0771 -61.3252 50.6016 -61.3252h21.2988c45.4912 0 77.21 35.9131 120 39.6768v176.752c-25.2393 2.96289 -42.9658 21.2227 -59.0752 39.5967c-11.2744 12.6494 -21.7246 25.2998 -30.7988 39.875
c-14.4814 23.3877 -26.1318 56.0996 -34.9258 56.0996c-23.375 0 -44 -8.7998 -44 -35.2002c0 -35.2002 26.3994 -53.0752 26.3994 -70.3994h-158.399c-18.4248 0 -35.2002 -16.5 -35.2002 -35.2002zM448 88c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24
s24 10.7451 24 24s-10.7451 24 -24 24z" />
<glyph glyph-name="hand-point-up" unicode="&#xf0a6;" horiz-adv-x="448"
d="M105.6 364.8c0 45.0996 38.1016 83.2002 83.2002 83.2002c45.6162 0 83.2002 -37.7646 83.2002 -83.2002v-35.6465c6.36719 -1.41602 16.252 -4.96875 22.0645 -7.92969c22.0059 2.50684 44.9775 -3.50293 62.791 -15.9844
c52.4863 -1.14062 91.1445 -37.3984 91.1445 -99.9404v-21.2988c0 -60.0635 -40 -98.5117 -40 -127.2v-2.67871c4.95215 -5.74707 8 -13.5361 8 -22.1201v-64c0 -17.6729 -12.8936 -32 -28.7998 -32h-230.4c-15.9062 0 -28.7998 14.3271 -28.7998 32v64
c0 8.58398 3.04785 16.373 8 22.1201v2.67871c0 6.96387 -6.19336 14.8623 -23.6689 30.1816l-0.148438 0.128906l-0.145508 0.130859c-9.93652 8.85645 -20.8398 18.1162 -33.2529 25.8506c-30.2471 18.7051 -78.7842 30.3936 -78.7842 75.707
c0 56.9277 35.2861 92 83.2002 92h0.0839844c6.21777 0 16.2148 -0.974609 22.3154 -2.17578v86.1768zM224 364.8c0 18.9756 -16.2246 35.2002 -35.2002 35.2002c-18.7002 0 -35.2002 -16.7754 -35.2002 -35.2002v-158.399c-17.3242 0 -35.1992 26.3994 -70.3994 26.3994
c-26.4004 0 -35.2002 -20.625 -35.2002 -44c0 -8.79395 32.7119 -20.4443 56.0996 -34.9258c14.5752 -9.07422 27.2256 -19.5244 39.875 -30.7988c18.374 -16.1094 36.6328 -33.8359 39.5967 -59.0752h176.753c3.7627 42.79 39.6758 74.5088 39.6758 120v21.2988
c0 40.5244 -22.1973 57.124 -61.3252 50.6006c-8.00098 14.6113 -33.9785 24.1514 -53.625 12.9248c-18.2246 19.3652 -46.3809 17.7871 -61.0498 4.9502v91.0254zM352 24c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24z" />
<glyph glyph-name="hand-point-down" unicode="&#xf0a7;" horiz-adv-x="448"
d="M188.8 -64c-45.0986 0 -83.2002 38.1006 -83.2002 83.2002v86.1758c-6.91016 -1.3623 -14.374 -2.17578 -22.3994 -2.17578c-47.9141 0 -83.2002 35.0723 -83.2002 92c0 45.3135 48.5371 57.002 78.7852 75.707c12.4121 7.73438 23.3154 16.9951 33.2529 25.8506
l0.145508 0.130859l0.148438 0.128906c17.4746 15.3213 23.668 23.2197 23.668 30.1836v2.67871c-4.95215 5.74707 -8 13.5361 -8 22.1201v64c0 17.6729 12.8936 32 28.7998 32h230.4c15.9062 0 28.7998 -14.3271 28.7998 -32v-64.001
c0 -8.58398 -3.04785 -16.373 -8 -22.1201v-2.67871c0 -28.6885 40 -67.1367 40 -127.2v-21.2988c0 -62.542 -38.6582 -98.8008 -91.1445 -99.9404c-17.8135 -12.4814 -40.7852 -18.4922 -62.791 -15.9844c-5.8125 -2.96094 -15.6973 -6.51367 -22.0645 -7.92969v-35.6465
c0 -45.4355 -37.584 -83.2002 -83.2002 -83.2002zM188.8 -16c18.9756 0 35.2002 16.2246 35.2002 35.2002v91.0244c14.6689 -12.8369 42.8252 -14.415 61.0498 4.9502c19.6465 -11.2256 45.624 -1.68652 53.625 12.9248c39.1279 -6.52246 61.3252 10.0771 61.3252 50.6016
v21.2988c0 45.4912 -35.9131 77.21 -39.6768 120h-176.752c-2.96289 -25.2393 -21.2227 -42.9658 -39.5967 -59.0752c-12.6494 -11.2744 -25.2998 -21.7246 -39.875 -30.7988c-23.3877 -14.4814 -56.0996 -26.1318 -56.0996 -34.9258c0 -23.375 8.7998 -44 35.2002 -44
c35.2002 0 53.0752 26.3994 70.3994 26.3994v-158.399c0 -18.4248 16.5 -35.2002 35.2002 -35.2002zM328 384c0 -13.2549 10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24z" />
<glyph glyph-name="copy" unicode="&#xf0c5;" horiz-adv-x="448"
d="M433.941 382.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-80v-48c0 -26.5098 -21.4902 -48 -48 -48h-224c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h80v48c0 26.5098 21.4902 48 48 48
h172.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM266 -16c3.31152 0 6 2.68848 6 6v42h-96c-26.5098 0 -48 21.4902 -48 48v224h-74c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM394 80c3.31152 0 6 2.68848 6 6v202h-88
c-13.2549 0 -24 10.7451 -24 24v88h-106c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM400 336v9.63184v0.000976562c0 1.37207 -0.787109 3.27246 -1.75684 4.24219l-48.3682 48.3682c-1.12598 1.125 -2.65234 1.75684 -4.24316 1.75684h-9.63184
v-64h64z" />
<glyph glyph-name="save" unicode="&#xf0c7;" horiz-adv-x="448"
d="M433.941 318.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h268.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM272 368h-128v-80h128v80
zM394 16c3.31152 0 6 2.68848 6 6v259.632v0.000976562c0 1.37207 -0.787109 3.27246 -1.75684 4.24219l-78.2432 78.2432v-100.118c0 -13.2549 -10.7451 -24 -24 -24h-176c-13.2549 0 -24 10.7451 -24 24v104h-42c-3.31152 0 -6 -2.68848 -6 -6v-340
c0 -3.31152 2.68848 -6 6 -6h340zM224 216c48.5234 0 88 -39.4766 88 -88s-39.4766 -88 -88 -88s-88 39.4766 -88 88s39.4766 88 88 88zM224 88c22.0557 0 40 17.9443 40 40s-17.9443 40 -40 40s-40 -17.9443 -40 -40s17.9443 -40 40 -40z" />
<glyph glyph-name="square" unicode="&#xf0c8;" horiz-adv-x="448"
d="M400 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352zM394 16c3.2998 0 6 2.7002 6 6v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340z" />
<glyph glyph-name="envelope" unicode="&#xf0e0;"
d="M464 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h416zM464 336h-416v-40.8047c22.4248 -18.2627 58.1797 -46.6602 134.587 -106.49
c16.834 -13.2422 50.2051 -45.0762 73.4131 -44.7012c23.2119 -0.371094 56.5723 31.4541 73.4131 44.7012c76.4189 59.8389 112.165 88.2305 134.587 106.49v40.8047zM48 48h416v185.601c-22.915 -18.252 -55.4189 -43.8691 -104.947 -82.6523
c-22.5439 -17.748 -60.3359 -55.1787 -103.053 -54.9473c-42.9277 -0.231445 -81.2051 37.75 -103.062 54.9551c-49.5293 38.7842 -82.0244 64.3945 -104.938 82.6455v-185.602z" />
<glyph glyph-name="lightbulb" unicode="&#xf0eb;" horiz-adv-x="352"
d="M176 368c8.83984 0 16 -7.16016 16 -16s-7.16016 -16 -16 -16c-35.2803 0 -64 -28.7002 -64 -64c0 -8.83984 -7.16016 -16 -16 -16s-16 7.16016 -16 16c0 52.9404 43.0596 96 96 96zM96.0596 -11.1699l-0.0400391 43.1797h159.961l-0.0507812 -43.1797
c-0.00976562 -3.13965 -0.939453 -6.21973 -2.67969 -8.83984l-24.5098 -36.8398c-2.95996 -4.45996 -7.95996 -7.14062 -13.3203 -7.14062h-78.8496c-5.35059 0 -10.3506 2.68066 -13.3203 7.14062l-24.5098 36.8398c-1.75 2.62012 -2.68066 5.68945 -2.68066 8.83984z
M176 448c97.2002 0 176 -78.7998 176 -176c0 -44.3701 -16.4502 -84.8496 -43.5498 -115.79c-16.6406 -18.9795 -42.7402 -58.79 -52.4199 -92.1602v-0.0498047h-48v0.0996094c0.00390625 4.04199 0.999023 10.4482 2.21973 14.3008
c5.67969 17.9893 22.9902 64.8496 62.0996 109.46c20.4102 23.29 31.6504 53.1699 31.6504 84.1396c0 70.5801 -57.4199 128 -128 128c-68.2803 0 -128.15 -54.3604 -127.95 -128c0.0898438 -30.9902 11.0703 -60.71 31.6104 -84.1396
c39.3496 -44.9004 56.5801 -91.8604 62.1699 -109.67c1.42969 -4.56055 2.13965 -9.30078 2.15039 -14.0703v-0.120117h-48v0.0595703c-9.68066 33.3604 -35.7803 73.1709 -52.4209 92.1602c-27.1094 30.9307 -43.5596 71.4102 -43.5596 115.78
c0 93.0303 73.7197 176 176 176z" />
<glyph glyph-name="bell" unicode="&#xf0f3;" horiz-adv-x="448"
d="M439.39 85.71c6 -6.44043 8.66016 -14.1602 8.61035 -21.71c-0.0996094 -16.4004 -12.9805 -32 -32.0996 -32h-383.801c-19.1191 0 -31.9893 15.5996 -32.0996 32c-0.0498047 7.5498 2.61035 15.2598 8.61035 21.71c19.3193 20.7598 55.4697 51.9902 55.4697 154.29
c0 77.7002 54.4795 139.9 127.939 155.16v20.8398c0 17.6699 14.3203 32 31.9805 32s31.9805 -14.3301 31.9805 -32v-20.8398c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -102.3 36.1504 -133.53 55.4697 -154.29zM67.5303 80h312.939
c-21.2197 27.96 -44.4199 74.3203 -44.5293 159.42c0 0.200195 0.0595703 0.379883 0.0595703 0.580078c0 61.8604 -50.1396 112 -112 112s-112 -50.1396 -112 -112c0 -0.200195 0.0595703 -0.379883 0.0595703 -0.580078
c-0.109375 -85.0898 -23.3096 -131.45 -44.5293 -159.42zM224 -64c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
<glyph glyph-name="hospital" unicode="&#xf0f8;" horiz-adv-x="448"
d="M128 204v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40c0 -6.62695 -5.37305 -12 -12 -12h-40c-6.62695 0 -12 5.37305 -12 12zM268 192c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40
c0 -6.62695 -5.37305 -12 -12 -12h-40zM192 108c0 -6.62695 -5.37305 -12 -12 -12h-40c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40zM268 96c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40
c6.62695 0 12 -5.37305 12 -12v-40c0 -6.62695 -5.37305 -12 -12 -12h-40zM448 -28v-36h-448v36c0 6.62695 5.37305 12 12 12h19.5v378.965c0 11.6172 10.7451 21.0352 24 21.0352h88.5v40c0 13.2549 10.7451 24 24 24h112c13.2549 0 24 -10.7451 24 -24v-40h88.5
c13.2549 0 24 -9.41797 24 -21.0352v-378.965h19.5c6.62695 0 12 -5.37305 12 -12zM79.5 -15h112.5v67c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-67h112.5v351h-64.5v-24c0 -13.2549 -10.7451 -24 -24 -24h-112c-13.2549 0 -24 10.7451 -24 24v24
h-64.5v-351zM266 384h-26v26c0 3.31152 -2.68848 6 -6 6h-20c-3.31152 0 -6 -2.68848 -6 -6v-26h-26c-3.31152 0 -6 -2.68848 -6 -6v-20c0 -3.31152 2.68848 -6 6 -6h26v-26c0 -3.31152 2.68848 -6 6 -6h20c3.31152 0 6 2.68848 6 6v26h26c3.31152 0 6 2.68848 6 6v20
c0 3.31152 -2.68848 6 -6 6z" />
<glyph glyph-name="plus-square" unicode="&#xf0fe;" horiz-adv-x="448"
d="M352 208v-32c0 -6.59961 -5.40039 -12 -12 -12h-88v-88c0 -6.59961 -5.40039 -12 -12 -12h-32c-6.59961 0 -12 5.40039 -12 12v88h-88c-6.59961 0 -12 5.40039 -12 12v32c0 6.59961 5.40039 12 12 12h88v88c0 6.59961 5.40039 12 12 12h32c6.59961 0 12 -5.40039 12 -12
v-88h88c6.59961 0 12 -5.40039 12 -12zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340
c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="circle" unicode="&#xf111;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200z" />
<glyph glyph-name="smile" unicode="&#xf118;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM332 135.4c8.5 10.1992 23.7002 11.5 33.7998 3.09961c10.2002 -8.5 11.6006 -23.5996 3.10059 -33.7998
c-30 -36 -74.1006 -56.6006 -120.9 -56.6006s-90.9004 20.6006 -120.9 56.6006c-8.39941 10.2002 -7.09961 25.2998 3.10059 33.7998c10.0996 8.40039 25.2998 7.09961 33.7998 -3.09961c20.7998 -25.1006 51.5 -39.4004 84 -39.4004s63.2002 14.4004 84 39.4004z" />
<glyph glyph-name="frown" unicode="&#xf119;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM248 144c40.2002 0 78 -17.7002 103.8 -48.5996c8.40039 -10.2002 7.10059 -25.3008 -3.09961 -33.8008
c-10.7002 -8.7998 -25.7002 -6.59961 -33.7998 3.10059c-16.6006 20 -41 31.3994 -66.9004 31.3994s-50.2998 -11.5 -66.9004 -31.3994c-8.5 -10.2002 -23.5996 -11.5 -33.7998 -3.10059c-10.2002 8.5 -11.5996 23.6006 -3.09961 33.8008
c25.7998 30.8994 63.5996 48.5996 103.8 48.5996z" />
<glyph glyph-name="meh" unicode="&#xf11a;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM336 128c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-176c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h176z
" />
<glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="576"
d="M528 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h480zM536 48v288c0 4.41113 -3.58887 8 -8 8h-480c-4.41113 0 -8 -3.58887 -8 -8v-288c0 -4.41113 3.58887 -8 8 -8
h480c4.41113 0 8 3.58887 8 8zM170 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM266 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28
c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM362 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM458 178c0 -6.62695 -5.37305 -12 -12 -12h-28
c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM122 96c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM506 96
c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM122 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28
c6.62695 0 12 -5.37305 12 -12v-28zM218 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM314 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28
c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM410 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM506 260c0 -6.62695 -5.37305 -12 -12 -12h-28
c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM408 102c0 -6.62695 -5.37305 -12 -12 -12h-216c-6.62695 0 -12 5.37305 -12 12v16c0 6.62695 5.37305 12 12 12h216c6.62695 0 12 -5.37305 12 -12v-16z" />
<glyph glyph-name="calendar" unicode="&#xf133;" horiz-adv-x="448"
d="M400 384c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12
v-52h48zM394 -16c3.2998 0 6 2.7002 6 6v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340z" />
<glyph glyph-name="play-circle" unicode="&#xf144;"
d="M371.7 210c16.3994 -9.2002 16.3994 -32.9004 0 -42l-176 -101c-15.9004 -8.7998 -35.7002 2.59961 -35.7002 21v208c0 18.5 19.9004 29.7998 35.7002 21zM504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192
c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200z" />
<glyph glyph-name="minus-square" unicode="&#xf146;" horiz-adv-x="448"
d="M108 164c-6.59961 0 -12 5.40039 -12 12v32c0 6.59961 5.40039 12 12 12h232c6.59961 0 12 -5.40039 12 -12v-32c0 -6.59961 -5.40039 -12 -12 -12h-232zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352
c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="check-square" unicode="&#xf14a;" horiz-adv-x="448"
d="M400 416c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h352zM400 16v352h-352v-352h352zM364.136 257.724l-172.589 -171.204
c-4.70508 -4.66699 -12.3027 -4.63672 -16.9697 0.0683594l-90.7812 91.5156c-4.66699 4.70508 -4.63672 12.3037 0.0693359 16.9717l22.7188 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l59.792 -60.2773l141.353 140.217
c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0683594l22.5361 -22.7178c4.66699 -4.70605 4.63672 -12.3047 -0.0683594 -16.9717z" />
<glyph glyph-name="share-square" unicode="&#xf14d;" horiz-adv-x="576"
d="M561.938 289.94c18.75 -18.7402 18.75 -49.1406 0 -67.8809l-143.998 -144c-29.9727 -29.9727 -81.9404 -9.05273 -81.9404 33.9404v53.7998c-101.266 -7.83691 -99.625 -31.6406 -84.1104 -78.7598c14.2285 -43.0889 -33.4736 -79.248 -71.0195 -55.7402
c-51.6924 32.3057 -84.8701 83.0635 -84.8701 144.76c0 39.3408 12.2197 72.7402 36.3301 99.3008c19.8398 21.8398 47.7402 38.4697 82.9102 49.4199c36.7295 11.4395 78.3096 16.1094 120.76 17.9893v57.1982c0 42.9355 51.9258 63.9541 81.9404 33.9404zM384 112l144 144
l-144 144v-104.09c-110.86 -0.90332 -240 -10.5166 -240 -119.851c0 -52.1396 32.79 -85.6094 62.3096 -104.06c-39.8174 120.65 48.999 141.918 177.69 143.84v-103.84zM408.74 27.5068c6.14844 1.75684 15.5449 5.92383 20.9736 9.30273
c7.97656 4.95215 18.2861 -0.825195 18.2861 -10.2139v-42.5957c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h132c6.62695 0 12 -5.37305 12 -12v-4.48633c0 -4.91699 -2.9873 -9.36914 -7.56934 -11.1514
c-13.7021 -5.33105 -26.3955 -11.5371 -38.0498 -18.585c-1.59668 -0.974609 -4.41016 -1.77051 -6.28027 -1.77734h-86.1006c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340c3.31152 0 6 2.68848 6 6v25.9658c0 5.37012 3.5791 10.0596 8.74023 11.541
z" />
<glyph glyph-name="compass" unicode="&#xf14e;" horiz-adv-x="496"
d="M347.94 318.14c16.6592 7.61035 33.8096 -9.54004 26.1992 -26.1992l-65.9697 -144.341c-2.73047 -5.97363 -9.7959 -13.0391 -15.7695 -15.7695l-144.341 -65.9697c-16.6592 -7.61035 -33.8096 9.5498 -26.1992 26.1992l65.9697 144.341
c2.73047 5.97363 9.7959 13.0391 15.7695 15.7695zM270.58 169.42c12.4697 12.4697 12.4697 32.6904 0 45.1602s-32.6904 12.4697 -45.1602 0s-12.4697 -32.6904 0 -45.1602s32.6904 -12.4697 45.1602 0zM248 440c136.97 0 248 -111.03 248 -248s-111.03 -248 -248 -248
s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
<glyph glyph-name="caret-square-down" unicode="&#xf150;" horiz-adv-x="448"
d="M125.1 240h197.801c10.6992 0 16.0996 -13 8.5 -20.5l-98.9004 -98.2998c-4.7002 -4.7002 -12.2002 -4.7002 -16.9004 0l-98.8994 98.2998c-7.7002 7.5 -2.2998 20.5 8.39941 20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="caret-square-up" unicode="&#xf151;" horiz-adv-x="448"
d="M322.9 144h-197.801c-10.6992 0 -16.0996 13 -8.5 20.5l98.9004 98.2998c4.7002 4.7002 12.2002 4.7002 16.9004 0l98.8994 -98.2998c7.7002 -7.5 2.2998 -20.5 -8.39941 -20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="caret-square-right" unicode="&#xf152;" horiz-adv-x="448"
d="M176 93.0996v197.801c0 10.6992 13 16.0996 20.5 8.5l98.2998 -98.9004c4.7002 -4.7002 4.7002 -12.2002 0 -16.9004l-98.2998 -98.8994c-7.5 -7.7002 -20.5 -2.2998 -20.5 8.39941zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="file" unicode="&#xf15b;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416z" />
<glyph glyph-name="file-alt" unicode="&#xf15c;" horiz-adv-x="384"
d="M288 200v-28c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12v28c0 6.59961 5.40039 12 12 12h168c6.59961 0 12 -5.40039 12 -12zM276 128c6.59961 0 12 -5.40039 12 -12v-28c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12
v28c0 6.59961 5.40039 12 12 12h168zM384 316.1v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996l83.9004 -83.9004c9 -8.90039 14.0996 -21.2002 14.0996 -33.9004z
M256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416h288z" />
<glyph glyph-name="thumbs-up" unicode="&#xf164;"
d="M466.27 161.31c4.6748 -22.6465 0.864258 -44.5371 -8.98926 -62.9893c2.95898 -23.8682 -4.02148 -48.5654 -17.3398 -66.9902c-0.954102 -55.9072 -35.8232 -95.3301 -112.94 -95.3301c-7 0 -15 0.00976562 -22.2197 0.00976562
c-102.742 0 -133.293 38.9395 -177.803 39.9404c-3.56934 -13.7764 -16.085 -23.9502 -30.9775 -23.9502h-64c-17.6729 0 -32 14.3271 -32 32v240c0 17.6729 14.3271 32 32 32h98.7598c19.1455 16.9531 46.0137 60.6533 68.7598 83.4004
c13.667 13.667 10.1533 108.6 71.7607 108.6c57.5801 0 95.2695 -31.9355 95.2695 -104.73c0 -18.4092 -3.92969 -33.7295 -8.84961 -46.5391h36.4795c48.6025 0 85.8203 -41.5654 85.8203 -85.5801c0 -19.1504 -4.95996 -34.9902 -13.7305 -49.8408zM404.52 107.48
c21.5811 20.3838 18.6992 51.0645 5.21094 65.6191c9.44922 0 22.3594 18.9102 22.2695 37.8105c-0.0898438 18.9102 -16.71 37.8203 -37.8203 37.8203h-103.989c0 37.8193 28.3594 55.3691 28.3594 94.5391c0 23.75 0 56.7305 -47.2695 56.7305
c-18.9102 -18.9102 -9.45996 -66.1797 -37.8203 -94.54c-26.5596 -26.5703 -66.1797 -97.46 -94.54 -97.46h-10.9199v-186.17c53.6113 0 100.001 -37.8203 171.64 -37.8203h37.8203c35.5117 0 60.8203 17.1201 53.1201 65.9004
c15.2002 8.16016 26.5 36.4395 13.9395 57.5703zM88 16c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
<glyph glyph-name="thumbs-down" unicode="&#xf165;"
d="M466.27 222.69c8.77051 -14.8506 13.7305 -30.6904 13.7305 -49.8408c0 -44.0146 -37.2178 -85.5801 -85.8203 -85.5801h-36.4795c4.91992 -12.8096 8.84961 -28.1299 8.84961 -46.5391c0 -72.7949 -37.6895 -104.73 -95.2695 -104.73
c-61.6074 0 -58.0938 94.9326 -71.7607 108.6c-22.7461 22.7471 -49.6133 66.4473 -68.7598 83.4004h-7.05176c-5.5332 -9.56152 -15.8662 -16 -27.708 -16h-64c-17.6729 0 -32 14.3271 -32 32v240c0 17.6729 14.3271 32 32 32h64c8.11328 0 15.5146 -3.02539 21.1553 -8
h10.8447c40.9971 0 73.1953 39.9902 176.78 39.9902c7.21973 0 15.2197 0.00976562 22.2197 0.00976562c77.1172 0 111.986 -39.4229 112.94 -95.3301c13.3184 -18.4248 20.2979 -43.1221 17.3398 -66.9902c9.85352 -18.4521 13.6641 -40.3428 8.98926 -62.9893zM64 152
c13.2549 0 24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24zM394.18 135.27c21.1104 0 37.7305 18.9102 37.8203 37.8203c0.0898438 18.9004 -12.8203 37.8105 -22.2695 37.8105c13.4883 14.5547 16.3701 45.2354 -5.21094 65.6191
c12.5605 21.1309 1.26074 49.4102 -13.9395 57.5703c7.7002 48.7803 -17.6084 65.9004 -53.1201 65.9004h-37.8203c-71.6387 0 -118.028 -37.8203 -171.64 -37.8203v-186.17h10.9199c28.3604 0 67.9805 -70.8896 94.54 -97.46
c28.3604 -28.3604 18.9102 -75.6299 37.8203 -94.54c47.2695 0 47.2695 32.9805 47.2695 56.7305c0 39.1699 -28.3594 56.7197 -28.3594 94.5391h103.989z" />
<glyph glyph-name="sun" unicode="&#xf185;"
d="M494.2 226.1c11.2002 -7.59961 17.7998 -20.0996 17.8994 -33.6992c0 -13.4004 -6.69922 -26 -17.7998 -33.5l-59.7998 -40.5l13.7002 -71c2.5 -13.2002 -1.60059 -26.8008 -11.1006 -36.3008s-22.8994 -13.7998 -36.2998 -11.0996l-70.8994 13.7002l-40.4004 -59.9004
c-7.5 -11.0996 -20.0996 -17.7998 -33.5 -17.7998s-26 6.7002 -33.5 17.9004l-40.4004 59.8994l-70.7998 -13.7002c-13.3994 -2.59961 -26.7998 1.60059 -36.2998 11.1006s-13.7002 23.0996 -11.0996 36.2998l13.6992 71l-59.7998 40.5
c-11.0996 7.5 -17.7998 20 -17.7998 33.5s6.59961 26 17.7998 33.5996l59.7998 40.5l-13.6992 71c-2.60059 13.2002 1.59961 26.7002 11.0996 36.3008c9.5 9.59961 23 13.6992 36.2998 11.1992l70.7998 -13.6992l40.4004 59.8994c15.0996 22.2998 51.9004 22.2998 67 0
l40.4004 -59.8994l70.8994 13.6992c13 2.60059 26.6006 -1.59961 36.2002 -11.0996c9.5 -9.59961 13.7002 -23.2002 11.0996 -36.4004l-13.6992 -71zM381.3 140.5l76.7998 52.0996l-76.7998 52l17.6006 91.1006l-91 -17.6006l-51.9004 76.9004l-51.7998 -76.7998
l-91 17.5996l17.5996 -91.2002l-76.7998 -52l76.7998 -52l-17.5996 -91.1992l90.8994 17.5996l51.9004 -77l51.9004 76.9004l91 -17.6006zM256 296c57.2998 0 104 -46.7002 104 -104s-46.7002 -104 -104 -104s-104 46.7002 -104 104s46.7002 104 104 104zM256 136
c30.9004 0 56 25.0996 56 56s-25.0996 56 -56 56s-56 -25.0996 -56 -56s25.0996 -56 56 -56z" />
<glyph glyph-name="moon" unicode="&#xf186;"
d="M279.135 -64c-141.424 0 -256 114.64 -256 256c0 141.425 114.641 256 256 256c13.0068 -0.00195312 33.9443 -1.91797 46.7354 -4.27734c44.0205 -8.13086 53.7666 -66.8691 15.0215 -88.9189c-41.374 -23.5439 -67.4336 -67.4121 -67.4336 -115.836
c0 -83.5234 75.9238 -146.475 158.272 -130.792c43.6904 8.32129 74.5186 -42.5693 46.248 -77.4004c-47.8613 -58.9717 -120.088 -94.7754 -198.844 -94.7754zM279.135 400c-114.875 0 -208 -93.125 -208 -208s93.125 -208 208 -208
c65.2314 0 123.439 30.0361 161.575 77.0244c-111.611 -21.2568 -215.252 64.0957 -215.252 177.943c0 67.5127 36.9326 126.392 91.6934 157.555c-12.3271 2.27637 -25.0312 3.47754 -38.0166 3.47754z" />
<glyph glyph-name="caret-square-left" unicode="&#xf191;" horiz-adv-x="448"
d="M272 290.9v-197.801c0 -10.6992 -13 -16.0996 -20.5 -8.5l-98.2998 98.9004c-4.7002 4.7002 -4.7002 12.2002 0 16.9004l98.2998 98.8994c7.5 7.7002 20.5 2.2998 20.5 -8.39941zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="dot-circle" unicode="&#xf192;"
d="M256 392c-110.549 0 -200 -89.4678 -200 -200c0 -110.549 89.4678 -200 200 -200c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200zM256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248z
M256 272c44.1826 0 80 -35.8174 80 -80s-35.8174 -80 -80 -80s-80 35.8174 -80 80s35.8174 80 80 80z" />
<glyph glyph-name="building" unicode="&#xf1ad;" horiz-adv-x="448"
d="M128 300v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12zM268 288c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40
c0 -6.59961 -5.40039 -12 -12 -12h-40zM140 192c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM268 192c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM192 108c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM268 96c-6.59961 0 -12 5.40039 -12 12v40
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM448 -28v-36h-448v36c0 6.59961 5.40039 12 12 12h19.5v440c0 13.2998 10.7002 24 24 24h337c13.2998 0 24 -10.7002 24 -24v-440h19.5
c6.59961 0 12 -5.40039 12 -12zM79.5 -15h112.5v67c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-67h112.5v414l-288.5 1z" />
<glyph glyph-name="file-pdf" unicode="&#xf1c1;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM298.2 127.7c10.5 -10.5 8 -38.7002 -17.5 -38.7002c-14.7998 0 -36.9004 6.7998 -55.7998 17c-21.6006 -3.59961 -46 -12.7002 -68.4004 -20.0996c-50.0996 -86.4004 -79.4004 -47 -76.0996 -31.2002
c4 20 31 35.8994 51 46.2002c10.5 18.3994 25.3994 50.5 35.3994 74.3994c-7.39941 28.6006 -11.3994 51 -7 67.1006c4.7998 17.6992 38.4004 20.2998 42.6006 -5.90039c4.69922 -15.4004 -1.5 -39.9004 -5.40039 -56c8.09961 -21.2998 19.5996 -35.7998 36.7998 -46.2998
c17.4004 2.2002 52.2002 5.5 64.4004 -6.5zM100.1 49.9004c0 -0.700195 11.4004 4.69922 30.4004 35c-5.90039 -5.5 -25.2998 -21.3008 -30.4004 -35zM181.7 240.5c-2.5 0 -2.60059 -26.9004 1.7998 -40.7998c4.90039 8.7002 5.59961 40.7998 -1.7998 40.7998zM157.3 103.9
c15.9004 6.09961 34 14.8994 54.7998 19.1992c-11.1992 8.30078 -21.7998 20.4004 -30.0996 35.5c-6.7002 -17.6992 -15 -37.7998 -24.7002 -54.6992zM288.9 108.9c3.59961 2.39941 -2.2002 10.3994 -37.3008 7.7998c32.3008 -13.7998 37.3008 -7.7998 37.3008 -7.7998z" />
<glyph glyph-name="file-word" unicode="&#xf1c2;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM268.1 192v0.200195h15.8008c7.7998 0 13.5 -7.2998 11.5996 -14.9004c-4.2998 -17 -13.7002 -54.0996 -34.5 -136c-1.2998 -5.39941 -6.09961 -9.09961 -11.5996 -9.09961h-24.7002
c-5.5 0 -10.2998 3.7998 -11.6006 9.09961c-5.2998 20.9004 -17.7998 71 -17.8994 71.4004l-2.90039 17.2998c-0.5 -5.2998 -1.5 -11.0996 -3 -17.2998l-17.8994 -71.4004c-1.30078 -5.39941 -6.10059 -9.09961 -11.6006 -9.09961h-25.2002
c-5.59961 0 -10.3994 3.7002 -11.6992 9.09961c-6.5 26.5 -25.2002 103.4 -33.2002 136c-1.7998 7.5 3.89941 14.7998 11.7002 14.7998h16.7998c5.7998 0 10.7002 -4.09961 11.7998 -9.69922c5 -25.7002 18.4004 -93.8008 19.0996 -99
c0.300781 -1.7002 0.400391 -3.10059 0.5 -4.2002c0.800781 7.5 0.400391 4.7002 24.8008 103.7c1.39941 5.2998 6.19922 9.09961 11.6992 9.09961h13.3008c5.59961 0 10.3994 -3.7998 11.6992 -9.2002c23.9004 -99.7002 22.8008 -94.3994 23.6006 -99.5
c0.299805 -1.7002 0.5 -3.09961 0.700195 -4.2998c0.599609 8.09961 0.399414 5.7998 21 103.5c1.09961 5.5 6 9.5 11.6992 9.5z" />
<glyph glyph-name="file-excel" unicode="&#xf1c3;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM260 224c9.2002 0 15 -10 10.2998 -18c-16 -27.5 -45.5996 -76.9004 -46.2998 -78l46.4004 -78c4.59961 -8 -1.10059 -18 -10.4004 -18h-28.7998c-4.40039 0 -8.5 2.40039 -10.6006 6.2998
c-22.6992 41.7998 -13.6992 27.5 -28.5996 57.7002c-5.59961 -12.7002 -6.90039 -17.7002 -28.5996 -57.7002c-2.10059 -3.89941 -6.10059 -6.2998 -10.5 -6.2998h-28.9004c-9.2998 0 -15.0996 10 -10.4004 18l46.3008 78l-46.3008 78c-4.59961 8 1.10059 18 10.4004 18
h28.9004c4.39941 0 8.5 -2.40039 10.5996 -6.2998c21.7002 -40.4004 14.7002 -28.6006 28.5996 -57.7002c6.40039 15.2998 10.6006 24.5996 28.6006 57.7002c2.09961 3.89941 6.09961 6.2998 10.5 6.2998h28.7998z" />
<glyph glyph-name="file-powerpoint" unicode="&#xf1c4;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM120 44v168c0 6.59961 5.40039 12 12 12h69.2002c36.7002 0 62.7998 -27 62.7998 -66.2998c0 -74.2998 -68.7002 -66.5 -95.5 -66.5v-47.2002c0 -6.59961 -5.40039 -12 -12 -12h-24.5c-6.59961 0 -12 5.40039 -12 12z
M168.5 131.4h23c7.90039 0 13.9004 2.39941 18.0996 7.19922c8.5 9.80078 8.40039 28.5 0.100586 37.8008c-4.10059 4.59961 -9.90039 7 -17.4004 7h-23.8994v-52h0.0996094z" />
<glyph glyph-name="file-image" unicode="&#xf1c5;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM80 32v64l39.5 39.5c4.7002 4.7002 12.2998 4.7002 17 0l39.5 -39.5l87.5 87.5c4.7002 4.7002 12.2998 4.7002 17 0l23.5 -23.5v-128h-224zM128 272c26.5 0 48 -21.5 48 -48s-21.5 -48 -48 -48s-48 21.5 -48 48
s21.5 48 48 48z" />
<glyph glyph-name="file-archive" unicode="&#xf1c6;" horiz-adv-x="384"
d="M128.3 288h32v-32h-32v32zM192.3 384v-32h-32v32h32zM128.3 352h32v-32h-32v32zM192.3 320v-32h-32v32h32zM369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1
c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-48.2998v-16h-32v16h-79.7002v-416h288zM194.2 182.3l17.2998 -87.7002c6.40039 -32.3994 -18.4004 -62.5996 -51.5 -62.5996
c-33.2002 0 -58 30.4004 -51.4004 62.9004l19.7002 97.0996v32h32v-32h22.1006c5.7998 0 10.6992 -4.09961 11.7998 -9.7002zM160.3 57.9004c17.9004 0 32.4004 12.0996 32.4004 27c0 14.8994 -14.5 27 -32.4004 27c-17.8994 0 -32.3994 -12.1006 -32.3994 -27
c0 -14.9004 14.5 -27 32.3994 -27zM192.3 256v-32h-32v32h32z" />
<glyph glyph-name="file-audio" unicode="&#xf1c7;" horiz-adv-x="384"
d="M369.941 350.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM332.118 320
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM192 60.0244c0 -10.6914 -12.9258 -16.0459 -20.4854 -8.48535l-35.5146 35.9746h-28c-6.62695 0 -12 5.37305 -12 12v56c0 6.62695 5.37305 12 12 12h28
l35.5146 36.9473c7.56055 7.56055 20.4854 2.20605 20.4854 -8.48535v-135.951zM233.201 107.154c9.05078 9.29688 9.05957 24.1328 0.000976562 33.4385c-22.1494 22.752 12.2344 56.2461 34.3945 33.4814c27.1982 -27.9404 27.2119 -72.4443 0.000976562 -100.401
c-21.793 -22.3857 -56.9463 10.3154 -34.3965 33.4814z" />
<glyph glyph-name="file-video" unicode="&#xf1c8;" horiz-adv-x="384"
d="M369.941 350.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM332.118 320
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM276.687 195.303c10.0049 10.0049 27.3135 2.99707 27.3135 -11.3135v-111.976c0 -14.2939 -17.2959 -21.332 -27.3135 -11.3135l-52.6865 52.6738v-37.374
c0 -11.0459 -8.9541 -20 -20 -20h-104c-11.0459 0 -20 8.9541 -20 20v104c0 11.0459 8.9541 20 20 20h104c11.0459 0 20 -8.9541 20 -20v-37.374z" />
<glyph glyph-name="file-code" unicode="&#xf1c9;" horiz-adv-x="384"
d="M149.9 98.9004c3.5 -3.30078 3.69922 -8.90039 0.399414 -12.4004l-17.3994 -18.5996c-1.60059 -1.80078 -4 -2.80078 -6.40039 -2.80078c-2.2002 0 -4.40039 0.900391 -6 2.40039l-57.7002 54.0996c-3.7002 3.40039 -3.7002 9.30078 0 12.8008l57.7002 54.0996
c3.40039 3.2998 9 3.2002 12.4004 -0.400391l17.3994 -18.5996l0.200195 -0.200195c3.2002 -3.59961 2.7998 -9.2002 -0.799805 -12.3994l-32.7998 -28.9004l32.7998 -28.9004zM369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288
c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416h288zM209.6 234l24.4004 -7
c4.7002 -1.2998 7.40039 -6.2002 6 -10.9004l-54.7002 -188.199c-1.2998 -4.60059 -6.2002 -7.40039 -10.8994 -6l-24.4004 7.09961c-4.7002 1.2998 -7.40039 6.2002 -6 10.9004l54.7002 188.1c1.39941 4.7002 6.2002 7.40039 10.8994 6zM234.1 157.1
c-3.5 3.30078 -3.69922 8.90039 -0.399414 12.4004l17.3994 18.5996c3.30078 3.60059 8.90039 3.7002 12.4004 0.400391l57.7002 -54.0996c3.7002 -3.40039 3.7002 -9.30078 0 -12.8008l-57.7002 -54.0996c-3.5 -3.2998 -9.09961 -3.09961 -12.4004 0.400391
l-17.3994 18.5996l-0.200195 0.200195c-3.2002 3.59961 -2.7998 9.2002 0.799805 12.3994l32.7998 28.9004l-32.7998 28.9004z" />
<glyph glyph-name="life-ring" unicode="&#xf1cd;"
d="M256 -56c-136.967 0 -248 111.033 -248 248s111.033 248 248 248s248 -111.033 248 -248s-111.033 -248 -248 -248zM152.602 20.7197c63.2178 -38.3184 143.579 -38.3184 206.797 0l-53.4111 53.4111c-31.8467 -13.5215 -68.168 -13.5059 -99.9746 0zM336 192
c0 44.1123 -35.8877 80 -80 80s-80 -35.8877 -80 -80s35.8877 -80 80 -80s80 35.8877 80 80zM427.28 88.6016c38.3184 63.2178 38.3184 143.579 0 206.797l-53.4111 -53.4111c13.5215 -31.8467 13.5049 -68.168 0 -99.9746zM359.397 363.28
c-63.2168 38.3184 -143.578 38.3184 -206.796 0l53.4111 -53.4111c31.8457 13.5215 68.167 13.5049 99.9736 0zM84.7197 295.398c-38.3184 -63.2178 -38.3184 -143.579 0 -206.797l53.4111 53.4111c-13.5215 31.8467 -13.5059 68.168 0 99.9746z" />
<glyph glyph-name="paper-plane" unicode="&#xf1d8;"
d="M440 441.5c34.5996 19.9004 77.5996 -8.7998 71.5 -48.9004l-59.4004 -387.199c-2.2998 -14.5 -11.0996 -27.3008 -23.8994 -34.5c-7.2998 -4.10059 -15.4004 -6.2002 -23.6006 -6.2002c-6.19922 0 -12.3994 1.2002 -18.2998 3.59961l-111.899 46.2002l-43.8008 -59.0996
c-27.3994 -36.9004 -86.5996 -17.8008 -86.5996 28.5996v84.4004l-114.3 47.2998c-36.7998 15.0996 -40.1006 66 -5.7002 85.8994zM192 -16l36.5996 49.5l-36.5996 15.0996v-64.5996zM404.6 12.7002l59.4004 387.3l-416 -240l107.8 -44.5996l211.5 184.3
c14.2002 12.2998 34.4004 -5.7002 23.7002 -21.2002l-140.2 -202.3z" />
<glyph glyph-name="futbol" unicode="&#xf1e3;" horiz-adv-x="496"
d="M483.8 268.6c42.2998 -130.199 -29 -270.1 -159.2 -312.399c-25.5 -8.2998 -51.2998 -12.2002 -76.6992 -12.2002c-104.5 0 -201.7 66.5996 -235.7 171.4c-42.2998 130.199 29 270.1 159.2 312.399c25.5 8.2998 51.2998 12.2002 76.6992 12.2002
c104.5 0 201.7 -66.5996 235.7 -171.4zM409.3 74.9004c6.10059 8.39941 12.1006 16.8994 16.7998 26.1992c14.3008 28.1006 21.5 58.5 21.7002 89.2002l-38.8994 36.4004l-71.1006 -22.1006l-24.3994 -75.1992l43.6992 -60.9004zM409.3 310.3
c-24.5 33.4004 -58.7002 58.4004 -97.8994 71.4004l-47.4004 -26.2002v-73.7998l64.2002 -46.5l70.7002 22zM184.9 381.6c-39.9004 -13.2998 -73.5 -38.5 -97.8008 -71.8994l10.1006 -52.5l70.5996 -22l64.2002 46.5v73.7998zM139 68.5l43.5 61.7002l-24.2998 74.2998
l-71.1006 22.2002l-39 -36.4004c0.5 -55.7002 23.4004 -95.2002 37.8008 -115.3zM187.2 1.5c64.0996 -20.4004 115.5 -1.7998 121.7 0l22.3994 48.0996l-44.2998 61.7002h-78.5996l-43.6006 -61.7002z" />
<glyph glyph-name="newspaper" unicode="&#xf1ea;" horiz-adv-x="576"
d="M552 384c13.2549 0 24 -10.7451 24 -24v-336c0 -13.2549 -10.7451 -24 -24 -24h-496c-30.9277 0 -56 25.0723 -56 56v272c0 13.2549 10.7451 24 24 24h42.752c6.60547 18.623 24.3896 32 45.248 32h440zM48 56c0 -4.41113 3.58887 -8 8 -8s8 3.58887 8 8v248h-16v-248z
M528 48v288h-416v-280c0 -2.7168 -0.204102 -5.38574 -0.578125 -8h416.578zM172 168c-6.62695 0 -12 5.37305 -12 12v96c0 6.62695 5.37305 12 12 12h136c6.62695 0 12 -5.37305 12 -12v-96c0 -6.62695 -5.37305 -12 -12 -12h-136zM200 248v-40h80v40h-80zM160 108v24
c0 6.62695 5.37305 12 12 12h136c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-136c-6.62695 0 -12 5.37305 -12 12zM352 108v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-104
c-6.62695 0 -12 5.37305 -12 12zM352 252v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-104c-6.62695 0 -12 5.37305 -12 12zM352 180v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24
c0 -6.62695 -5.37305 -12 -12 -12h-104c-6.62695 0 -12 5.37305 -12 12z" />
<glyph glyph-name="bell-slash" unicode="&#xf1f6;" horiz-adv-x="640"
d="M633.99 -23.0195c6.91016 -5.52051 8.01953 -15.5908 2.5 -22.4902l-10 -12.4902c-5.53027 -6.88965 -15.5898 -8.00977 -22.4902 -2.49023l-598 467.51c-6.90039 5.52051 -8.01953 15.5908 -2.49023 22.4902l10 12.4902
c5.52051 6.90039 15.5898 8.00977 22.4902 2.49023zM163.53 80h182.84l61.3994 -48h-279.659c-19.1201 0 -31.9902 15.5996 -32.1006 32c-0.0498047 7.5498 2.61035 15.2598 8.61035 21.71c18.3701 19.7402 51.5703 49.6904 54.8398 140.42l45.4697 -35.5498
c-6.91992 -54.7803 -24.6895 -88.5498 -41.3994 -110.58zM320 352c-23.3496 0 -45 -7.17969 -62.9404 -19.4004l-38.1699 29.8408c19.6807 15.7793 43.1104 27.3096 69.1299 32.7197v20.8398c0 17.6699 14.3203 32 31.9805 32s31.9805 -14.3301 31.9805 -32v-20.8398
c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -41.3604 6.03027 -70.7197 14.3398 -92.8496l-59.5293 46.54c-1.63086 13.96 -2.77051 28.8896 -2.79004 45.7295c0 0.200195 0.0595703 0.379883 0.0595703 0.580078c0 61.8604 -50.1396 112 -112 112zM320 -64
c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
<glyph glyph-name="copyright" unicode="&#xf1f9;"
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
M363.351 93.0645c-9.61328 -9.71289 -45.5293 -41.3965 -104.064 -41.3965c-82.4297 0 -140.484 61.4248 -140.484 141.567c0 79.1514 60.2754 139.4 139.763 139.4c55.5303 0 88.7373 -26.6201 97.5928 -34.7783c2.13379 -1.96289 3.86523 -5.9082 3.86523 -8.80762
c0 -1.95508 -0.864258 -4.87402 -1.92969 -6.51465l-18.1543 -28.1133c-3.8418 -5.9502 -11.9668 -7.28223 -17.499 -2.9209c-8.5957 6.77637 -31.8145 22.5381 -61.708 22.5381c-48.3037 0 -77.916 -35.3301 -77.916 -80.082c0 -41.5889 26.8877 -83.6924 78.2764 -83.6924
c32.6572 0 56.8428 19.0391 65.7266 27.2256c5.26953 4.85645 13.5957 4.03906 17.8193 -1.73828l19.8652 -27.1699c1.28613 -1.74512 2.33008 -4.91992 2.33008 -7.08789c0 -2.72363 -1.56055 -6.5 -3.48242 -8.42969z" />
<glyph glyph-name="closed-captioning" unicode="&#xf20a;"
d="M464 384c26.5 0 48 -21.5 48 -48v-288c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h416zM458 48c3.2998 0 6 2.7002 6 6v276c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-276c0 -3.2998 2.7002 -6 6 -6h404z
M246.9 133.7c1.69922 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.6006 -56.7998 -172.801 -32.0996 -172.801 67.9004c0 97.2998 121.7 119.5 172.5 70.0996c2.10059 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.89941 -3.09961 -6.19922 -4 -9.09961 -1.7002
c-40.7998 32 -94.5996 14.9004 -94.5996 -31.1992c0 -48 51 -70.5 92.1992 -32.6006c2.80078 2.5 7.10059 2.10059 9.2002 -0.899414zM437.3 133.7c1.7002 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.5996 -56.9004 -172.8 -32.0996 -172.8 67.9004
c0 97.2998 121.7 119.5 172.5 70.0996c2.09961 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.90039 -3.09961 -6.2002 -4 -9.09961 -1.7002c-40.8008 32 -94.6006 14.9004 -94.6006 -31.1992c0 -48 51 -70.5 92.2002 -32.6006c2.7998 2.5 7.09961 2.10059 9.2002 -0.899414z
" />
<glyph glyph-name="object-group" unicode="&#xf247;"
d="M500 320h-12v-256h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-320v-12c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v256h-12
c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-12h320v12c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12zM448 384v-32h32v32h-32zM32 384v-32h32v32h-32zM64 0v32
h-32v-32h32zM480 0v32h-32v-32h32zM440 64v256h-12c-6.62695 0 -12 5.37305 -12 12v12h-320v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-256h12c6.62695 0 12 -5.37305 12 -12v-12h320v12c0 6.62695 5.37305 12 12 12h12zM404 256c6.62695 0 12 -5.37207 12 -12v-168
c0 -6.62793 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37207 -12 12v52h-84c-6.62695 0 -12 5.37207 -12 12v168c0 6.62793 5.37305 12 12 12h200c6.62695 0 12 -5.37207 12 -12v-52h84zM136 280v-112h144v112h-144zM376 104v112h-56v-76
c0 -6.62793 -5.37305 -12 -12 -12h-76v-24h144z" />
<glyph glyph-name="object-ungroup" unicode="&#xf248;" horiz-adv-x="576"
d="M564 224h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v24h-88v-12
c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h72
c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-12v-24h88v12c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12zM352 384v-32h32v32h-32zM352 128v-32h32v32h-32zM64 96v32h-32v-32h32zM64 352v32
h-32v-32h32zM96 136h224v12c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-12zM224 0v32h-32v-32h32zM504 64v160h-12c-6.62695 0 -12 5.37305 -12 12v12
h-88v-88h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-88v-24h12c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h12zM544 0v32h-32v-32h32zM544 256v32h-32v-32h32z" />
<glyph glyph-name="sticky-note" unicode="&#xf249;" horiz-adv-x="448"
d="M448 99.8936c0 -10.9746 -6.29883 -26.1797 -14.0586 -33.9404l-83.8828 -83.8818c-7.75977 -7.76074 -22.9658 -14.0596 -33.9404 -14.0596h-268.118c-26.5098 0 -48 21.4902 -48 48v351.988c0 26.5098 21.4902 48 48 48h352c26.5098 0 48 -21.4902 48 -48v-268.106z
M320 19.8936l76.1182 76.1182h-76.1182v-76.1182zM400 368h-352v-351.988h224v104c0 13.2549 10.7451 24 24 24h104v223.988z" />
<glyph glyph-name="clone" unicode="&#xf24d;"
d="M464 448c26.5098 0 48 -21.4902 48 -48v-320c0 -26.5098 -21.4902 -48 -48 -48h-48v-48c0 -26.5098 -21.4902 -48 -48 -48h-320c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h48v48c0 26.5098 21.4902 48 48 48h320zM362 -16c3.31152 0 6 2.68848 6 6
v42h-224c-26.5098 0 -48 21.4902 -48 48v224h-42c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h308zM458 80c3.31152 0 6 2.68848 6 6v308c0 3.31152 -2.68848 6 -6 6h-308c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h308z" />
<glyph glyph-name="hourglass" unicode="&#xf254;" horiz-adv-x="384"
d="M368 400c0 -80.0996 -31.8984 -165.619 -97.1797 -208c64.9912 -42.1934 97.1797 -127.436 97.1797 -208h4c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-360c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h4
c0 80.0996 31.8994 165.619 97.1797 208c-64.9912 42.1934 -97.1797 127.436 -97.1797 208h-4c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h360c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-4zM64 400
c0 -101.621 57.3066 -184 128 -184s128 82.3799 128 184h-256zM320 -16c0 101.62 -57.3076 184 -128 184s-128 -82.3799 -128 -184h256z" />
<glyph glyph-name="hand-rock" unicode="&#xf255;"
d="M408.864 368.948c48.8213 20.751 103.136 -15.0723 103.136 -67.9111v-114.443c0 -15.3955 -3.08887 -30.3906 -9.18262 -44.5674l-42.835 -99.6562c-4.99707 -11.625 -3.98242 -18.8574 -3.98242 -42.3701c0 -17.6729 -14.3271 -32 -32 -32h-252
c-17.6729 0 -32 14.3271 -32 32c0 27.3301 1.1416 29.2012 -3.11035 32.9033l-97.71 85.0811c-24.8994 21.6797 -39.1797 52.8926 -39.1797 85.6338v56.9531c0 47.4277 44.8457 82.0215 91.0459 71.1807c1.96094 55.751 63.5107 87.8262 110.671 60.8057
c29.1895 31.0713 78.8604 31.4473 108.334 -0.0214844c32.7051 18.6846 76.4121 10.3096 98.8135 -23.5879zM464 186.594v114.445c0 34.29 -52 33.8232 -52 0.676758c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v26.751
c0 34.457 -52 33.707 -52 0.676758v-27.4287c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v40.4658c0 34.3525 -52 33.8115 -52 0.677734v-41.1436c0 -8.83594 -7.16406 -16 -16 -16h-7c-8.83594 0 -16 7.16406 -16 16v26.751
c0 34.4023 -52 33.7744 -52 0.676758v-116.571c0 -8.83203 -7.16797 -16 -16 -16c-3.30664 0 -8.01367 1.7627 -10.5068 3.93359l-7 6.09473c-3.03223 2.64062 -5.49316 8.04688 -5.49316 12.0674v0v41.2275c0 34.2148 -52 33.8857 -52 0.677734v-56.9531
c0 -18.8555 8.27441 -36.874 22.7002 -49.4365l97.71 -85.0801c12.4502 -10.8398 19.5898 -26.4463 19.5898 -42.8164v-10.2861h220v7.07617c0 13.21 2.65332 26.0791 7.88281 38.25l42.835 99.6553c2.91602 6.75391 5.28223 18.207 5.28223 25.5635v0.0488281z" />
<glyph glyph-name="hand-paper" unicode="&#xf256;" horiz-adv-x="448"
d="M372.57 335.359c39.9062 5.63281 75.4297 -25.7393 75.4297 -66.3594v-131.564c-0.00195312 -12.7666 -2.33008 -33.2246 -5.19531 -45.666l-30.1836 -130.958c-3.34668 -14.5234 -16.2783 -24.8125 -31.1816 -24.8125h-222.897
c-9.10352 0 -20.7793 6.01758 -26.0615 13.4316l-119.97 168.415c-21.2441 29.8203 -14.8047 71.3574 14.5498 93.1533c18.7754 13.9395 42.1309 16.2979 62.083 8.87109v126.13c0 44.0547 41.125 75.5439 82.4053 64.9834c23.8926 48.1963 92.3535 50.2471 117.982 0.74707
c42.5186 11.1445 83.0391 -21.9346 83.0391 -65.5469v-10.8242zM399.997 137.437l-0.00195312 131.563c0 24.9492 -36.5703 25.5508 -36.5703 -0.691406v-76.3086c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v154.184
c0 25.501 -36.5703 26.3633 -36.5703 0.691406v-154.875c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v188.309c0 25.501 -36.5703 26.3545 -36.5703 0.691406v-189c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16
v153.309c0 25.501 -36.5713 26.3359 -36.5713 0.691406v-206.494c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832l-27.1279 38.0791c-14.3711 20.1709 -43.833 -2.33496 -29.3945 -22.6045l115.196 -161.697h201.92l27.3252 118.551
c2.63086 11.417 3.96484 23.1553 3.96484 34.8857z" />
<glyph glyph-name="hand-scissors" unicode="&#xf257;"
d="M256 -32c-44.9561 0 -77.3428 43.2627 -64.0244 85.8535c-21.6484 13.71 -34.0156 38.7617 -30.3408 65.0068h-87.6348c-40.8037 0 -74 32.8105 -74 73.1406c0 40.3291 33.1963 73.1396 74 73.1396l94 -9.14062l-78.8496 18.6787
c-38.3076 14.7422 -57.04 57.4707 -41.9424 95.1123c15.0303 37.4736 57.7549 55.7803 95.6416 41.2012l144.929 -55.7568c24.9551 30.5566 57.8086 43.9932 92.2178 24.7324l97.999 -54.8525c20.9746 -11.7393 34.0049 -33.8457 34.0049 -57.6904v-205.702
c0 -30.7422 -21.4404 -57.5576 -51.7979 -64.5537l-118.999 -27.4268c-4.97168 -1.14648 -10.0889 -1.72949 -15.2031 -1.72949zM256 16.0127l70 -0.000976562c1.23633 0 3.21777 0.225586 4.42285 0.501953l119.001 27.4277
c8.58203 1.97754 14.5762 9.29102 14.5762 17.7812v205.701c0 6.4873 -3.62109 12.542 -9.44922 15.8047l-98 54.8545c-8.13965 4.55566 -18.668 2.61914 -24.4873 -4.50781l-21.7646 -26.6475c-2.65039 -3.24512 -8.20215 -5.87891 -12.3926 -5.87891
c-1.64062 0 -4.21484 0.477539 -5.74609 1.06738l-166.549 64.0908c-32.6543 12.5664 -50.7744 -34.5771 -19.2227 -46.7168l155.357 -59.7852c5.66016 -2.17773 10.2539 -8.86816 10.2539 -14.9326v0v-11.6328c0 -8.83691 -7.16309 -16 -16 -16h-182
c-34.375 0 -34.4297 -50.2803 0 -50.2803h182c8.83691 0 16 -7.16309 16 -16v-6.85645c0 -8.83691 -7.16309 -16 -16 -16h-28c-25.1221 0 -25.1592 -36.5674 0 -36.5674h28c8.83691 0 16 -7.16211 16 -16v-6.85547c0 -8.83691 -7.16309 -16 -16 -16
c-25.1201 0 -25.1602 -36.5674 0 -36.5674z" />
<glyph glyph-name="hand-lizard" unicode="&#xf258;" horiz-adv-x="576"
d="M556.686 157.458c12.6357 -19.4863 19.3145 -42.0615 19.3145 -65.2871v-124.171h-224v71.582l-99.751 38.7871c-2.7832 1.08203 -5.70996 1.63086 -8.69727 1.63086h-131.552c-30.8789 0 -56 25.1211 -56 56c0 48.5234 39.4766 88 88 88h113.709l18.333 48h-196.042
c-44.1123 0 -80 35.8877 -80 80v8c0 30.8779 25.1211 56 56 56h293.917c24.5 0 47.084 -12.2725 60.4111 -32.8291zM528 16v76.1709v0.0478516c0 11.7461 -5.19141 29.2734 -11.5879 39.124l-146.358 225.715c-4.44336 6.85254 -11.9707 10.9424 -20.1367 10.9424h-293.917
c-4.41113 0 -8 -3.58887 -8 -8v-8c0 -17.6445 14.3555 -32 32 -32h213.471c25.2021 0 42.626 -25.293 33.6299 -48.8457l-24.5518 -64.2812c-7.05371 -18.4658 -25.0732 -30.873 -44.8398 -30.873h-113.709c-22.0557 0 -40 -17.9443 -40 -40c0 -4.41113 3.58887 -8 8 -8
h131.552h0.0517578c7.44141 0 19.1074 -2.19238 26.041 -4.89355l99.752 -38.7881c18.5898 -7.22852 30.6035 -24.7881 30.6035 -44.7363v-23.582h128z" />
<glyph glyph-name="hand-spock" unicode="&#xf259;"
d="M21.0957 66.21c-26.9688 25.3818 -28.2471 67.7461 -2.87109 94.707c24.1982 25.7139 64.2881 28.2373 91.4824 5.72168l-31.04 136.509c-9.38379 41.2803 21.4336 81.0127 64.0713 81.8438c1.74414 28.9062 22.2656 54.4912 51.8818 61.2949
c36.001 8.27539 72.0176 -14.2266 80.3037 -50.2959l21.6748 -131.99l16.9014 105.25c9.02344 36.0947 45.4473 57.7021 81.25 48.75c27.3066 -6.82715 45.7061 -29.1357 49.8496 -53.9922c43.2285 0.212891 75.6436 -40.1133 65.5439 -82.5244l-31.7295 -133.41
c-0.938477 -3.94141 -1.41406 -7.99414 -1.41406 -12.0449v-36.8389v-0.00683594c0 -9.29102 -2.14355 -24.0596 -4.78516 -32.9668l-31.8145 -107.312c-4.02734 -13.585 -16.5107 -22.9043 -30.6807 -22.9043h-237.6c-7.00586 0 -16.8311 3.89648 -21.9316 8.69824z
M53.1641 128.021c-7.17969 -7.62891 -6.81543 -19.6777 0.813477 -26.8574l124.487 -117.164h219.311l28.4199 95.8613c1.86133 6.27637 2.80469 12.7793 2.80469 19.3281v36.8389c0.000976562 6.48047 1.21973 16.8574 2.71973 23.1621l31.7549 133.407
c5.83105 24.4893 -31.1445 33.25 -36.9658 8.80273l-26.9229 -113.105c-1.61523 -6.78711 -8.58887 -12.2949 -15.5645 -12.2949h-9.69434c-10.4072 0 -18.043 9.79199 -15.5225 19.8799l38.127 152.512c6.09766 24.376 -30.7607 33.6396 -36.8643 9.21777l-42.3721 -169.49
c-1.67285 -6.68945 -8.62695 -12.1191 -15.5225 -12.1191h-13.2168v0c-7.0332 0 -14.0195 5.5625 -15.5938 12.417l-45.2207 196.828c-5.64453 24.5684 -42.6572 15.9609 -37.0342 -8.50781l41.6191 -181.153c2.30078 -10.0156 -5.31738 -19.583 -15.5938 -19.583h-8.60352
h-0.000976562c-7.0498 0 -14.04 5.5791 -15.6025 12.4541l-30.3984 133.757c-5.55273 24.4395 -42.6504 16.1963 -37.0547 -8.4209l34.1299 -150.172c0.263672 -1.16309 0.397461 -2.35352 0.397461 -3.5459v-69.4795c0 -13.9941 -16.7754 -21.2432 -26.9658 -11.6523
l-53.0117 49.8936c-7.61523 7.16699 -19.6377 6.85938 -26.8564 -0.8125z" />
<glyph glyph-name="hand-pointer" unicode="&#xf25a;" horiz-adv-x="448"
d="M358.182 268.639c43.1934 16.6348 89.8184 -15.7949 89.8184 -62.6387v-84c-0.000976562 -4.25 -0.775391 -11.0615 -1.72754 -15.2041l-27.4297 -118.999c-6.98242 -30.2969 -33.7549 -51.7969 -64.5566 -51.7969h-178.286c-21.2588 0 -41.3682 10.4102 -53.791 27.8457
l-109.699 154.001c-21.2432 29.8193 -14.8047 71.3574 14.5498 93.1523c18.8115 13.9658 42.1748 16.2822 62.083 8.87207v161.129c0 36.9443 29.7363 67 66.2861 67s66.2861 -30.0557 66.2861 -67v-73.6338c20.4131 2.85742 41.4678 -3.94238 56.5947 -19.6289
c27.1934 12.8467 60.3799 5.66992 79.8721 -19.0986zM80.9854 168.303c-14.4004 20.2119 -43.8008 -2.38281 -29.3945 -22.6055l109.712 -154c3.43457 -4.81934 8.92871 -7.69727 14.6973 -7.69727h178.285c8.49219 0 15.8037 5.99414 17.7822 14.5762l27.4297 119.001
c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285v84c0 25.1602 -36.5713 25.1211 -36.5713 0c0 -8.83594 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16406 -16 16v21c0 25.1602 -36.5713 25.1201 -36.5713 0v-21c0 -8.83594 -7.16309 -16 -16 -16h-6.85938
c-8.83691 0 -16 7.16406 -16 16v35c0 25.1602 -36.5703 25.1201 -36.5703 0v-35c0 -8.83594 -7.16309 -16 -16 -16h-6.85742c-8.83691 0 -16 7.16406 -16 16v175c0 25.1602 -36.5713 25.1201 -36.5713 0v-241.493c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832z
M176.143 48v96c0 8.83691 6.26855 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM251.571 48v96c0 8.83691 6.26758 16 14 16h6c7.73145 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26855 -16 -14 -16h-6
c-7.73242 0 -14 7.16309 -14 16zM327 48v96c0 8.83691 6.26758 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16z" />
<glyph glyph-name="hand-peace" unicode="&#xf25b;" horiz-adv-x="448"
d="M362.146 256.024c42.5908 13.3184 85.8535 -19.0684 85.8535 -64.0244l-0.0117188 -70.001c-0.000976562 -4.25 -0.775391 -11.0615 -1.72949 -15.2031l-27.4268 -118.999c-6.99707 -30.3564 -33.8105 -51.7969 -64.5547 -51.7969h-205.702
c-23.8447 0 -45.9502 13.0303 -57.6904 34.0059l-54.8525 97.999c-19.2607 34.4092 -5.82422 67.2617 24.7324 92.2178l-55.7568 144.928c-14.5791 37.8867 3.72754 80.6113 41.2012 95.6416c37.6406 15.0977 80.3691 -3.63477 95.1123 -41.9424l18.6787 -78.8496
l-9.14062 94c0 40.8037 32.8096 74 73.1396 74s73.1406 -33.1963 73.1406 -74v-87.6348c26.2451 3.6748 51.2959 -8.69238 65.0068 -30.3408zM399.987 122l-0.000976562 70c0 25.1602 -36.5674 25.1201 -36.5674 0c0 -8.83691 -7.16309 -16 -16 -16h-6.85547
c-8.83789 0 -16 7.16309 -16 16v28c0 25.1592 -36.5674 25.1221 -36.5674 0v-28c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v182c0 34.4297 -50.2803 34.375 -50.2803 0v-182c0 -8.83691 -7.16309 -16 -16 -16h-11.6328v0
c-6.06445 0 -12.7549 4.59375 -14.9326 10.2539l-59.7842 155.357c-12.1396 31.5518 -59.2842 13.4326 -46.7168 -19.2227l64.0898 -166.549c0.589844 -1.53125 1.06738 -4.10547 1.06738 -5.74609c0 -4.19043 -2.63379 -9.74219 -5.87891 -12.3926l-26.6475 -21.7646
c-7.12695 -5.81934 -9.06445 -16.3467 -4.50781 -24.4873l54.8535 -98c3.26367 -5.82812 9.31934 -9.44922 15.8057 -9.44922h205.701c8.49121 0 15.8037 5.99414 17.7812 14.5762l27.4277 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285z" />
<glyph glyph-name="registered" unicode="&#xf25d;"
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
M366.442 73.791c4.40332 -7.99219 -1.37012 -17.791 -10.5107 -17.791h-42.8096h-0.0126953c-3.97559 0 -8.71582 2.84961 -10.5801 6.36035l-47.5156 89.3027h-31.958v-83.6631c0 -6.61719 -5.38281 -12 -12 -12h-38.5674c-6.61719 0 -12 5.38281 -12 12v248.304
c0 6.61719 5.38281 12 12 12h78.667c71.251 0 101.498 -32.749 101.498 -85.252c0 -31.6123 -15.2148 -59.2969 -39.4824 -73.1758c3.02148 -4.61719 0.225586 0.199219 53.2715 -96.085zM256.933 208.094c20.9131 0 32.4307 11.5186 32.4316 32.4316
c0 19.5752 -6.5127 31.709 -38.9297 31.709h-27.377v-64.1406h33.875z" />
<glyph glyph-name="calendar-plus" unicode="&#xf271;" horiz-adv-x="448"
d="M336 156v-24c0 -6.59961 -5.40039 -12 -12 -12h-76v-76c0 -6.59961 -5.40039 -12 -12 -12h-24c-6.59961 0 -12 5.40039 -12 12v76h-76c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h76v76c0 6.59961 5.40039 12 12 12h24c6.59961 0 12 -5.40039 12 -12
v-76h76c6.59961 0 12 -5.40039 12 -12zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40
c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="calendar-minus" unicode="&#xf272;" horiz-adv-x="448"
d="M124 120c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h200c6.59961 0 12 -5.40039 12 -12v-24c0 -6.59961 -5.40039 -12 -12 -12h-200zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="calendar-times" unicode="&#xf273;" horiz-adv-x="448"
d="M311.7 73.2998l-17 -17c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-53.7002 53.7998l-53.7002 -53.6992c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-17 17c-4.7002 4.69922 -4.7002 12.2998 0 17l53.7002 53.6992l-53.7002 53.7002c-4.7002 4.7002 -4.7002 12.2998 0 17
l17 17c4.7002 4.7002 12.2998 4.7002 17 0l53.7002 -53.7002l53.7002 53.7002c4.7002 4.7002 12.2998 4.7002 17 0l17 -17c4.7002 -4.7002 4.7002 -12.2998 0 -17l-53.7998 -53.7998l53.6992 -53.7002c4.80078 -4.7002 4.80078 -12.2998 0.100586 -17zM448 336v-352
c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10
v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="calendar-check" unicode="&#xf274;" horiz-adv-x="448"
d="M400 384c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h48v52c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-52h128v52c0 6.62695 5.37305 12 12 12h40
c6.62695 0 12 -5.37305 12 -12v-52h48zM394 -16c3.31152 0 6 2.68848 6 6v298h-352v-298c0 -3.31152 2.68848 -6 6 -6h340zM341.151 184.65l-142.31 -141.169c-4.70508 -4.66699 -12.3027 -4.6377 -16.9707 0.0673828l-75.0908 75.6992
c-4.66699 4.70508 -4.6377 12.3027 0.0673828 16.9707l22.7197 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l44.1035 -44.4609l111.072 110.182c4.70508 4.66699 12.3027 4.63672 16.9707 -0.0683594l22.5361 -22.7178
c4.66699 -4.70508 4.63672 -12.3027 -0.0683594 -16.9697z" />
<glyph glyph-name="map" unicode="&#xf279;" horiz-adv-x="576"
d="M560.02 416c8.4502 0 15.9805 -6.83008 15.9805 -16.0195v-346.32c0 -11.9609 -9.01367 -25.2705 -20.1201 -29.71l-151.83 -52.8105c-5.32617 -1.7334 -14.1953 -3.13965 -19.7969 -3.13965c-5.7373 0 -14.8105 1.47363 -20.2529 3.29004l-172 60.71l-170.05 -62.8398
c-1.99023 -0.790039 -4 -1.16016 -5.95996 -1.16016c-8.45996 0 -15.9902 6.83008 -15.9902 16.0195v346.32c0.00292969 11.959 9.0166 25.2686 20.1201 29.71l151.83 52.8105c6.43945 2.08984 13.1201 3.13965 19.8096 3.13965
c5.73242 -0.00195312 14.8008 -1.47168 20.2402 -3.28027l172 -60.7197h0.00976562l170.05 62.8398c1.98047 0.790039 4 1.16016 5.95996 1.16016zM224 357.58v-285.97l128 -45.1904v285.97zM48 29.9502l127.36 47.0801l0.639648 0.229492v286.2l-128 -44.5303v-288.979z
M528 65.0801v288.97l-127.36 -47.0693l-0.639648 -0.240234v-286.19z" />
<glyph glyph-name="comment-alt" unicode="&#xf27a;"
d="M448 448c35.2998 0 64 -28.7002 64 -64v-288c0 -35.2998 -28.7002 -64 -64 -64h-144l-124.9 -93.5996c-2.19922 -1.7002 -4.69922 -2.40039 -7.09961 -2.40039c-6.2002 0 -12 4.90039 -12 12v84h-96c-35.2998 0 -64 28.7002 -64 64v288c0 35.2998 28.7002 64 64 64h384z
M464 96v288c0 8.7998 -7.2002 16 -16 16h-384c-8.7998 0 -16 -7.2002 -16 -16v-288c0 -8.7998 7.2002 -16 16 -16h144v-60l67.2002 50.4004l12.7998 9.59961h160c8.7998 0 16 7.2002 16 16z" />
<glyph glyph-name="pause-circle" unicode="&#xf28b;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM352 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-48
c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h48c8.7998 0 16 -7.2002 16 -16zM240 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-48c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h48c8.7998 0 16 -7.2002 16 -16z" />
<glyph glyph-name="stop-circle" unicode="&#xf28d;"
d="M504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200zM352 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-160
c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h160c8.7998 0 16 -7.2002 16 -16z" />
<glyph glyph-name="handshake" unicode="&#xf2b5;" horiz-adv-x="640"
d="M519.2 320.1h120.8v-255.699h-64c-17.5 0 -31.7998 14.1992 -31.9004 31.6992h-57.8994c-1.7998 -8.19922 -5.2998 -16.0996 -10.9004 -23l-26.2002 -32.2998c-15.7998 -19.3994 -41.8994 -25.5 -64 -16.7998c-13.5 -16.5996 -30.5996 -24 -48.7998 -24
c-15.0996 0 -28.5996 5.09961 -41.0996 15.9004c-31.7998 -21.9004 -74.7002 -21.3008 -105.601 3.7998l-84.5996 76.3994h-9.09961c-0.100586 -17.5 -14.3008 -31.6992 -31.9004 -31.6992h-64v255.699h118l47.5996 47.6006c10.5 10.3994 24.8008 16.2998 39.6006 16.2998
h226.8v0c12.7812 0 30.5225 -7.30273 39.5996 -16.2998zM48 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16zM438 103.3c2.7002 3.40039 2.2002 8.5 -1.2002 11.2998l-108.2 87.8008l-8.19922 -7.5
c-40.3008 -36.8008 -86.7002 -11.8008 -101.5 4.39941c-26.7002 29 -25 74.4004 4.39941 101.3l38.7002 35.5h-56.7002c-2 -0.799805 -3.7002 -1.5 -5.7002 -2.2998l-61.6992 -61.5996h-41.9004v-128.101h27.7002l97.2998 -88
c16.0996 -13.0996 41.4004 -10.5 55.2998 6.60059l15.6006 19.2002l36.7998 -31.5c3 -2.40039 12 -4.90039 18 2.39941l30 36.5l23.8994 -19.3994c3.5 -2.80078 8.5 -2.2002 11.3008 1.19922zM544 144.1v128h-44.7002l-61.7002 61.6006
c-1.39941 1.5 -3.39941 2.2998 -5.5 2.2998l-83.6992 -0.200195c-10 0 -19.6006 -3.7002 -27 -10.5l-65.6006 -60.0996c-9.7002 -8.7998 -10.5 -24 -1.2002 -33.9004c8.90039 -9.39941 25.1006 -8.7002 34.6006 0l55.2002 50.6006c6.5 5.89941 16.5996 5.5 22.5996 -1
l10.9004 -11.7002c6 -6.5 5.5 -16.6006 -1 -22.6006l-12.5 -11.3994l102.699 -83.4004c2.80078 -2.2998 5.40039 -4.89941 7.7002 -7.7002h69.2002zM592 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16z
" />
<glyph glyph-name="envelope-open" unicode="&#xf2b6;"
d="M494.586 283.484c9.6123 -7.94824 17.4141 -24.5205 17.4141 -36.9932v-262.491c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v262.515c0 12.5166 7.84668 29.1279 17.5146 37.0771c4.08008 3.35449 110.688 89.0996 135.15 108.549
c22.6992 18.1426 60.1299 55.8594 103.335 55.8594c43.4365 0 81.2314 -38.1914 103.335 -55.8594c23.5283 -18.707 130.554 -104.773 135.251 -108.656zM464 -10v253.632v0.00488281c0 1.5791 -0.996094 3.66602 -2.22363 4.6582
c-15.8633 12.8232 -108.793 87.5752 -132.366 106.316c-17.5527 14.0195 -49.7168 45.3887 -73.4102 45.3887c-23.6016 0 -55.2451 -30.8799 -73.4102 -45.3887c-23.5713 -18.7393 -116.494 -93.4795 -132.364 -106.293
c-1.40918 -1.13965 -2.22559 -2.85254 -2.22559 -4.66504v-253.653c0 -3.31152 2.68848 -6 6 -6h404c3.31152 0 6 2.68848 6 6zM432.009 177.704c4.24902 -5.15918 3.46484 -12.7949 -1.74512 -16.9814c-28.9746 -23.2822 -59.2734 -47.5967 -70.9287 -56.8623
c-22.6992 -18.1436 -60.1299 -55.8604 -103.335 -55.8604c-43.4521 0 -81.2871 38.2373 -103.335 55.8604c-11.2793 8.9668 -41.7441 33.4131 -70.9268 56.8643c-5.20996 4.1875 -5.99316 11.8223 -1.74512 16.9814l15.2578 18.5283
c4.17773 5.07227 11.6572 5.84277 16.7793 1.72559c28.6182 -23.001 58.5654 -47.0352 70.5596 -56.5713c17.5527 -14.0195 49.7168 -45.3887 73.4102 -45.3887c23.6016 0 55.2461 30.8799 73.4102 45.3887c11.9941 9.53516 41.9434 33.5703 70.5625 56.5684
c5.12207 4.11621 12.6016 3.3457 16.7783 -1.72656z" />
<glyph glyph-name="address-book" unicode="&#xf2b9;" horiz-adv-x="448"
d="M436 288h-20v-64h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-20v-64h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-20v-48c0 -26.5 -21.5 -48 -48 -48h-320c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48
h320c26.5 0 48 -21.5 48 -48v-48h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM368 -16v416h-320v-416h320zM208 192c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64zM118.4 64
c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002c0 -10.6006 -10 -19.2002 -22.4004 -19.2002
h-179.199z" />
<glyph glyph-name="address-card" unicode="&#xf2bb;" horiz-adv-x="576"
d="M528 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-480c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h480zM528 16v352h-480v-352h480zM208 192c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64z
M118.4 64c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002
c0 -10.6006 -10 -19.2002 -22.4004 -19.2002h-179.199zM360 128c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 192c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112
c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 256c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112z" />
<glyph glyph-name="user-circle" unicode="&#xf2bd;" horiz-adv-x="496"
d="M248 344c53 0 96 -43 96 -96s-43 -96 -96 -96s-96 43 -96 96s43 96 96 96zM248 200c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8
c49.7002 0 95.0996 18.2998 130.1 48.4004c-14.8994 23 -40.3994 38.5 -69.5996 39.5c-20.7998 -6.5 -40.5996 -9.60059 -60.5 -9.60059s-39.7002 3.2002 -60.5 9.60059c-29.2002 -0.900391 -54.7002 -16.5 -69.5996 -39.5c35 -30.1006 80.3994 -48.4004 130.1 -48.4004z
M410.7 76.0996c23.3994 32.7002 37.2998 72.7002 37.2998 115.9c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -43.2002 13.9004 -83.2002 37.2998 -115.9c24.5 31.4004 62.2002 51.9004 105.101 51.9004c10.1992 0 26.0996 -9.59961 57.5996 -9.59961
c31.5996 0 47.4004 9.59961 57.5996 9.59961c43 0 80.7002 -20.5 105.101 -51.9004z" />
<glyph glyph-name="id-badge" unicode="&#xf2c1;" horiz-adv-x="384"
d="M336 448c26.5 0 48 -21.5 48 -48v-416c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48h288zM336 -16v416h-288v-416h288zM144 336c-8.7998 0 -16 7.2002 -16 16s7.2002 16 16 16h96c8.7998 0 16 -7.2002 16 -16s-7.2002 -16 -16 -16
h-96zM192 160c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64zM102.4 32c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8
c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002c0 -10.6006 -10 -19.2002 -22.4004 -19.2002h-179.199z" />
<glyph glyph-name="id-card" unicode="&#xf2c2;" horiz-adv-x="576"
d="M528 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-480c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h480zM528 16v288h-480v-288h32.7998c-1 4.5 -0.799805 -3.59961 -0.799805 22.4004c0 31.7998 30.0996 57.5996 67.2002 57.5996
c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996c0 -26 0.0996094 -17.9004 -0.799805 -22.4004h224.8zM360 96c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16
c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 160c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 224c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112
c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM192 128c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64z" />
<glyph glyph-name="window-maximize" unicode="&#xf2d0;"
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v234h-416v-234c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="window-minimize" unicode="&#xf2d1;"
d="M480 -32h-448c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32h448c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32z" />
<glyph glyph-name="window-restore" unicode="&#xf2d2;"
d="M464 448c26.5 0 48 -21.5 48 -48v-320c0 -26.5 -21.5 -48 -48 -48h-48v-48c0 -26.5 -21.5 -48 -48 -48h-320c-26.5 0 -48 21.5 -48 48v320c0 26.5 21.5 48 48 48h48v48c0 26.5 21.5 48 48 48h320zM368 -16v208h-320v-208h320zM464 80v320h-320v-48h224
c26.5 0 48 -21.5 48 -48v-224h48z" />
<glyph glyph-name="snowflake" unicode="&#xf2dc;" horiz-adv-x="448"
d="M440.1 92.7998c7.60059 -4.39941 10.1006 -14.2002 5.5 -21.7002l-7.89941 -13.8994c-4.40039 -7.7002 -14 -10.2998 -21.5 -5.90039l-39.2002 23l9.09961 -34.7002c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.5996l-15.2002 -4.09961
c-8.39941 -2.30078 -17.0996 2.7998 -19.2998 11.2998l-21.2998 81l-71.9004 42.2002v-84.5l58.2998 -59.3008c6.10059 -6.19922 6.10059 -16.3994 0 -22.5996l-11.0996 -11.2998c-6.09961 -6.2002 -16.0996 -6.2002 -22.2002 0l-24.8994 25.3994v-46.0996
c0 -8.7998 -7 -16 -15.7002 -16h-15.7002c-8.7002 0 -15.7002 7.2002 -15.7002 16v45.9004l-24.8994 -25.4004c-6.10059 -6.2002 -16.1006 -6.2002 -22.2002 0l-11.1006 11.2998c-6.09961 6.2002 -6.09961 16.4004 0 22.6006l58.3008 59.2998v84.5l-71.9004 -42.2002
l-21.2998 -81c-2.2998 -8.5 -10.9004 -13.5996 -19.2998 -11.2998l-15.2002 4.09961c-8.40039 2.2998 -13.2998 11.1006 -11.1006 19.6006l9.10059 34.6992l-39.2002 -23c-7.5 -4.39941 -17.2002 -1.7998 -21.5 5.90039l-7.90039 13.9004
c-4.2998 7.69922 -1.69922 17.5 5.80078 21.8994l39.1992 23l-34.0996 9.2998c-8.40039 2.30078 -13.2998 11.1006 -11.0996 19.6006l4.09961 15.5c2.2998 8.5 10.9004 13.5996 19.2998 11.2998l79.7002 -21.7002l71.9004 42.2002l-71.9004 42.2002l-79.7002 -21.7002
c-8.39941 -2.2998 -17.0996 2.7998 -19.2998 11.2998l-4.09961 15.5c-2.30078 8.5 2.69922 17.2998 11.0996 19.6006l34.0996 9.09961l-39.1992 23c-7.60059 4.5 -10.1006 14.2002 -5.80078 21.9004l7.90039 13.8994c4.40039 7.7002 14 10.2998 21.5 5.90039l39.2002 -23
l-9.10059 34.7002c-2.2998 8.5 2.7002 17.2998 11.1006 19.5996l15.2002 4.09961c8.39941 2.30078 17.0996 -2.7998 19.2998 -11.2998l21.2998 -81l71.9004 -42.2002v84.5l-58.3008 59.3008c-6.09961 6.19922 -6.09961 16.3994 0 22.5996l11.5 11.2998
c6.10059 6.2002 16.1006 6.2002 22.2002 0l24.9004 -25.3994v46.0996c0 8.7998 7 16 15.7002 16h15.6992c8.7002 0 15.7002 -7.2002 15.7002 -16v-45.9004l24.9004 25.4004c6.09961 6.2002 16.0996 6.2002 22.2002 0l11.0996 -11.2998
c6.09961 -6.2002 6.09961 -16.4004 0 -22.6006l-58.2998 -59.2998v-84.5l71.8994 42.2002l21.3008 81c2.2998 8.5 10.8994 13.5996 19.2998 11.2998l15.2002 -4.09961c8.39941 -2.2998 13.2998 -11.1006 11.0996 -19.6006l-9.09961 -34.6992l39.1992 23
c7.5 4.39941 17.2002 1.7998 21.5 -5.90039l7.90039 -13.9004c4.2998 -7.69922 1.7002 -17.5 -5.7998 -21.8994l-39.2002 -23l34.0996 -9.2998c8.40039 -2.30078 13.3008 -11.1006 11.1006 -19.6006l-4.10059 -15.5c-2.2998 -8.5 -10.8994 -13.5996 -19.2998 -11.2998
l-79.7002 21.7002l-71.8994 -42.2002l71.7998 -42.2002l79.7002 21.7002c8.39941 2.2998 17.0996 -2.7998 19.2998 -11.2998l4.09961 -15.5c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.6006l-34.0996 -9.2998z" />
<glyph glyph-name="trash-alt" unicode="&#xf2ed;" horiz-adv-x="448"
d="M268 32c-6.62402 0 -12 5.37598 -12 12v216c0 6.62402 5.37598 12 12 12h24c6.62402 0 12 -5.37598 12 -12v-216c0 -6.62402 -5.37598 -12 -12 -12h-24zM432 368c8.83203 0 16 -7.16797 16 -16v-16c0 -8.83203 -7.16797 -16 -16 -16h-16v-336
c0 -26.4961 -21.5039 -48 -48 -48h-288c-26.4961 0 -48 21.5039 -48 48v336h-16c-8.83203 0 -16 7.16797 -16 16v16c0 8.83203 7.16797 16 16 16h82.4102l34.0195 56.7002c7.71875 12.8613 26.1572 23.2998 41.1572 23.2998h0.00292969h100.82h0.0224609
c15 0 33.4385 -10.4385 41.1572 -23.2998l34 -56.7002h82.4102zM171.84 397.09l-17.4502 -29.0898h139.221l-17.46 29.0898c-0.96582 1.60645 -3.26953 2.91016 -5.14355 2.91016h-0.00683594h-94h-0.0166016c-1.87402 0 -4.17871 -1.30371 -5.14355 -2.91016zM368 -16v336
h-288v-336h288zM156 32c-6.62402 0 -12 5.37598 -12 12v216c0 6.62402 5.37598 12 12 12h24c6.62402 0 12 -5.37598 12 -12v-216c0 -6.62402 -5.37598 -12 -12 -12h-24z" />
<glyph glyph-name="images" unicode="&#xf302;" horiz-adv-x="576"
d="M480 32v-16c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256c0 26.5098 21.4902 48 48 48h16v-48h-10c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v10h48zM522 368h-372
c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v244c0 3.31152 -2.68848 6 -6 6zM528 416c26.5098 0 48 -21.4902 48 -48v-256c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256
c0 26.5098 21.4902 48 48 48h384zM264 304c0 -22.0908 -17.9092 -40 -40 -40s-40 17.9092 -40 40s17.9092 40 40 40s40 -17.9092 40 -40zM192 208l39.5146 39.5146c4.68652 4.68652 12.2842 4.68652 16.9717 0l39.5137 -39.5146l103.515 103.515
c4.68652 4.68652 12.2842 4.68652 16.9717 0l71.5137 -71.5146v-80h-288v48z" />
<glyph glyph-name="clipboard" unicode="&#xf328;" horiz-adv-x="384"
d="M336 384c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h80c0 35.2998 28.7002 64 64 64s64 -28.7002 64 -64h80zM192 408c-13.2998 0 -24 -10.7002 -24 -24s10.7002 -24 24 -24s24 10.7002 24 24
s-10.7002 24 -24 24zM336 -10v340c0 3.2998 -2.7002 6 -6 6h-42v-36c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12v36h-42c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h276c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="arrow-alt-circle-down" unicode="&#xf358;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM224 308c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-116
h67c10.7002 0 16.0996 -12.9004 8.5 -20.5l-99 -99c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-99 99c-7.5 7.59961 -2.2002 20.5 8.5 20.5h67v116z" />
<glyph glyph-name="arrow-alt-circle-left" unicode="&#xf359;"
d="M8 192c0 137 111 248 248 248s248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248zM456 192c0 110.5 -89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200s200 89.5 200 200zM384 212v-40c0 -6.59961 -5.40039 -12 -12 -12h-116v-67
c0 -10.7002 -12.9004 -16 -20.5 -8.5l-99 99c-4.7002 4.7002 -4.7002 12.2998 0 17l99 99c7.59961 7.59961 20.5 2.2002 20.5 -8.5v-67h116c6.59961 0 12 -5.40039 12 -12z" />
<glyph glyph-name="arrow-alt-circle-right" unicode="&#xf35a;"
d="M504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200zM128 172v40c0 6.59961 5.40039 12 12 12h116v67
c0 10.7002 12.9004 16 20.5 8.5l99 -99c4.7002 -4.7002 4.7002 -12.2998 0 -17l-99 -99c-7.59961 -7.59961 -20.5 -2.2002 -20.5 8.5v67h-116c-6.59961 0 -12 5.40039 -12 12z" />
<glyph glyph-name="arrow-alt-circle-up" unicode="&#xf35b;"
d="M256 -56c-137 0 -248 111 -248 248s111 248 248 248s248 -111 248 -248s-111 -248 -248 -248zM256 392c-110.5 0 -200 -89.5 -200 -200s89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200zM276 64h-40c-6.59961 0 -12 5.40039 -12 12v116h-67
c-10.7002 0 -16 12.9004 -8.5 20.5l99 99c4.7002 4.7002 12.2998 4.7002 17 0l99 -99c7.59961 -7.59961 2.2002 -20.5 -8.5 -20.5h-67v-116c0 -6.59961 -5.40039 -12 -12 -12z" />
<glyph glyph-name="gem" unicode="&#xf3a5;" horiz-adv-x="576"
d="M464 448c4.09961 0 7.7998 -2 10.0996 -5.40039l99.9004 -147.199c2.90039 -4.40039 2.59961 -10.1006 -0.700195 -14.2002l-276 -340.8c-4.7998 -5.90039 -13.7998 -5.90039 -18.5996 0l-276 340.8c-3.2998 4 -3.60059 9.7998 -0.700195 14.2002l100 147.199
c2.2002 3.40039 6 5.40039 10 5.40039h352zM444.7 400h-56.7998l51.6992 -96h68.4004zM242.6 400l-51.5996 -96h194l-51.7002 96h-90.7002zM131.3 400l-63.2998 -96h68.4004l51.6992 96h-56.7998zM88.2998 256l119.7 -160l-68.2998 160h-51.4004zM191.2 256l96.7998 -243.3
l96.7998 243.3h-193.6zM368 96l119.6 160h-51.3994z" />
<glyph glyph-name="money-bill-alt" unicode="&#xf3d1;" horiz-adv-x="640"
d="M320 304c53.0195 0 96 -50.1396 96 -112c0 -61.8701 -43 -112 -96 -112c-53.0195 0 -96 50.1504 -96 112c0 61.8604 42.9805 112 96 112zM360 136v16c0 4.41992 -3.58008 8 -8 8h-16v88c0 4.41992 -3.58008 8 -8 8h-13.5801h-0.000976562
c-4.01074 0 -9.97266 -1.80566 -13.3086 -4.03027l-15.3301 -10.2197c-1.96777 -1.30957 -3.56445 -4.29004 -3.56445 -6.65332c0 -1.33691 0.601562 -3.32422 1.34375 -4.43652l8.88086 -13.3105c1.30859 -1.9668 4.29004 -3.56445 6.65332 -3.56445
c1.33691 0 3.32422 0.602539 4.43652 1.34473l0.469727 0.310547v-55.4404h-16c-4.41992 0 -8 -3.58008 -8 -8v-16c0 -4.41992 3.58008 -8 8 -8h64c4.41992 0 8 3.58008 8 8zM608 384c17.6699 0 32 -14.3301 32 -32v-320c0 -17.6699 -14.3301 -32 -32 -32h-576
c-17.6699 0 -32 14.3301 -32 32v320c0 17.6699 14.3301 32 32 32h576zM592 112v160c-35.3496 0 -64 28.6504 -64 64h-416c0 -35.3496 -28.6504 -64 -64 -64v-160c35.3496 0 64 -28.6504 64 -64h416c0 35.3496 28.6504 64 64 64z" />
<glyph glyph-name="window-close" unicode="&#xf410;"
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v340c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z
M356.5 253.4l-61.4004 -61.4004l61.4004 -61.4004c4.59961 -4.59961 4.59961 -12.0996 0 -16.7998l-22.2998 -22.2998c-4.60059 -4.59961 -12.1006 -4.59961 -16.7998 0l-61.4004 61.4004l-61.4004 -61.4004c-4.59961 -4.59961 -12.0996 -4.59961 -16.7998 0
l-22.2998 22.2998c-4.59961 4.60059 -4.59961 12.1006 0 16.7998l61.4004 61.4004l-61.4004 61.4004c-4.59961 4.59961 -4.59961 12.0996 0 16.7998l22.2998 22.2998c4.60059 4.59961 12.1006 4.59961 16.7998 0l61.4004 -61.4004l61.4004 61.4004
c4.59961 4.59961 12.0996 4.59961 16.7998 0l22.2998 -22.2998c4.7002 -4.60059 4.7002 -12.1006 0 -16.7998z" />
<glyph glyph-name="comment-dots" unicode="&#xf4ad;"
d="M144 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM256 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM368 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32
s-32 14.2998 -32 32s14.2998 32 32 32zM256 416c141.4 0 256 -93.0996 256 -208s-114.6 -208 -256 -208c-32.7998 0 -64 5.2002 -92.9004 14.2998c-29.0996 -20.5996 -77.5996 -46.2998 -139.1 -46.2998c-9.59961 0 -18.2998 5.7002 -22.0996 14.5
c-3.80078 8.7998 -2 19 4.59961 26c0.5 0.400391 31.5 33.7998 46.4004 73.2002c-33 35.0996 -52.9004 78.7002 -52.9004 126.3c0 114.9 114.6 208 256 208zM256 48c114.7 0 208 71.7998 208 160s-93.2998 160 -208 160s-208 -71.7998 -208 -160
c0 -42.2002 21.7002 -74.0996 39.7998 -93.4004l20.6006 -21.7998l-10.6006 -28.0996c-5.5 -14.5 -12.5996 -28.1006 -19.8994 -40.2002c23.5996 7.59961 43.1992 18.9004 57.5 29l19.5 13.7998l22.6992 -7.2002c25.3008 -8 51.7002 -12.0996 78.4004 -12.0996z" />
<glyph glyph-name="smile-wink" unicode="&#xf4da;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM365.8 138.4c10.2002 -8.5 11.6006 -23.6006 3.10059 -33.8008
c-30 -36 -74.1006 -56.5996 -120.9 -56.5996s-90.9004 20.5996 -120.9 56.5996c-8.39941 10.2002 -7.09961 25.3008 3.10059 33.8008c10.0996 8.39941 25.2998 7.09961 33.7998 -3.10059c20.7998 -25.0996 51.5 -39.3994 84 -39.3994s63.2002 14.3994 84 39.3994
c8.5 10.2002 23.5996 11.6006 33.7998 3.10059zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 268c25.7002 0 55.9004 -16.9004 59.7002 -42.0996c1.7998 -11.1006 -11.2998 -18.2002 -19.7998 -10.8008l-9.5 8.5
c-14.8008 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-8.30078 -7.39941 -21.5 -0.399414 -19.8008 10.8008c4 25.1992 34.2002 42.0996 59.9004 42.0996z" />
<glyph glyph-name="angry" unicode="&#xf556;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM248 136c33.5996 0 65.2002 -14.7998 86.7998 -40.5996
c8.40039 -10.2002 7.10059 -25.3008 -3.09961 -33.8008c-10.6006 -8.89941 -25.7002 -6.69922 -33.7998 3c-24.8008 29.7002 -75 29.7002 -99.8008 0c-8.5 -10.1992 -23.5996 -11.5 -33.7998 -3s-11.5996 23.6006 -3.09961 33.8008
c21.5996 25.7998 53.2002 40.5996 86.7998 40.5996zM200 208c0 -17.7002 -14.2998 -32.0996 -32 -32.0996s-32 14.2998 -32 32c0 6.19922 2.2002 11.6992 5.2998 16.5996l-28.2002 8.5c-12.6992 3.7998 -19.8994 17.2002 -16.0996 29.9004
c3.7998 12.6992 17.0996 20 29.9004 16.0996l80 -24c12.6992 -3.7998 19.8994 -17.2002 16.0996 -29.9004c-3.09961 -10.3994 -12.7002 -17.0996 -23 -17.0996zM399 262.9c3.7998 -12.7002 -3.40039 -26.1006 -16.0996 -29.8008l-28.2002 -8.5
c3.09961 -4.89941 5.2998 -10.3994 5.2998 -16.5996c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32c-10.2998 0 -19.9004 6.7002 -23 17.0996c-3.7998 12.7002 3.40039 26.1006 16.0996 29.9004l80 24c12.8008 3.7998 26.1006 -3.40039 29.9004 -16.0996z" />
<glyph glyph-name="dizzy" unicode="&#xf567;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM214.2 209.9
c-7.90039 -7.90039 -20.5 -7.90039 -28.4004 -0.200195l-17.7998 17.7998l-17.7998 -17.7998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0c-7.80078 7.7998 -7.80078 20.5 0 28.2998l17.8994 17.9004l-17.8994 17.8994c-7.80078 7.7998 -7.80078 20.5 0 28.2998
c7.7998 7.80078 20.5 7.80078 28.2998 0l17.7998 -17.7998l17.9004 17.9004c7.7998 7.7998 20.5 7.7998 28.2998 0s7.7998 -20.5 0 -28.2998l-17.9004 -17.9004l17.9004 -17.7998c7.7998 -7.7998 7.7998 -20.5 0 -28.2998zM374.2 302.1
c7.7002 -7.7998 7.7002 -20.3994 0 -28.1992l-17.9004 -17.9004l17.7998 -18c7.80078 -7.7998 7.80078 -20.5 0 -28.2998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0l-17.7998 17.7998l-17.7998 -17.7998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0
c-7.80078 7.7998 -7.80078 20.5 0 28.2998l17.8994 17.9004l-17.8994 17.8994c-7.80078 7.7998 -7.80078 20.5 0 28.2998c7.7998 7.80078 20.5 7.80078 28.2998 0l17.7998 -17.7998l17.9004 17.7998c7.7998 7.80078 20.5 7.80078 28.2998 0zM248 176
c35.2998 0 64 -28.7002 64 -64s-28.7002 -64 -64 -64s-64 28.7002 -64 64s28.7002 64 64 64z" />
<glyph glyph-name="flushed" unicode="&#xf579;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM344 304c44.2002 0 80 -35.7998 80 -80s-35.7998 -80 -80 -80
s-80 35.7998 -80 80s35.7998 80 80 80zM344 176c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM344 248c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM232 224c0 -44.2002 -35.7998 -80 -80 -80
s-80 35.7998 -80 80s35.7998 80 80 80s80 -35.7998 80 -80zM152 176c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM152 248c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM312 104
c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-128c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h128z" />
<glyph glyph-name="frown-open" unicode="&#xf57a;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM200 240c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32
s14.2998 32 32 32s32 -14.2998 32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM248 160c35.5996 0 88.7998 -21.2998 95.7998 -61.2002c2 -11.7998 -9.09961 -21.5996 -20.5 -18.0996
c-31.2002 9.59961 -59.3994 15.2998 -75.2998 15.2998s-44.0996 -5.7002 -75.2998 -15.2998c-11.5 -3.40039 -22.5 6.2998 -20.5 18.0996c7 39.9004 60.2002 61.2002 95.7998 61.2002z" />
<glyph glyph-name="grimace" unicode="&#xf57f;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM344 192c26.5 0 48 -21.5 48 -48v-32c0 -26.5 -21.5 -48 -48 -48h-192c-26.5 0 -48 21.5 -48 48v32c0 26.5 21.5 48 48 48
h192zM176 96v24h-40v-8c0 -8.7998 7.2002 -16 16 -16h24zM176 136v24h-24c-8.7998 0 -16 -7.2002 -16 -16v-8h40zM240 96v24h-48v-24h48zM240 136v24h-48v-24h48zM304 96v24h-48v-24h48zM304 136v24h-48v-24h48zM360 112v8h-40v-24h24c8.7998 0 16 7.2002 16 16zM360 136v8
c0 8.7998 -7.2002 16 -16 16h-24v-24h40z" />
<glyph glyph-name="grin" unicode="&#xf580;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 9.90039 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32z" />
<glyph glyph-name="grin-alt" unicode="&#xf581;" horiz-adv-x="496"
d="M200.3 200c-7.5 -11.4004 -24.5996 -12 -32.7002 0c-12.3994 18.7002 -15.1992 37.2998 -15.6992 56c0.599609 18.7002 3.2998 37.2998 15.6992 56c7.60059 11.4004 24.7002 12 32.7002 0c12.4004 -18.7002 15.2002 -37.2998 15.7002 -56
c-0.599609 -18.7002 -3.2998 -37.2998 -15.7002 -56zM328.3 200c-7.5 -11.4004 -24.5996 -12 -32.7002 0c-12.3994 18.7002 -15.1992 37.2998 -15.6992 56c0.599609 18.7002 3.2998 37.2998 15.6992 56c7.60059 11.4004 24.7002 12 32.7002 0
c12.4004 -18.7002 15.2002 -37.2998 15.7002 -56c-0.599609 -18.7002 -3.2998 -37.2998 -15.7002 -56zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200
s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006
s79.7002 4.7998 105.6 13.1006z" />
<glyph glyph-name="grin-beam" unicode="&#xf582;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM117.7 216.3c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996
l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002zM277.7 216.3c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998
c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002z" />
<glyph glyph-name="grin-beam-sweat" unicode="&#xf583;" horiz-adv-x="496"
d="M440 288c-29.5 0 -53.2998 26.2998 -53.2998 58.7002c0 25 31.7002 75.5 46.2002 97.2998c3.5 5.2998 10.5996 5.2998 14.1992 0c14.5 -21.7998 46.2002 -72.2998 46.2002 -97.2998c0 -32.4004 -23.7998 -58.7002 -53.2998 -58.7002zM248 48
c-51.9004 0 -115.3 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-8 -47.0996 -71.3994 -80 -123.3 -80zM378.3 216.3
c-3.09961 -0.899414 -7.2002 0.100586 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998zM483.6 269.2c8 -24.2998 12.4004 -50.2002 12.4004 -77.2002c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248
c45.7002 0 88.4004 -12.5996 125.2 -34.2002c-10.9004 -21.5996 -15.5 -36.2002 -17.2002 -45.7002c-31.2002 20.1006 -68.2002 31.9004 -108 31.9004c-110.3 0 -200 -89.7002 -200 -200s89.7002 -200 200 -200s200 89.7002 200 200
c0 22.5 -3.90039 44.0996 -10.7998 64.2998c0.399414 0 21.7998 -2.7998 46.3994 12.9004zM168 258.6c-12.2998 0 -23.7998 -7.7998 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996z" />
<glyph glyph-name="grin-hearts" unicode="&#xf584;" horiz-adv-x="496"
d="M353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM200.8 192.3
l-70.2002 18.1006c-20.3994 5.2998 -31.8994 27 -24.1992 47.1992c6.69922 17.7002 26.6992 26.7002 44.8994 22l7.10059 -1.89941l2 7.09961c5.09961 18.1006 22.8994 30.9004 41.5 27.9004c21.3994 -3.40039 34.3994 -24.2002 28.7998 -44.5l-19.4004 -69.9004
c-1.2998 -4.5 -6 -7.2002 -10.5 -6zM389.6 257.6c7.7002 -20.1992 -3.7998 -41.7998 -24.1992 -47.0996l-70.2002 -18.2002c-4.60059 -1.2002 -9.2998 1.5 -10.5 6l-19.4004 69.9004c-5.59961 20.2998 7.40039 41.0996 28.7998 44.5c18.7002 3 36.5 -9.7998 41.5 -27.9004
l2 -7.09961l7.10059 1.89941c18.2002 4.7002 38.2002 -4.39941 44.8994 -22zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200
s89.7002 -200 200 -200z" />
<glyph glyph-name="grin-squint" unicode="&#xf585;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 9.90039 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM118.9 184.2c-3.80078 4.39941 -3.90039 11 -0.100586 15.5l33.6006 40.2998
l-33.6006 40.2998c-3.7002 4.5 -3.7002 11 0.100586 15.5c3.89941 4.40039 10.1992 5.5 15.2998 2.5l80 -48c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998s-2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7002 -1.7002 -15.2998 2.5zM361.8 181.7
l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5.10059 2.90039 11.5 1.90039 15.2998 -2.5c3.80078 -4.5 3.90039 -11 0.100586 -15.5l-33.6006 -40.2998l33.6006 -40.2998c3.7002 -4.5 3.7002 -11 -0.100586 -15.5
c-3.59961 -4.2002 -9.89941 -5.7002 -15.2998 -2.5z" />
<glyph glyph-name="grin-squint-tears" unicode="&#xf586;"
d="M117.1 63.9004c6.30078 0.899414 11.7002 -4.5 10.9004 -10.9004c-3.7002 -25.7998 -13.7002 -84 -30.5996 -100.9c-22 -21.8994 -57.9004 -21.5 -80.3008 0.900391c-22.3994 22.4004 -22.7998 58.4004 -0.899414 80.2998
c16.8994 16.9004 75.0996 26.9004 100.899 30.6006zM75.9004 105.6c-19.6006 -3.89941 -35.1006 -8.09961 -47.3008 -12.1992c-39.2998 90.5996 -22.0996 199.899 52 274c48.5 48.3994 111.9 72.5996 175.4 72.5996c38.9004 0 77.7998 -9.2002 113.2 -27.4004
c-4 -12.1992 -8.2002 -28 -12 -48.2998c-30.4004 17.9004 -65 27.7002 -101.2 27.7002c-53.4004 0 -103.6 -20.7998 -141.4 -58.5996c-61.5996 -61.5 -74.2998 -153.4 -38.6992 -227.801zM428.2 293.2c20.2998 3.89941 36.2002 8 48.5 12
c47.8994 -93.2002 32.8994 -210.5 -45.2002 -288.601c-48.5 -48.3994 -111.9 -72.5996 -175.4 -72.5996c-33.6992 0 -67.2998 7 -98.6992 20.5996c4.19922 12.2002 8.2998 27.7002 12.1992 47.2002c26.6006 -12.7998 55.9004 -19.7998 86.4004 -19.7998
c53.4004 0 103.6 20.7998 141.4 58.5996c65.6992 65.7002 75.7998 166 30.7998 242.601zM394.9 320.1c-6.30078 -0.899414 -11.7002 4.5 -10.9004 10.9004c3.7002 25.7998 13.7002 84 30.5996 100.9c22 21.8994 57.9004 21.5 80.3008 -0.900391
c22.3994 -22.4004 22.7998 -58.4004 0.899414 -80.2998c-16.8994 -16.9004 -75.0996 -26.9004 -100.899 -30.6006zM207.9 211.8c3 -3 4.19922 -7.2998 3.19922 -11.5l-22.5996 -90.5c-1.40039 -5.39941 -6.2002 -9.09961 -11.7002 -9.09961h-0.899414
c-5.80078 0.5 -10.5 5.09961 -11 10.8994l-4.80078 52.3008l-52.2998 4.7998c-5.7998 0.5 -10.3994 5.2002 -10.8994 11c-0.400391 5.89941 3.39941 11.2002 9.09961 12.5996l90.5 22.7002c4.2002 1 8.40039 -0.200195 11.4004 -3.2002zM247.6 236.9
c-0.0996094 0 -6.39941 -1.80078 -11.3994 3.19922c-3 3 -4.2002 7.30078 -3.2002 11.4004l22.5996 90.5c1.40039 5.7002 7 9.2002 12.6006 9.09961c5.7998 -0.5 10.5 -5.09961 11 -10.8994l4.7998 -52.2998l52.2998 -4.80078c5.7998 -0.5 10.4004 -5.19922 10.9004 -11
c0.399414 -5.89941 -3.40039 -11.1992 -9.10059 -12.5996zM299.6 148.4c29.1006 29.0996 53 59.5996 65.3008 83.7998c4.89941 9.2998 17.5996 9.89941 23.3994 1.7002c27.7002 -38.9004 6.10059 -106.9 -30.5996 -143.7s-104.8 -58.2998 -143.7 -30.6006
c-8.2998 5.90039 -7.5 18.6006 1.7002 23.4004c24.2002 12.5 54.7998 36.2998 83.8994 65.4004z" />
<glyph glyph-name="grin-stars" unicode="&#xf587;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM125.7 200.9l6.09961 34.8994l-25.3994 24.6006
c-4.60059 4.59961 -1.90039 12.2998 4.2998 13.1992l34.8994 5l15.5 31.6006c2.90039 5.7998 11 5.7998 13.9004 0l15.5 -31.6006l34.9004 -5c6.19922 -1 8.7998 -8.69922 4.2998 -13.1992l-25.4004 -24.6006l6 -34.8994c1 -6.2002 -5.39941 -11 -11 -7.90039
l-31.2998 16.2998l-31.2998 -16.2998c-5.60059 -3.09961 -12 1.7002 -11 7.90039zM385.4 273.6c6.19922 -1 8.89941 -8.59961 4.39941 -13.1992l-25.3994 -24.6006l6 -34.8994c1 -6.2002 -5.40039 -11 -11 -7.90039l-31.3008 16.2998l-31.2998 -16.2998
c-5.59961 -3.09961 -12 1.7002 -11 7.90039l6 34.8994l-25.3994 24.6006c-4.60059 4.59961 -1.90039 12.2998 4.2998 13.1992l34.8994 5l15.5 31.6006c2.90039 5.7998 11 5.7998 13.9004 0l15.5 -31.6006z" />
<glyph glyph-name="grin-tears" unicode="&#xf588;" horiz-adv-x="640"
d="M117.1 191.9c6.30078 0.899414 11.7002 -4.5 10.9004 -10.9004c-3.7002 -25.7998 -13.7002 -84 -30.5996 -100.9c-22 -21.8994 -57.9004 -21.5 -80.3008 0.900391c-22.3994 22.4004 -22.7998 58.4004 -0.899414 80.2998c16.8994 16.9004 75.0996 26.9004 100.899 30.6006
zM623.8 161.3c21.9004 -21.8994 21.5 -57.8994 -0.799805 -80.2002c-22.4004 -22.3994 -58.4004 -22.7998 -80.2998 -0.899414c-16.9004 16.8994 -26.9004 75.0996 -30.6006 100.899c-0.899414 6.30078 4.5 11.7002 10.8008 10.8008
c25.7998 -3.7002 84 -13.7002 100.899 -30.6006zM497.2 99.5996c12.3994 -37.2998 25.0996 -43.7998 28.2998 -46.5c-44.5996 -65.7998 -120 -109.1 -205.5 -109.1s-160.9 43.2998 -205.5 109.1c3.09961 2.60059 15.7998 9.10059 28.2998 46.5
c33.4004 -63.8994 100.3 -107.6 177.2 -107.6s143.8 43.7002 177.2 107.6zM122.7 223.5c-2.40039 0.299805 -5 2.5 -49.5 -6.90039c12.3994 125.4 118.1 223.4 246.8 223.4s234.4 -98 246.8 -223.5c-44.2998 9.40039 -47.3994 7.2002 -49.5 7
c-15.2002 95.2998 -97.7998 168.5 -197.3 168.5s-182.1 -73.2002 -197.3 -168.5zM320 48c-51.9004 0 -115.3 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996
c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-8 -47.0996 -71.3994 -80 -123.3 -80zM450.3 216.3c-3.09961 -0.899414 -7.2002 0.100586 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17
c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998zM240 258.6
c-12.2998 0 -23.7998 -7.7998 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996z" />
<glyph glyph-name="grin-tongue" unicode="&#xf589;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0
l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200
s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996
s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998zM168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32
s14.2998 32 32 32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
<glyph glyph-name="grin-tongue-squint" unicode="&#xf58a;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0
l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200
s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996
s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998zM377.1 295.8c3.80078 -4.39941 3.90039 -11 0.100586 -15.5l-33.6006 -40.2998
l33.6006 -40.2998c3.7002 -4.5 3.7002 -11 -0.100586 -15.5c-3.59961 -4.2002 -9.89941 -5.7002 -15.2998 -2.5l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5 3 11.5 1.90039 15.2998 -2.5zM214.2 250.3
c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998s-2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7002 -1.7002 -15.2998 2.5c-3.80078 4.5 -3.90039 11 -0.100586 15.5l33.6006 40.2998l-33.6006 40.2998c-3.7002 4.5 -3.7002 11 0.100586 15.5
c3.89941 4.5 10.2998 5.5 15.2998 2.5z" />
<glyph glyph-name="grin-tongue-wink" unicode="&#xf58b;" horiz-adv-x="496"
d="M152 268c25.7002 0 55.9004 -16.9004 59.7998 -42.0996c0.799805 -5 -1.7002 -10 -6.09961 -12.4004c-5.7002 -3.09961 -11.2002 -0.599609 -13.7002 1.59961l-9.5 8.5c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5
c-3.7998 -3.39941 -9.2998 -4 -13.7002 -1.59961c-4.39941 2.40039 -6.89941 7.40039 -6.09961 12.4004c3.89941 25.1992 34.0996 42.0996 59.7998 42.0996zM328 320c44.2002 0 80 -35.7998 80 -80s-35.7998 -80 -80 -80s-80 35.7998 -80 80s35.7998 80 80 80zM328 192
c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM328 264c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248z
M312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998
c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3
c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998
c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998z" />
<glyph glyph-name="grin-wink" unicode="&#xf58c;" horiz-adv-x="496"
d="M328 268c25.6904 0 55.8799 -16.9199 59.8701 -42.1201c1.72949 -11.0898 -11.3506 -18.2695 -19.8301 -10.8398l-9.5498 8.47949c-14.8105 13.1904 -46.1602 13.1904 -60.9707 0l-9.5498 -8.47949c-8.33008 -7.40039 -21.5801 -0.379883 -19.8301 10.8398
c3.98047 25.2002 34.1699 42.1201 59.8604 42.1201zM168 208c-17.6699 0 -32 14.3301 -32 32s14.3301 32 32 32s32 -14.3301 32 -32s-14.3301 -32 -32 -32zM353.55 143.36c10.04 3.13965 19.3906 -5.4502 17.71 -15.3408
c-7.92969 -47.1494 -71.3193 -80.0195 -123.26 -80.0195s-115.33 32.8701 -123.26 80.0195c-1.69043 9.9707 7.76953 18.4707 17.71 15.3408c25.9297 -8.31055 64.3994 -13.0605 105.55 -13.0605s79.6201 4.75977 105.55 13.0605zM248 440c136.97 0 248 -111.03 248 -248
s-111.03 -248 -248 -248s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
<glyph glyph-name="kiss" unicode="&#xf596;" horiz-adv-x="496"
d="M168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM304 140c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5
c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM248 440c137 0 248 -111 248 -248
s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z
" />
<glyph glyph-name="kiss-beam" unicode="&#xf597;" horiz-adv-x="496"
d="M168 296c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.299805 -3.7998 -2 -7.19922 -5.59961 -8.2998c-3.10059 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996c-12.3008 0 -23.8008 -7.89941 -31.5 -21.5996l-9.5 -17
c-1.80078 -3.2002 -5.80078 -4.7002 -9.30078 -3.7002c-3.59961 1.10059 -5.89941 4.60059 -5.59961 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8
c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM304 140c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5
c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM328 296
c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.299805 -3.7998 -2 -7.19922 -5.59961 -8.2998c-3.10059 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996c-12.3008 0 -23.8008 -7.89941 -31.5 -21.5996l-9.5 -17
c-1.80078 -3.2002 -5.80078 -4.7002 -9.30078 -3.7002c-3.59961 1.10059 -5.89941 4.60059 -5.59961 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004z" />
<glyph glyph-name="kiss-wink-heart" unicode="&#xf598;" horiz-adv-x="504"
d="M304 139.5c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002
c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM374.5 223c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-2.5 -2.2998 -7.90039 -4.7002 -13.7002 -1.59961c-4.39941 2.39941 -6.89941 7.39941 -6.09961 12.3994
c3.89941 25.2002 34.2002 42.1006 59.7998 42.1006s55.7998 -16.9004 59.7998 -42.1006c0.799805 -5 -1.7002 -10 -6.09961 -12.3994c-4.40039 -2.40039 -9.90039 -1.7002 -13.7002 1.59961zM136 239.5c0 17.7002 14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32
s-32 14.2998 -32 32zM501.1 45.5c9.2002 -23.9004 -4.39941 -49.4004 -28.5 -55.7002l-83 -21.5c-5.39941 -1.39941 -10.8994 1.7998 -12.3994 7.10059l-22.9004 82.5996c-6.59961 24 8.7998 48.5996 34 52.5996c22 3.5 43.1006 -11.5996 49 -33l2.2998 -8.39941
l8.40039 2.2002c21.5996 5.59961 45.0996 -5.10059 53.0996 -25.9004zM334 11.7002c17.7002 -64 10.9004 -39.5 13.4004 -46.7998c-30.5 -13.4004 -64 -20.9004 -99.4004 -20.9004c-137 0 -248 111 -248 248s111 248 248 248s248 -111 247.9 -248
c0 -31.7998 -6.2002 -62.0996 -17.1006 -90c-6 1.5 -12.2002 2.7998 -18.5996 2.90039c-5.60059 9.69922 -13.6006 17.5 -22.6006 23.8994c6.7002 19.9004 10.4004 41.1006 10.4004 63.2002c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200
c30.7998 0 59.9004 7.2002 86 19.7002z" />
<glyph glyph-name="laugh" unicode="&#xf599;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 224c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM168 224
c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
<glyph glyph-name="laugh-beam" unicode="&#xf59a;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 296c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.700195 -8.5 -10.7998 -11.8994 -14.8994 -4.5
l-9.5 17c-7.7002 13.7002 -19.2002 21.6006 -31.5 21.6006c-12.3008 0 -23.8008 -7.90039 -31.5 -21.6006l-9.5 -17c-4.10059 -7.39941 -15.6006 -4.09961 -14.9004 4.5c3.2998 42.1006 32.2002 71.4004 56 71.4004zM127 220.1c-4.2002 -7.39941 -15.7002 -4 -15.0996 4.5
c3.2998 42.1006 32.1992 71.4004 56 71.4004c23.7998 0 52.6992 -29.2998 56 -71.4004c0.699219 -8.5 -10.8008 -11.8994 -14.9004 -4.5l-9.5 17c-7.7002 13.7002 -19.2002 21.6006 -31.5 21.6006s-23.7998 -7.90039 -31.5 -21.6006zM362.4 160c8.19922 0 14.5 -7 13.5 -15
c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
<glyph glyph-name="laugh-squint" unicode="&#xf59b;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM343.6 252l33.6006 -40.2998c8.59961 -10.4004 -3.90039 -24.7998 -15.4004 -18l-80 48
c-7.7998 4.7002 -7.7998 15.8994 0 20.5996l80 48c11.6006 6.7998 24 -7.7002 15.4004 -18zM134.2 193.7c-11.6006 -6.7998 -24.1006 7.59961 -15.4004 18l33.6006 40.2998l-33.6006 40.2998c-8.59961 10.2998 3.7998 24.9004 15.4004 18l80 -48
c7.7998 -4.7002 7.7998 -15.8994 0 -20.5996zM362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
<glyph glyph-name="laugh-wink" unicode="&#xf59c;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 284c25.7002 0 55.9004 -16.9004 59.7002 -42.0996c1.7998 -11.1006 -11.2998 -18.2002 -19.7998 -10.8008
l-9.5 8.5c-14.8008 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-8.30078 -7.39941 -21.5 -0.399414 -19.8008 10.8008c4 25.1992 34.2002 42.0996 59.9004 42.0996zM168 224c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32z
M362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
<glyph glyph-name="meh-blank" unicode="&#xf5a4;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32
s-32 14.2998 -32 32s14.2998 32 32 32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
<glyph glyph-name="meh-rolling-eyes" unicode="&#xf5a5;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM336 296c39.7998 0 72 -32.2002 72 -72s-32.2002 -72 -72 -72
s-72 32.2002 -72 72s32.2002 72 72 72zM336 184c22.0996 0 40 17.9004 40 40c0 13.5996 -7.2998 25.0996 -17.7002 32.2998c1 -2.59961 1.7002 -5.39941 1.7002 -8.2998c0 -13.2998 -10.7002 -24 -24 -24s-24 10.7002 -24 24c0 3 0.700195 5.7002 1.7002 8.2998
c-10.4004 -7.2002 -17.7002 -18.7002 -17.7002 -32.2998c0 -22.0996 17.9004 -40 40 -40zM232 224c0 -39.7998 -32.2002 -72 -72 -72s-72 32.2002 -72 72s32.2002 72 72 72s72 -32.2002 72 -72zM120 224c0 -22.0996 17.9004 -40 40 -40s40 17.9004 40 40
c0 13.5996 -7.2998 25.0996 -17.7002 32.2998c1 -2.59961 1.7002 -5.39941 1.7002 -8.2998c0 -13.2998 -10.7002 -24 -24 -24s-24 10.7002 -24 24c0 3 0.700195 5.7002 1.7002 8.2998c-10.4004 -7.2002 -17.7002 -18.7002 -17.7002 -32.2998zM312 96
c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-128c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h128z" />
<glyph glyph-name="sad-cry" unicode="&#xf5b3;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM392 53.5996c34.5996 35.9004 56 84.7002 56 138.4c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -53.7002 21.4004 -102.4 56 -138.4v114.4
c0 13.2002 10.7998 24 24 24s24 -10.7998 24 -24v-151.4c28.5 -15.5996 61.2002 -24.5996 96 -24.5996s67.5 9 96 24.5996v151.4c0 13.2002 10.7998 24 24 24s24 -10.7998 24 -24v-114.4zM205.8 213.5c-5.7998 -3.2002 -11.2002 -0.700195 -13.7002 1.59961l-9.5 8.5
c-14.7998 13.2002 -46.1992 13.2002 -61 0l-9.5 -8.5c-3.7998 -3.39941 -9.2998 -4 -13.6992 -1.59961c-4.40039 2.40039 -6.90039 7.40039 -6.10059 12.4004c3.90039 25.1992 34.2002 42.0996 59.7998 42.0996c25.6006 0 55.8008 -16.9004 59.8008 -42.0996
c0.799805 -5 -1.7002 -10 -6.10059 -12.4004zM344 268c25.7002 0 55.9004 -16.9004 59.7998 -42.0996c0.799805 -5 -1.7002 -10 -6.09961 -12.4004c-5.7002 -3.09961 -11.2002 -0.599609 -13.7002 1.59961l-9.5 8.5c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5
c-3.7998 -3.39941 -9.2002 -4 -13.7002 -1.59961c-4.39941 2.40039 -6.89941 7.40039 -6.09961 12.4004c3.89941 25.1992 34.0996 42.0996 59.7998 42.0996zM248 176c30.9004 0 56 -28.7002 56 -64s-25.0996 -64 -56 -64s-56 28.7002 -56 64s25.0996 64 56 64z" />
<glyph glyph-name="sad-tear" unicode="&#xf5b4;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM256 144c38.0996 0 74 -16.7998 98.5 -46.0996
c8.5 -10.2002 7.09961 -25.3008 -3.09961 -33.8008c-10.6006 -8.7998 -25.7002 -6.69922 -33.8008 3.10059c-15.2998 18.2998 -37.7998 28.7998 -61.5996 28.7998c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM162.4 173.2c2.7998 3.7002 8.39941 3.7002 11.1992 0c11.4004 -15.2998 36.4004 -50.6006 36.4004 -68.1006
c0 -22.6992 -18.7998 -41.0996 -42 -41.0996s-42 18.4004 -42 41.0996c0 17.5 25 52.8008 36.4004 68.1006z" />
<glyph glyph-name="smile-beam" unicode="&#xf5b8;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM332 135.4c8.5 10.1992 23.5996 11.5 33.7998 3.09961
c10.2002 -8.5 11.6006 -23.5996 3.10059 -33.7998c-30 -36 -74.1006 -56.6006 -120.9 -56.6006s-90.9004 20.6006 -120.9 56.6006c-8.39941 10.2002 -7.09961 25.2998 3.10059 33.7998c10.2002 8.40039 25.2998 7.09961 33.7998 -3.09961
c20.7998 -25.1006 51.5 -39.4004 84 -39.4004s63.2002 14.4004 84 39.4004zM136.5 237l-9.5 -17c-1.90039 -3.2002 -5.90039 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996zM328 296c23.7998 0 52.7002 -29.2998 56 -71.4004
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002
c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004z" />
<glyph glyph-name="surprise" unicode="&#xf5c2;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM248 168c35.2998 0 64 -28.7002 64 -64s-28.7002 -64 -64 -64
s-64 28.7002 -64 64s28.7002 64 64 64zM200 240c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
<glyph glyph-name="tired" unicode="&#xf5c8;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM377.1 295.8c3.80078 -4.39941 3.90039 -11 0.100586 -15.5
l-33.6006 -40.2998l33.6006 -40.2998c3.7998 -4.5 3.7002 -11 -0.100586 -15.5c-3.5 -4.10059 -9.89941 -5.7002 -15.2998 -2.5l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5 2.90039 11.5 1.90039 15.2998 -2.5z
M220 240c0 -4.2002 -2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7998 -1.60059 -15.2998 2.5c-3.80078 4.5 -3.90039 11 -0.100586 15.5l33.6006 40.2998l-33.6006 40.2998c-3.7998 4.5 -3.7002 11 0.100586 15.5
c3.7998 4.40039 10.2998 5.5 15.2998 2.5l80 -48c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998zM248 176c45.4004 0 100.9 -38.2998 107.8 -93.2998c1.5 -11.9004 -7 -21.6006 -15.5 -17.9004c-22.7002 9.7002 -56.2998 15.2002 -92.2998 15.2002
s-69.5996 -5.5 -92.2998 -15.2002c-8.60059 -3.7002 -17 6.10059 -15.5 17.9004c6.89941 55 62.3994 93.2998 107.8 93.2998z" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 141 KiB

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.ttf

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.woff

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-regular-400.woff2

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.eot

Binary file not shown.

4649
gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.svg

File diff suppressed because it is too large

After

Width:  |  Height:  |  Size: 820 KiB

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.ttf

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.woff

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/fa-solid-900.woff2

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/glyphicons-halflings-regular.448c34a.woff2

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/glyphicons-halflings-regular.e18bbf6.ttf

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/glyphicons-halflings-regular.f4769f9.eot

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/glyphicons-halflings-regular.fa27723.woff

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.eot

Binary file not shown.

308
gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.svg

@ -0,0 +1,308 @@
<?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">
<defs >
<font id="Roboto" horiz-adv-x="1158" ><font-face
font-family="Roboto"
units-per-em="2048"
panose-1="2 0 0 0 0 0 0 0 0 0"
ascent="1900"
descent="-500"
alphabetic="0" />
<glyph unicode=" " horiz-adv-x="507" />
<glyph unicode="!" horiz-adv-x="527" d="M347 411H180L167 1456H361L347 411ZM160 93Q160 138 187 168T269 199T351 169T379 93T351 19T269 -11T188 18T160 93Z" />
<glyph unicode="&quot;" horiz-adv-x="655" d="M277 1400L247 1042H136L137 1536H277V1400ZM547 1400L517 1042H406L407 1536H547V1400Z" />
<glyph unicode="#" horiz-adv-x="1261" d="M765 410H501L421 0H278L358 410H119V547H384L453 901H195V1040H480L562 1456H705L623 1040H887L969 1456H1113L1031 1040H1235V901H1004L935 547H1160V410H909L829 0H685L765 410ZM527 547H791L860 901H596L527 547Z" />
<glyph unicode="$" horiz-adv-x="1150" d="M856 375Q856 467 792 530T574 644Q361 709 264 813T166 1079Q166 1243 261 1348T524 1473V1692H673V1472Q841 1449 934 1331T1028 1008H844Q844 1149 777 1232T596 1315Q477 1315 414 1254T351 1082Q351 980 417 920T636
810T874 701T1000 562T1041 377Q1041 208 940 105T655 -17V-208H507V-17Q321 0 216 115T110 429H295Q295 290 368 215T575 140Q706 140 781 203T856 375Z" />
<glyph unicode="%" horiz-adv-x="1500" d="M105 1176Q105 1307 188 1392T403 1477Q536 1477 618 1392T701 1170V1099Q701 967 618 884T405 800Q275 800 190 883T105 1106V1176ZM243 1099Q243 1021 287 971T405 920Q476 920 519 969T563 1103V1176Q563 1254 520
1305T403 1356T286 1305T243 1172V1099ZM814 357Q814 488 897 572T1112 657T1327 573T1411 350V279Q1411 148 1328 64T1114 -21T899 62T814 285V357ZM952 279Q952 200 996 150T1114 99Q1186 99 1229 148T1272 283V357Q1272 436 1229 486T1112 536Q1041 536 997
487T952 353V279ZM447 110L342 176L1053 1314L1158 1248L447 110Z" />
<glyph unicode="&amp;" horiz-adv-x="1273" d="M101 391Q101 496 159 584T383 789Q286 907 253 979T220 1122Q220 1288 318 1382T584 1476Q734 1476 832 1389T930 1168Q930 1080 886 1006T730 849L623 770L947 383Q1015 513 1015 672H1182Q1182 417 1059 249L1267
0H1045L948 115Q874 49 775 15T572 -20Q359 -20 230 93T101 391ZM572 131Q719 131 841 243L486 668L453 644Q286 521 286 391Q286 273 362 202T572 131ZM405 1128Q405 1032 523 888L641 971Q709 1019 734 1062T759 1168Q759 1235 709 1279T583 1324Q501 1324 453
1269T405 1128Z" />
<glyph unicode="&apos;" horiz-adv-x="357" d="M253 1425L232 1057H103L104 1536H253V1425Z" />
<glyph unicode="(" horiz-adv-x="700" d="M133 591Q133 817 193 1025T374 1403T623 1643L661 1521Q515 1409 422 1179T319 664L318 579Q318 193 459 -91Q544 -261 661 -357L623 -470Q490 -396 369 -222Q133 118 133 591Z" />
<glyph unicode=")" horiz-adv-x="712" d="M567 581Q567 358 509 154T330 -224T77 -470L38 -357Q192 -239 285 9T381 561V593Q381 803 337 983T215 1307T38 1530L77 1643Q209 1570 328 1399T507 1022T567 581Z" />
<glyph unicode="*" horiz-adv-x="882" d="M330 983L28 1073L74 1224L376 1112L367 1456H520L510 1107L807 1217L853 1065L546 974L744 703L620 609L434 897L254 616L129 707L330 983Z" />
<glyph unicode="+" horiz-adv-x="1161" d="M670 781H1076V606H670V146H484V606H78V781H484V1206H670V781Z" />
<glyph unicode="," horiz-adv-x="402" d="M134 -290L29 -218Q123 -87 127 52V219H308V74Q308 -27 259 -128T134 -290Z" />
<glyph unicode="-" horiz-adv-x="565" d="M525 543H37V694H525V543Z" />
<glyph unicode="." horiz-adv-x="539" d="M144 97Q144 145 172 177T258 209T344 177T374 97Q374 51 345 20T258 -11T173 20T144 97Z" />
<glyph unicode="/" horiz-adv-x="844" d="M177 -125H18L626 1456H784L177 -125Z" />
<glyph unicode="0" horiz-adv-x="1150" d="M1034 621Q1034 296 923 138T576 -20Q343 -20 231 134T115 596V843Q115 1164 226 1320T574 1476Q809 1476 920 1326T1034 861V621ZM849 874Q849 1109 783 1216T574 1324Q432 1324 367 1217T300 888V592Q300 356 368 244T576
131Q713 131 779 237T849 571V874Z" />
<glyph unicode="1" horiz-adv-x="1150" d="M729 0H543V1233L170 1096V1264L700 1463H729V0Z" />
<glyph unicode="2" horiz-adv-x="1150" d="M1075 0H121V133L625 693Q737 820 779 899T822 1064Q822 1178 753 1251T569 1324Q431 1324 355 1246T278 1027H93Q93 1228 222 1352T569 1476Q772 1476 890 1370T1008 1086Q1008 871 734 574L344 151H1075V0Z" />
<glyph unicode="3" horiz-adv-x="1150" d="M390 818H529Q660 820 735 887T810 1068Q810 1324 555 1324Q435 1324 364 1256T292 1074H107Q107 1247 233 1361T555 1476Q761 1476 878 1367T995 1064Q995 969 934 880T766 747Q886 709 951 621T1017 406Q1017 210 889
95T556 -20T223 91T94 384H280Q280 269 355 200T556 131Q690 131 761 201T832 402Q832 529 754 597T529 667H390V818Z" />
<glyph unicode="4" horiz-adv-x="1150" d="M902 489H1104V338H902V0H716V338H53V447L705 1456H902V489ZM263 489H716V1203L694 1163L263 489Z" />
<glyph unicode="5" horiz-adv-x="1150" d="M206 730L280 1456H1026V1285H437L393 888Q500 951 636 951Q835 951 952 820T1069 464Q1069 239 948 110T608 -20Q415 -20 293 87T154 383H329Q346 258 418 195T608 131Q737 131 810 219T884 462Q884 608 805 696T593
785Q472 785 403 732L354 692L206 730Z" />
<glyph unicode="6" horiz-adv-x="1150" d="M847 1457V1300H813Q597 1296 469 1172T321 823Q436 955 635 955Q825 955 938 821T1052 475Q1052 250 930 115T601 -20Q392 -20 262 140T132 554V625Q132 1027 303 1239T814 1457H847ZM604 801Q509 801 429 744T318 601V533Q318
353 399 243T601 133Q726 133 797 225T869 466Q869 616 797 708T604 801Z" />
<glyph unicode="7" horiz-adv-x="1150" d="M1061 1352L458 0H264L865 1304H77V1456H1061V1352Z" />
<glyph unicode="8" horiz-adv-x="1150" d="M1004 1076Q1004 967 947 882T791 749Q905 700 971 606T1038 393Q1038 204 911 92T575 -20Q365 -20 239 92T112 393Q112 511 176 606T355 750Q258 798 202 883T146 1076Q146 1260 264 1368T575 1476Q767 1476 885 1368T1004
1076ZM853 397Q853 519 776 596T573 673T373 597T297 397T370 202T575 131Q705 131 779 202T853 397ZM575 1324Q466 1324 399 1257T331 1073Q331 962 397 894T575 825T752 893T819 1073T750 1254T575 1324Z" />
<glyph unicode="9" horiz-adv-x="1150" d="M830 640Q772 571 692 529T515 487Q389 487 296 549T151 723T100 972Q100 1118 155 1235T313 1414T551 1476Q767 1476 891 1315T1016 874V820Q1016 395 848 200T341 -1H305V155H344Q573 159 696 274T830 640ZM545 640Q638
640 716 697T831 838V912Q831 1094 752 1208T552 1322Q430 1322 356 1229T282 982Q282 833 353 737T545 640Z" />
<glyph unicode=":" horiz-adv-x="496" d="M390 97Q390 145 418 177T504 209T590 177T620 97Q620 51 591 20T504 -11T419 20T390 97ZM135 980Q135 1028 163 1060T249 1092T335 1060T365 980Q365 934 336 903T249 872T164 903T135 980Z" />
<glyph unicode=";" horiz-adv-x="433" d="M111 980Q111 1028 139 1060T225 1092T311 1060T341 980Q341 934 312 903T225 872T140 903T111 980ZM146 -290L41 -218Q135 -87 139 52V219H320V74Q320 -27 271 -128T146 -290Z" />
<glyph unicode="&lt;" horiz-adv-x="1041" d="M264 644L890 391V195L72 574V720L890 1098V902L264 644Z" />
<glyph unicode="=" horiz-adv-x="1124" d="M986 814H152V975H986V814ZM986 399H152V559H986V399Z" />
<glyph unicode="&gt;" horiz-adv-x="1070" d="M795 650L134 909V1099L988 721V575L134 196V388L795 650Z" />
<glyph unicode="?" horiz-adv-x="967" d="M357 410Q359 529 384 598T486 751L617 886Q701 981 701 1090Q701 1195 646 1254T486 1314Q384 1314 322 1260T260 1115H75Q77 1277 190 1376T486 1476Q675 1476 780 1375T886 1096Q886 921 724 751L615 643Q542 562 542
410H357ZM349 93Q349 138 376 168T458 199T540 169T568 93T540 19T458 -11T377 18T349 93Z" />
<glyph unicode="@" horiz-adv-x="1839" d="M1738 502Q1726 260 1618 120T1329 -20Q1142 -20 1089 148Q1035 63 966 22T822 -20Q680 -20 607 96T553 417Q568 582 628 711T784 915T985 989Q1066 989 1130 968T1274 883L1222 329Q1203 98 1350 98Q1463 98 1533 210T1609
502Q1628 891 1465 1095T967 1299Q766 1299 610 1200T364 912T263 478Q251 230 323 48T542 -231T899 -328Q989 -328 1079 -306T1230 -249L1267 -364Q1205 -403 1103 -428T895 -453Q645 -453 465 -341T196 -17T118 478Q130 753 241 972T542 1311T971 1431Q1220 1431
1398 1319T1663 996T1738 502ZM712 417Q698 275 738 199T867 123Q927 123 982 174T1074 320L1075 329L1121 832Q1065 861 1001 861Q884 861 808 742T712 417Z" />
<glyph unicode="A" horiz-adv-x="1336" d="M973 380H363L226 0H28L584 1456H752L1309 0H1112L973 380ZM421 538H916L668 1219L421 538Z" />
<glyph unicode="B" horiz-adv-x="1275" d="M169 0V1456H645Q882 1456 1001 1358T1121 1068Q1121 966 1063 888T905 766Q1023 733 1091 641T1160 420Q1160 224 1033 112T674 0H169ZM361 681V157H678Q812 157 889 226T967 418Q967 681 681 681H361ZM361 835H651Q777
835 852 898T928 1069Q928 1189 858 1243T645 1298H361V835Z" />
<glyph unicode="C" horiz-adv-x="1333" d="M1240 462Q1213 231 1070 106T688 -20Q430 -20 275 165T119 660V800Q119 1003 191 1157T397 1393T705 1476Q937 1476 1077 1347T1240 988H1047Q1022 1162 939 1240T705 1318Q521 1318 417 1182T312 795V654Q312 417 411
277T688 137Q848 137 933 209T1047 462H1240Z" />
<glyph unicode="D" horiz-adv-x="1343" d="M169 0V1456H580Q770 1456 916 1372T1141 1133T1222 777V684Q1222 478 1143 323T916 85T572 0H169ZM361 1298V157H563Q785 157 908 295T1032 688V773Q1032 1021 916 1158T585 1298H361Z" />
<glyph unicode="E" horiz-adv-x="1164" d="M992 673H361V157H1094V0H169V1456H1084V1298H361V830H992V673Z" />
<glyph unicode="F" horiz-adv-x="1132" d="M972 643H361V0H169V1456H1071V1298H361V800H972V643Z" />
<glyph unicode="G" horiz-adv-x="1395" d="M1244 191Q1170 85 1038 33T729 -20Q551 -20 413 63T200 301T122 658V785Q122 1114 275 1295T707 1476Q935 1476 1074 1360T1244 1029H1052Q998 1318 708 1318Q515 1318 416 1183T315 790V671Q315 426 427 282T730 137Q838
137 919 161T1053 242V569H716V725H1244V191Z" />
<glyph unicode="H" horiz-adv-x="1460" d="M1288 0H1095V673H361V0H169V1456H361V830H1095V1456H1288V0Z" />
<glyph unicode="I" horiz-adv-x="557" d="M375 0H183V1456H375V0Z" />
<glyph unicode="J" horiz-adv-x="1130" d="M779 1456H972V425Q972 216 847 98T512 -20Q295 -20 174 91T53 402H245Q245 277 313 207T512 137Q631 137 704 212T779 422V1456Z" />
<glyph unicode="K" horiz-adv-x="1284" d="M539 677L361 492V0H169V1456H361V736L1008 1456H1240L667 813L1285 0H1055L539 677Z" />
<glyph unicode="L" horiz-adv-x="1102" d="M362 157H1052V0H169V1456H362V157Z" />
<glyph unicode="M" horiz-adv-x="1788" d="M417 1456L893 268L1369 1456H1618V0H1426V567L1444 1179L966 0H819L342 1176L361 567V0H169V1456H417Z" />
<glyph unicode="N" horiz-adv-x="1460" d="M1288 0H1095L362 1122V0H169V1456H362L1097 329V1456H1288V0Z" />
<glyph unicode="O" horiz-adv-x="1408" d="M1289 681Q1289 467 1217 308T1013 64T705 -20Q533 -20 400 64T194 305T118 668V773Q118 983 191 1144T397 1390T703 1476Q878 1476 1011 1392T1217 1147T1289 773V681ZM1098 775Q1098 1034 994 1172T703 1311Q521 1311
417 1173T309 788V681Q309 430 414 287T705 143Q891 143 993 278T1098 667V775Z" />
<glyph unicode="P" horiz-adv-x="1292" d="M361 570V0H169V1456H706Q945 1456 1080 1334T1216 1011Q1216 799 1084 685T704 570H361ZM361 727H706Q860 727 942 799T1024 1009Q1024 1139 942 1217T717 1298H361V727Z" />
<glyph unicode="Q" horiz-adv-x="1408" d="M1281 681Q1281 470 1214 318T1026 79L1286 -125L1155 -246L848 -2Q776 -20 696 -20Q524 -20 391 64T185 305T109 668V773Q109 983 182 1144T388 1390T694 1476Q870 1476 1003 1391T1209 1147T1281 774V681ZM1089 775Q1089
1032 987 1171T694 1311Q513 1311 409 1173T301 788V681Q301 431 405 287T696 143T984 278T1089 667V775Z" />
<glyph unicode="R" horiz-adv-x="1261" d="M703 589H361V0H168V1456H650Q896 1456 1028 1344T1161 1018Q1161 882 1088 781T883 630L1225 12V0H1019L703 589ZM361 746H656Q799 746 883 820T968 1018Q968 1153 888 1225T655 1298H361V746Z" />
<glyph unicode="S" horiz-adv-x="1215" d="M598 649Q351 720 239 823T126 1079Q126 1251 263 1363T621 1476Q771 1476 888 1418T1070 1258T1135 1035H942Q942 1167 858 1242T621 1318Q479 1318 400 1256T320 1082Q320 993 395 932T652 819T936 707T1088 563T1138
370Q1138 193 1000 87T631 -20Q481 -20 351 37T151 195T80 422H273Q273 290 370 214T631 137Q783 137 864 199T945 368T870 533T598 649Z" />
<glyph unicode="T" horiz-adv-x="1222" d="M1175 1298H707V0H516V1298H49V1456H1175V1298Z" />
<glyph unicode="U" horiz-adv-x="1328" d="M1194 1456V466Q1193 260 1065 129T716 -18L665 -20Q426 -20 284 109T140 464V1456H330V470Q330 312 417 225T665 137Q828 137 914 224T1001 469V1456H1194Z" />
<glyph unicode="V" horiz-adv-x="1303" d="M651 255L1067 1456H1277L737 0H567L28 1456H237L651 255Z" />
<glyph unicode="W" horiz-adv-x="1817" d="M483 459L511 267L552 440L840 1456H1002L1283 440L1323 264L1354 460L1580 1456H1773L1420 0H1245L945 1061L922 1172L899 1061L588 0H413L61 1456H253L483 459Z" />
<glyph unicode="X" horiz-adv-x="1284" d="M644 898L993 1456H1219L759 734L1230 0H1002L644 568L284 0H57L529 734L68 1456H293L644 898Z" />
<glyph unicode="Y" horiz-adv-x="1230" d="M613 725L993 1456H1211L709 543V0H517V543L15 1456H235L613 725Z" />
<glyph unicode="Z" horiz-adv-x="1226" d="M313 157H1146V0H86V144L884 1298H99V1456H1114V1315L313 157Z" />
<glyph unicode="[" horiz-adv-x="543" d="M523 1512H332V-160H523V-312H146V1664H523V1512Z" />
<glyph unicode="\" horiz-adv-x="840" d="M40 1456H216L824 -125H648L40 1456Z" />
<glyph unicode="]" horiz-adv-x="543" d="M9 1664H387V-312H9V-160H202V1512H9V1664Z" />
<glyph unicode="^" horiz-adv-x="856" d="M426 1211L236 729H64L363 1456H490L788 729H617L426 1211Z" />
<glyph unicode="_" horiz-adv-x="924" d="M920 -151H4V0H920V-151Z" />
<glyph unicode="`" horiz-adv-x="633" d="M474 1242H315L57 1536H280L474 1242Z" />
<glyph unicode="a" horiz-adv-x="1114" d="M808 0Q792 32 782 114Q653 -20 474 -20Q314 -20 212 70T109 300Q109 469 237 562T599 656H779V741Q779 838 721 895T550 953Q451 953 384 903T317 782H131Q131 863 188 938T344 1058T561 1102Q748 1102 854 1009T964
751V253Q964 104 1002 16V0H808ZM501 141Q588 141 666 186T779 303V525H634Q294 525 294 326Q294 239 352 190T501 141Z" />
<glyph unicode="b" horiz-adv-x="1149" d="M1056 529Q1056 281 942 131T636 -20Q431 -20 319 125L310 0H140V1536H325V963Q437 1102 634 1102T943 953T1056 545V529ZM871 550Q871 739 798 842T588 945Q405 945 325 775V307Q410 137 590 137Q723 137 797 240T871 550Z" />
<glyph unicode="c" horiz-adv-x="1072" d="M574 131Q673 131 747 191T829 341H1004Q999 248 940 164T783 30T574 -20Q353 -20 223 127T92 531V562Q92 720 150 843T316 1034T573 1102Q755 1102 875 993T1004 710H829Q821 815 750 882T573 950Q432 950 355 849T277
555V520Q277 333 354 232T574 131Z" />
<glyph unicode="d" horiz-adv-x="1155" d="M95 550Q95 799 213 950T522 1102Q712 1102 823 972V1536H1008V0H838L829 116Q718 -20 520 -20Q332 -20 214 134T95 536V550ZM280 529Q280 345 356 241T566 137Q742 137 823 295V792Q740 945 568 945Q432 945 356 840T280 529Z" />
<glyph unicode="e" horiz-adv-x="1085" d="M589 -20Q369 -20 231 124T93 511V545Q93 706 154 832T326 1030T566 1102Q777 1102 894 963T1011 565V488H278Q282 328 371 230T599 131Q697 131 765 171T884 277L997 189Q861 -20 589 -20ZM566 950Q454 950 378 869T284
640H826V654Q818 795 750 872T566 950Z" />
<glyph unicode="f" horiz-adv-x="711" d="M231 0V939H60V1082H231V1193Q231 1367 324 1462T587 1557Q651 1557 714 1540L704 1390Q657 1399 604 1399Q514 1399 465 1347T416 1196V1082H647V939H416V0H231Z" />
<glyph unicode="g" horiz-adv-x="1149" d="M96 550Q96 803 213 952T523 1102Q721 1102 832 962L841 1082H1010V26Q1010 -184 886 -305T551 -426Q434 -426 322 -376T151 -239L247 -128Q366 -275 538 -275Q673 -275 748 -199T824 15V108Q713 -20 521 -20Q331 -20
214 133T96 550ZM282 529Q282 346 357 242T567 137Q742 137 824 296V790Q739 945 569 945Q434 945 358 840T282 529Z" />
<glyph unicode="h" horiz-adv-x="1128" d="M325 951Q448 1102 645 1102Q988 1102 991 715V0H806V716Q805 833 753 889T589 945Q499 945 431 897T325 771V0H140V1536H325V951Z" />
<glyph unicode="i" horiz-adv-x="497" d="M341 0H156V1082H341V0ZM141 1369Q141 1414 168 1445T250 1476T332 1445T360 1369T332 1294T250 1264T169 1294T141 1369Z" />
<glyph unicode="j" horiz-adv-x="489" d="M331 1082V-125Q331 -437 48 -437Q-13 -437 -65 -419V-271Q-33 -279 19 -279Q81 -279 113 -246T146 -129V1082H331ZM127 1369Q127 1413 154 1444T235 1476Q289 1476 317 1445T345 1369T317 1294T235 1264T154 1294T127 1369Z" />
<glyph unicode="k" horiz-adv-x="1038" d="M442 501L326 380V0H141V1536H326V607L425 726L762 1082H987L566 630L1036 0H819L442 501Z" />
<glyph unicode="l" horiz-adv-x="497" d="M341 0H156V1536H341V0Z" />
<glyph unicode="m" horiz-adv-x="1795" d="M314 1082L319 962Q438 1102 640 1102Q867 1102 949 928Q1003 1006 1089 1054T1294 1102Q1650 1102 1656 725V0H1471V714Q1471 830 1418 887T1240 945Q1137 945 1069 884T990 718V0H804V709Q804 945 573 945Q391 945
324 790V0H139V1082H314Z" />
<glyph unicode="n" horiz-adv-x="1130" d="M315 1082L321 946Q445 1102 645 1102Q988 1102 991 715V0H806V716Q805 833 753 889T589 945Q499 945 431 897T325 771V0H140V1082H315Z" />
<glyph unicode="o" horiz-adv-x="1168" d="M91 551Q91 710 153 837T327 1033T582 1102Q803 1102 939 949T1076 542V529Q1076 371 1016 246T843 50T584 -20Q364 -20 228 133T91 538V551ZM277 529Q277 349 360 240T584 131Q725 131 808 241T891 551Q891 729 807
839T582 950Q445 950 361 841T277 529Z" />
<glyph unicode="p" horiz-adv-x="1149" d="M1054 529Q1054 282 941 131T635 -20Q438 -20 325 105V-416H140V1082H309L318 962Q431 1102 632 1102Q827 1102 940 955T1054 546V529ZM869 550Q869 733 791 839T577 945Q409 945 325 796V279Q408 131 579 131Q712 131
790 236T869 550Z" />
<glyph unicode="q" horiz-adv-x="1164" d="M95 550Q95 805 212 953T526 1102Q718 1102 829 973L837 1082H1007V-416H822V100Q710 -20 524 -20Q328 -20 212 132T95 537V550ZM280 529Q280 343 358 237T570 131Q735 131 822 277V807Q734 950 572 950Q438 950 359
844T280 529Z" />
<glyph unicode="r" horiz-adv-x="693" d="M663 916Q621 923 572 923Q390 923 325 768V0H140V1082H320L323 957Q414 1102 581 1102Q635 1102 663 1088V916Z" />
<glyph unicode="s" horiz-adv-x="1056" d="M770 287Q770 362 714 403T517 475T294 547T172 647T132 785Q132 918 244 1010T532 1102Q716 1102 830 1007T945 764H759Q759 840 695 895T532 950Q431 950 374 906T317 791Q317 724 370 690T561 625T786 551T913 448T955
300Q955 155 839 68T538 -20Q408 -20 308 26T152 154T95 333H280Q285 240 354 186T538 131Q643 131 706 173T770 287Z" />
<glyph unicode="t" horiz-adv-x="669" d="M391 1344V1082H593V939H391V268Q391 203 418 171T510 138Q542 138 598 150V0Q525 -20 456 -20Q332 -20 269 55T206 268V939H9V1082H206V1344H391Z" />
<glyph unicode="u" horiz-adv-x="1129" d="M808 107Q700 -20 491 -20Q318 -20 228 80T136 378V1082H321V383Q321 137 521 137Q733 137 803 295V1082H988V0H812L808 107Z" />
<glyph unicode="v" horiz-adv-x="992" d="M497 251L765 1082H954L566 0H425L33 1082H222L497 251Z" />
<glyph unicode="w" horiz-adv-x="1539" d="M1098 255L1306 1082H1491L1176 0H1026L763 820L507 0H357L43 1082H227L440 272L692 1082H841L1098 255Z" />
<glyph unicode="x" horiz-adv-x="1015" d="M503 687L743 1082H959L605 547L970 0H756L506 405L256 0H41L406 547L52 1082H266L503 687Z" />
<glyph unicode="y" horiz-adv-x="969" d="M494 271L746 1082H944L509 -167Q408 -437 188 -437L153 -434L84 -421V-271L134 -275Q228 -275 280 -237T367 -98L408 12L22 1082H224L494 271Z" />
<glyph unicode="z" horiz-adv-x="1015" d="M314 151H947V0H88V136L685 929H97V1082H917V951L314 151Z" />
<glyph unicode="{" horiz-adv-x="693" d="M632 -366Q455 -316 366 -202T276 101V300Q276 543 64 543V688Q276 688 276 930V1138Q278 1321 365 1433T632 1597L670 1482Q461 1415 461 1133V931Q461 704 294 615Q461 525 461 296V90Q464 -185 670 -251L632 -366Z" />
<glyph unicode="|" horiz-adv-x="499" d="M324 -270H175V1456H324V-270Z" />
<glyph unicode="}" horiz-adv-x="693" d="M19 -251Q222 -186 229 80V300Q229 531 410 615Q229 697 229 930V1133Q229 1415 20 1482L58 1597Q235 1547 324 1435T414 1137V927Q414 688 626 688V543Q414 543 414 300V98Q414 -90 324 -203T58 -366L19 -251Z" />
<glyph unicode="~" horiz-adv-x="1393" d="M1263 777Q1263 619 1170 511T939 402Q867 402 803 428T655 529T533 621T454 639Q376 639 334 586T292 438L131 436Q131 596 223 699T454 802Q530 802 600 770T758 658T910 567L939 565Q1015 565 1062 623T1110 776L1263 777Z" />
<glyph unicode="&#xa0;" horiz-adv-x="507" />
<glyph unicode="&#xa1;" horiz-adv-x="499" d="M170 684H338L351 -360H157L170 684ZM358 996Q358 951 331 920T249 889T167 920T139 996T167 1071T249 1101T330 1071T358 996Z" />
<glyph unicode="&#xa2;" horiz-adv-x="1120" d="M586 131Q686 131 760 191T842 341H1017Q1011 215 912 115T669 -12V-245H484V-11Q305 23 205 165T105 527V562Q105 774 206 916T484 1092V1318H669V1095Q819 1072 915 966T1017 710H842Q834 815 763 882T586 950Q445
950 368 849T290 555V520Q290 333 367 232T586 131Z" />
<glyph unicode="&#xa3;" horiz-adv-x="1190" d="M449 622L457 402Q457 248 395 157H1128L1127 0H95V157H172Q212 166 237 231T264 393V401L256 622H91V779H251L242 1039Q242 1238 364 1357T687 1476Q877 1476 988 1370T1099 1087H908Q908 1194 845 1256T670 1318Q565
1318 500 1241T435 1039L444 779H763V622H449Z" />
<glyph unicode="&#xa4;" horiz-adv-x="1460" d="M1103 112Q944 -20 735 -20Q528 -20 369 110L235 -26L105 109L244 250Q140 406 140 608Q140 814 252 977L105 1128L235 1264L382 1114Q540 1234 735 1234Q931 1234 1090 1113L1239 1265L1371 1128L1220 974Q1330
811 1330 608Q1330 412 1228 253L1371 109L1239 -27L1103 112ZM311 608Q311 485 368 379T524 212T735 151T946 212T1100 379T1157 608Q1157 730 1101 835T946 1001T735 1062Q622 1062 524 1002T369 836T311 608Z" />
<glyph unicode="&#xa5;" horiz-adv-x="1075" d="M539 793L847 1456H1060L693 736H954V611H630V446H954V322H630V0H437V322H119V446H437V611H119V736H382L15 1456H231L539 793Z" />
<glyph unicode="&#xa6;" horiz-adv-x="491" d="M147 -270V521H333V-270H147ZM333 698H147V1456H333V698Z" />
<glyph unicode="&#xa7;" horiz-adv-x="1256" d="M1145 431Q1145 242 959 157Q1028 108 1064 40T1100 -128Q1100 -296 970 -395T612 -495Q500 -495 400 -467T229 -382Q90 -269 90 -64L276 -62Q276 -192 366 -267T612 -343Q748 -343 831 -285T914 -130Q914 -41 843
11T563 126Q381 174 285 229T143 362T96 551Q96 737 278 825Q212 874 177 942T141 1110Q141 1276 274 1376T630 1476Q862 1476 992 1363T1122 1045H937Q937 1170 853 1247T630 1325Q488 1325 408 1268T327 1112Q327 1043 355 1003T450 931T661 858T889 782T1030
698T1116 585T1145 431ZM602 691Q512 715 437 742Q357 723 320 673T282 553Q282 483 309 443T402 370T611 296T797 238Q875 258 917 308T959 428Q959 516 890 570T602 691Z" />
<glyph unicode="&#xa8;" horiz-adv-x="856" d="M101 1371Q101 1416 128 1446T210 1477T292 1447T320 1371T292 1296T210 1266T129 1296T101 1371ZM531 1369Q531 1414 558 1445T640 1476T722 1445T750 1369T722 1294T640 1264T559 1294T531 1369Z" />
<glyph unicode="&#xa9;" horiz-adv-x="1609" d="M1119 597Q1119 444 1033 364T788 283Q631 283 537 388T442 676V786Q442 962 537 1067T788 1173Q948 1173 1034 1091T1120 860H974Q974 959 927 1001T788 1044Q694 1044 640 975T586 783V670Q586 550 640 481T788
412Q880 412 926 454T973 597H1119ZM206 729Q206 557 286 411T503 181T801 98T1098 181T1315 410T1395 729Q1395 899 1316 1044T1100 1272T801 1356Q641 1356 503 1274T286 1045T206 729ZM91 729Q91 931 184 1104T443 1376T801 1476T1158 1377T1416 1104T1510 729Q1510
532 1420 360T1165 84T801 -21Q604 -21 439 82T182 358T91 729Z" />
<glyph unicode="&#xaa;" horiz-adv-x="915" d="M618 705Q606 739 600 777Q524 691 396 691Q277 691 212 753T147 918Q147 1029 230 1089T486 1149H594V1201Q594 1336 470 1336Q401 1336 362 1309T322 1231L161 1243Q161 1346 247 1411T470 1476Q603 1476 680 1405T757
1199V883Q757 786 783 705H618ZM435 828Q478 828 522 848T594 895V1037H482Q399 1036 355 1005T310 922Q310 828 435 828Z" />
<glyph unicode="&#xab;" horiz-adv-x="961" d="M536 804L794 407H653L358 795V814L653 1203H794L536 804ZM610 548L868 151H727L432 539V558L727 947H868L610 548Z" />
<glyph unicode="&#xac;" horiz-adv-x="1134" d="M958 375H772V639H127V800H958V375Z" />
<glyph unicode="&#xad;" horiz-adv-x="565" d="M525 543H37V694H525V543Z" />
<glyph unicode="&#xae;" horiz-adv-x="1610" d="M90 729Q90 931 183 1104T442 1376T800 1476T1157 1377T1415 1104T1509 729Q1509 532 1419 360T1164 84T800 -21Q603 -21 438 82T181 358T90 729ZM205 729Q205 557 285 411T502 181T800 98Q961 98 1099 182T1315
412T1394 729Q1394 900 1316 1044T1099 1272T800 1356Q640 1356 502 1274T285 1045T205 729ZM653 654V316H512V1165H788Q941 1165 1025 1100T1110 909Q1110 786 982 721Q1104 671 1105 517V456Q1105 370 1122 332V316H977Q963 352 963 444T960 554Q944 650 829
654H653ZM653 782H809Q881 784 925 817T969 904Q969 977 930 1007T791 1038H653V782Z" />
<glyph unicode="&#xaf;" horiz-adv-x="938" d="M814 1302H142V1445H814V1302Z" />
<glyph unicode="&#xb0;" horiz-adv-x="765" d="M130 1216Q130 1320 204 1398T385 1476Q489 1476 562 1399T636 1216Q636 1110 563 1035T385 960Q280 960 205 1035T130 1216ZM385 1088Q439 1088 476 1123T513 1216Q513 1274 476 1311T385 1349Q330 1349 293 1310T255
1216T292 1125T385 1088Z" />
<glyph unicode="&#xb1;" horiz-adv-x="1094" d="M649 854H1013V703H649V289H482V703H97V854H482V1267H649V854ZM970 0H135V152H970V0Z" />
<glyph unicode="&#xb2;" horiz-adv-x="751" d="M683 667H84V775L384 1057Q493 1159 493 1228Q493 1277 461 1307T369 1338Q294 1338 259 1300T223 1205H66Q66 1319 149 1393T365 1467T574 1404T651 1230Q651 1126 544 1019L460 940L284 795H683V667Z" />
<glyph unicode="&#xb3;" horiz-adv-x="751" d="M265 1126H349Q423 1126 459 1156T495 1235Q495 1280 464 1309T362 1338Q305 1338 268 1313T230 1246H73Q73 1344 154 1405T360 1467Q497 1467 575 1407T653 1242Q653 1187 618 1142T517 1071Q666 1030 666 887Q666
781 581 719T360 656Q228 656 145 719T62 889H220Q220 844 259 814T366 784Q436 784 472 814T509 895Q509 1008 353 1010H265V1126Z" />
<glyph unicode="&#xb4;" horiz-adv-x="642" d="M316 1536H540L272 1242H123L316 1536Z" />
<glyph unicode="&#xb5;" horiz-adv-x="1160" d="M339 1082V449Q340 286 391 208T559 130Q758 130 820 282V1082H1006V0H839L830 115Q737 -20 567 -20Q420 -20 339 53V-416H154V1082H339Z" />
<glyph unicode="&#xb6;" horiz-adv-x="1001" d="M646 0V520H562Q332 520 200 647T67 988Q67 1201 200 1328T563 1456H832V0H646Z" />
<glyph unicode="&#xb7;" horiz-adv-x="534" d="M147 729Q147 777 175 809T261 841T347 809T377 729Q377 682 348 651T261 619T176 650T147 729Z" />
<glyph unicode="&#xb8;" horiz-adv-x="507" d="M285 0L273 -52Q426 -79 426 -225Q426 -322 346 -378T123 -435L116 -328Q195 -328 238 -302T282 -229Q282 -185 250 -164T120 -134L152 0H285Z" />
<glyph unicode="&#xb9;" horiz-adv-x="751" d="M495 667H338V1268L122 1211V1339L477 1456H495V667Z" />
<glyph unicode="&#xba;" horiz-adv-x="931" d="M122 1123Q122 1281 216 1378T464 1476Q619 1476 713 1380T807 1117V1043Q807 884 714 787T466 690T217 787T122 1049V1123ZM285 1043Q285 943 333 886T466 829Q549 829 596 886T644 1045V1123Q644 1222 596 1279T464
1336Q383 1336 335 1281T285 1129V1043Z" />
<glyph unicode="&#xbb;" horiz-adv-x="960" d="M244 949L539 560V541L244 152H102L360 550L102 949H244ZM593 949L888 560V541L593 152H451L709 550L451 949H593Z" />
<glyph unicode="&#xbc;" horiz-adv-x="1500" d="M458 664H301V1265L85 1208V1336L440 1453H458V664ZM443 118L339 184L1050 1322L1154 1256L443 118ZM1318 299H1425V169H1318V0H1161V169H786L780 271L1157 789H1318V299ZM938 299H1161V588L1144 560L938 299Z" />
<glyph unicode="&#xbd;" horiz-adv-x="1589" d="M399 118L295 184L1006 1322L1110 1256L399 118ZM453 664H296V1265L80 1208V1336L435 1453H453V664ZM1481 0H882V108L1182 390Q1291 492 1291 561Q1291 610 1259 640T1167 671Q1092 671 1057 633T1021 538H864Q864
652 947 726T1163 800T1372 737T1449 563Q1449 459 1342 352L1258 273L1082 128H1481V0Z" />
<glyph unicode="&#xbe;" horiz-adv-x="1593" d="M570 118L466 184L1177 1322L1281 1256L570 118ZM1410 299H1517V169H1410V0H1253V169H878L872 271L1249 789H1410V299ZM1030 299H1253V588L1236 560L1030 299ZM314 1126H398Q472 1126 508 1156T544 1235Q544 1280
513 1309T411 1338Q354 1338 317 1313T279 1246H122Q122 1344 203 1405T409 1467Q546 1467 624 1407T702 1242Q702 1187 667 1142T566 1071Q715 1030 715 887Q715 781 630 719T409 656Q277 656 194 719T111 889H269Q269 844 308 814T415 784Q485 784 521 814T558
895Q558 1008 402 1010H314V1126Z" />
<glyph unicode="&#xbf;" horiz-adv-x="969" d="M588 680Q587 574 567 511T498 388T358 233T255 37L253 0Q253 -109 311 -166T478 -224Q578 -224 640 -168T703 -20H888Q886 -181 774 -283T478 -385Q282 -385 175 -285T68 -5Q68 168 228 343L337 456Q403 534 403
680H588ZM596 997Q596 952 569 921T487 890T405 921T377 997Q377 1041 405 1071T487 1101T568 1071T596 997Z" />
<glyph unicode="&#xc0;" horiz-adv-x="1336" d="M973 380H363L226 0H28L584 1456H752L1309 0H1112L973 380ZM421 538H916L668 1219L421 538ZM778 1552H619L361 1846H584L778 1552Z" />
<glyph unicode="&#xc1;" horiz-adv-x="1336" d="M973 380H363L226 0H28L584 1456H752L1309 0H1112L973 380ZM421 538H916L668 1219L421 538ZM763 1846H987L719 1552H570L763 1846Z" />
<glyph unicode="&#xc2;" horiz-adv-x="1336" d="M973 380H363L226 0H28L584 1456H752L1309 0H1112L973 380ZM421 538H916L668 1219L421 538ZM975 1572V1562H822L672 1732L523 1562H370V1574L616 1846H728L975 1572Z" />
<glyph unicode="&#xc3;" horiz-adv-x="1336" d="M973 380H363L226 0H28L584 1456H752L1309 0H1112L973 380ZM421 538H916L668 1219L421 538ZM1027 1814Q1027 1706 966 1639T812 1572Q771 1572 741 1582T663 1623T593 1660T543 1667Q502 1667 473 1636T444 1555L320
1562Q320 1669 380 1739T534 1809Q569 1809 597 1799T673 1760T746 1722T803 1713Q846 1713 874 1747T903 1826L1027 1814Z" />
<glyph unicode="&#xc4;" horiz-adv-x="1336" d="M973 380H363L226 0H28L584 1456H752L1309 0H1112L973 380ZM421 538H916L668 1219L421 538ZM350 1681Q350 1726 377 1756T459 1787T541 1757T569 1681T541 1606T459 1576T378 1606T350 1681ZM780 1679Q780 1724
807 1755T889 1786T971 1755T999 1679T971 1604T889 1574T808 1604T780 1679Z" />
<glyph unicode="&#xc5;" horiz-adv-x="1336" d="M973 380H363L226 0H28L584 1456H752L1309 0H1112L973 380ZM421 538H916L668 1219L421 538ZM887 1729Q887 1642 825 1584T672 1525Q580 1525 519 1584T457 1729T518 1876T672 1937T825 1876T887 1729ZM556 1729Q556
1682 589 1648T672 1614Q720 1614 754 1647T788 1729T755 1812T672 1847Q622 1847 589 1812T556 1729Z" />
<glyph unicode="&#xc6;" horiz-adv-x="1914" d="M1879 0H996L981 353H417L212 0H-14L866 1456H1817V1304H1126L1146 833H1736V682H1152L1174 151H1879V0ZM518 527H974L943 1260L518 527Z" />
<glyph unicode="&#xc7;" horiz-adv-x="1333" d="M1240 462Q1213 231 1070 106T688 -20Q430 -20 275 165T119 660V800Q119 1003 191 1157T397 1393T705 1476Q937 1476 1077 1347T1240 988H1047Q1022 1162 939 1240T705 1318Q521 1318 417 1182T312 795V654Q312
417 411 277T688 137Q848 137 933 209T1047 462H1240ZM751 -9L739 -61Q892 -88 892 -234Q892 -331 812 -387T589 -444L582 -337Q661 -337 704 -311T748 -238Q748 -194 716 -173T586 -143L618 -9H751Z" />
<glyph unicode="&#xc8;" horiz-adv-x="1164" d="M992 673H361V157H1094V0H169V1456H1084V1298H361V830H992V673ZM725 1564H566L308 1858H531L725 1564Z" />
<glyph unicode="&#xc9;" horiz-adv-x="1164" d="M992 673H361V157H1094V0H169V1456H1084V1298H361V830H992V673ZM710 1858H934L666 1564H517L710 1858Z" />
<glyph unicode="&#xca;" horiz-adv-x="1164" d="M992 673H361V157H1094V0H169V1456H1084V1298H361V830H992V673ZM922 1584V1574H769L619 1744L470 1574H317V1586L563 1858H675L922 1584Z" />
<glyph unicode="&#xcb;" horiz-adv-x="1164" d="M992 673H361V157H1094V0H169V1456H1084V1298H361V830H992V673ZM297 1693Q297 1738 324 1768T406 1799T488 1769T516 1693T488 1618T406 1588T325 1618T297 1693ZM727 1691Q727 1736 754 1767T836 1798T918 1767T946
1691T918 1616T836 1586T755 1616T727 1691Z" />
<glyph unicode="&#xcc;" horiz-adv-x="557" d="M375 0H183V1456H375V0ZM385 1564H226L-32 1858H191L385 1564Z" />
<glyph unicode="&#xcd;" horiz-adv-x="557" d="M375 0H183V1456H375V0ZM369 1858H593L325 1564H176L369 1858Z" />
<glyph unicode="&#xce;" horiz-adv-x="557" d="M375 0H183V1456H375V0ZM582 1584V1574H429L279 1744L130 1574H-23V1586L223 1858H335L582 1584Z" />
<glyph unicode="&#xcf;" horiz-adv-x="557" d="M375 0H183V1456H375V0ZM-43 1693Q-43 1738 -16 1768T66 1799T148 1769T176 1693T148 1618T66 1588T-15 1618T-43 1693ZM387 1691Q387 1736 414 1767T496 1798T578 1767T606 1691T578 1616T496 1586T415 1616T387 1691Z" />
<glyph unicode="&#xd0;" horiz-adv-x="1373" d="M199 0V666H7V817H199V1456H610Q800 1456 946 1372T1171 1133T1252 777V684Q1252 478 1173 323T946 85T602 0H199ZM643 666H391V157H592Q814 157 937 294T1062 680V773Q1062 1021 946 1158T615 1298H391V817H643V666Z" />
<glyph unicode="&#xd1;" horiz-adv-x="1460" d="M1288 0H1095L362 1122V0H169V1456H362L1097 329V1456H1288V0ZM1081 1814Q1081 1706 1020 1639T866 1572Q825 1572 795 1582T717 1623T647 1660T597 1667Q556 1667 527 1636T498 1555L374 1562Q374 1669 434 1739T588
1809Q623 1809 651 1799T727 1760T800 1722T857 1713Q900 1713 928 1747T957 1826L1081 1814Z" />
<glyph unicode="&#xd2;" horiz-adv-x="1408" d="M1289 681Q1289 467 1217 308T1013 64T705 -20Q533 -20 400 64T194 305T118 668V773Q118 983 191 1144T397 1390T703 1476Q878 1476 1011 1392T1217 1147T1289 773V681ZM1098 775Q1098 1034 994 1172T703 1311Q521
1311 417 1173T309 788V681Q309 430 414 287T705 143Q891 143 993 278T1098 667V775ZM812 1554H653L395 1848H618L812 1554Z" />
<glyph unicode="&#xd3;" horiz-adv-x="1408" d="M1289 681Q1289 467 1217 308T1013 64T705 -20Q533 -20 400 64T194 305T118 668V773Q118 983 191 1144T397 1390T703 1476Q878 1476 1011 1392T1217 1147T1289 773V681ZM1098 775Q1098 1034 994 1172T703 1311Q521
1311 417 1173T309 788V681Q309 430 414 287T705 143Q891 143 993 278T1098 667V775ZM797 1848H1021L753 1554H604L797 1848Z" />
<glyph unicode="&#xd4;" horiz-adv-x="1408" d="M1289 681Q1289 467 1217 308T1013 64T705 -20Q533 -20 400 64T194 305T118 668V773Q118 983 191 1144T397 1390T703 1476Q878 1476 1011 1392T1217 1147T1289 773V681ZM1098 775Q1098 1034 994 1172T703 1311Q521
1311 417 1173T309 788V681Q309 430 414 287T705 143Q891 143 993 278T1098 667V775ZM1009 1574V1564H856L706 1734L557 1564H404V1576L650 1848H762L1009 1574Z" />
<glyph unicode="&#xd5;" horiz-adv-x="1408" d="M1289 681Q1289 467 1217 308T1013 64T705 -20Q533 -20 400 64T194 305T118 668V773Q118 983 191 1144T397 1390T703 1476Q878 1476 1011 1392T1217 1147T1289 773V681ZM1098 775Q1098 1034 994 1172T703 1311Q521
1311 417 1173T309 788V681Q309 430 414 287T705 143Q891 143 993 278T1098 667V775ZM1061 1816Q1061 1708 1000 1641T846 1574Q805 1574 775 1584T697 1625T627 1662T577 1669Q536 1669 507 1638T478 1557L354 1564Q354 1671 414 1741T568 1811Q603 1811 631 1801T707
1762T780 1724T837 1715Q880 1715 908 1749T937 1828L1061 1816Z" />
<glyph unicode="&#xd6;" horiz-adv-x="1408" d="M1289 681Q1289 467 1217 308T1013 64T705 -20Q533 -20 400 64T194 305T118 668V773Q118 983 191 1144T397 1390T703 1476Q878 1476 1011 1392T1217 1147T1289 773V681ZM1098 775Q1098 1034 994 1172T703 1311Q521
1311 417 1173T309 788V681Q309 430 414 287T705 143Q891 143 993 278T1098 667V775ZM384 1683Q384 1728 411 1758T493 1789T575 1759T603 1683T575 1608T493 1578T412 1608T384 1683ZM814 1681Q814 1726 841 1757T923 1788T1005 1757T1033 1681T1005 1606T923
1576T842 1606T814 1681Z" />
<glyph unicode="&#xd7;" horiz-adv-x="1092" d="M89 329L419 665L91 1000L210 1123L539 788L868 1123L987 1000L659 665L989 329L870 206L539 543L208 206L89 329Z" />
<glyph unicode="&#xd8;" horiz-adv-x="1408" d="M1289 681Q1289 467 1217 308T1013 64T705 -20Q534 -20 403 62L306 -93H164L308 138Q118 330 118 690V773Q118 983 191 1144T397 1390T703 1476Q917 1476 1065 1351L1168 1516H1309L1150 1261Q1287 1074 1289 780V681ZM309
681Q309 437 407 296L971 1200Q869 1311 703 1311Q521 1311 417 1173T309 788V681ZM1098 775Q1098 957 1042 1088L493 207Q584 143 705 143Q891 143 993 278T1098 667V775Z" />
<glyph unicode="&#xd9;" horiz-adv-x="1328" d="M1194 1456V466Q1193 260 1065 129T716 -18L665 -20Q426 -20 284 109T140 464V1456H330V470Q330 312 417 225T665 137Q828 137 914 224T1001 469V1456H1194ZM773 1552H614L356 1846H579L773 1552Z" />
<glyph unicode="&#xda;" horiz-adv-x="1328" d="M1194 1456V466Q1193 260 1065 129T716 -18L665 -20Q426 -20 284 109T140 464V1456H330V470Q330 312 417 225T665 137Q828 137 914 224T1001 469V1456H1194ZM758 1846H982L714 1552H565L758 1846Z" />
<glyph unicode="&#xdb;" horiz-adv-x="1328" d="M1194 1456V466Q1193 260 1065 129T716 -18L665 -20Q426 -20 284 109T140 464V1456H330V470Q330 312 417 225T665 137Q828 137 914 224T1001 469V1456H1194ZM970 1572V1562H817L667 1732L518 1562H365V1574L611
1846H723L970 1572Z" />
<glyph unicode="&#xdc;" horiz-adv-x="1328" d="M1194 1456V466Q1193 260 1065 129T716 -18L665 -20Q426 -20 284 109T140 464V1456H330V470Q330 312 417 225T665 137Q828 137 914 224T1001 469V1456H1194ZM345 1681Q345 1726 372 1756T454 1787T536 1757T564
1681T536 1606T454 1576T373 1606T345 1681ZM775 1679Q775 1724 802 1755T884 1786T966 1755T994 1679T966 1604T884 1574T803 1604T775 1679Z" />
<glyph unicode="&#xdd;" horiz-adv-x="1230" d="M613 725L993 1456H1211L709 543V0H517V543L15 1456H235L613 725ZM708 1846H932L664 1552H515L708 1846Z" />
<glyph unicode="&#xde;" horiz-adv-x="1210" d="M352 1456V1163H631Q778 1163 888 1111T1057 961T1117 738Q1117 544 985 429T626 313H352V0H166V1456H352ZM352 1011V465H629Q771 465 851 540T931 736Q931 859 851 934T635 1011H352Z" />
<glyph unicode="&#xdf;" horiz-adv-x="1218" d="M324 0H139V1111Q139 1319 242 1436T532 1554Q712 1554 810 1465T909 1216Q909 1091 845 990T781 819Q781 768 818 721T950 601T1087 461T1130 317Q1130 158 1029 69T745 -20Q664 -20 574 2T445 52L488 207Q537
175 604 153T725 131Q832 131 888 178T945 307Q945 359 908 407T777 528T639 671T595 821Q595 910 664 1013T734 1201Q734 1295 682 1348T542 1402Q324 1402 324 1109V0Z" />
<glyph unicode="&#xe0;" horiz-adv-x="1114" d="M808 0Q792 32 782 114Q653 -20 474 -20Q314 -20 212 70T109 300Q109 469 237 562T599 656H779V741Q779 838 721 895T550 953Q451 953 384 903T317 782H131Q131 863 188 938T344 1058T561 1102Q748 1102 854 1009T964
751V253Q964 104 1002 16V0H808ZM501 141Q588 141 666 186T779 303V525H634Q294 525 294 326Q294 239 352 190T501 141ZM687 1242H528L270 1536H493L687 1242Z" />
<glyph unicode="&#xe1;" horiz-adv-x="1114" d="M808 0Q792 32 782 114Q653 -20 474 -20Q314 -20 212 70T109 300Q109 469 237 562T599 656H779V741Q779 838 721 895T550 953Q451 953 384 903T317 782H131Q131 863 188 938T344 1058T561 1102Q748 1102 854 1009T964
751V253Q964 104 1002 16V0H808ZM501 141Q588 141 666 186T779 303V525H634Q294 525 294 326Q294 239 352 190T501 141ZM672 1536H896L628 1242H479L672 1536Z" />
<glyph unicode="&#xe2;" horiz-adv-x="1114" d="M808 0Q792 32 782 114Q653 -20 474 -20Q314 -20 212 70T109 300Q109 469 237 562T599 656H779V741Q779 838 721 895T550 953Q451 953 384 903T317 782H131Q131 863 188 938T344 1058T561 1102Q748 1102 854 1009T964
751V253Q964 104 1002 16V0H808ZM501 141Q588 141 666 186T779 303V525H634Q294 525 294 326Q294 239 352 190T501 141ZM884 1262V1252H731L581 1422L432 1252H279V1264L525 1536H637L884 1262Z" />
<glyph unicode="&#xe3;" horiz-adv-x="1114" d="M808 0Q792 32 782 114Q653 -20 474 -20Q314 -20 212 70T109 300Q109 469 237 562T599 656H779V741Q779 838 721 895T550 953Q451 953 384 903T317 782H131Q131 863 188 938T344 1058T561 1102Q748 1102 854 1009T964
751V253Q964 104 1002 16V0H808ZM501 141Q588 141 666 186T779 303V525H634Q294 525 294 326Q294 239 352 190T501 141ZM936 1504Q936 1396 875 1329T721 1262Q680 1262 650 1272T572 1313T502 1350T452 1357Q411 1357 382 1326T353 1245L229 1252Q229 1359 289
1429T443 1499Q478 1499 506 1489T582 1450T655 1412T712 1403Q755 1403 783 1437T812 1516L936 1504Z" />
<glyph unicode="&#xe4;" horiz-adv-x="1114" d="M808 0Q792 32 782 114Q653 -20 474 -20Q314 -20 212 70T109 300Q109 469 237 562T599 656H779V741Q779 838 721 895T550 953Q451 953 384 903T317 782H131Q131 863 188 938T344 1058T561 1102Q748 1102 854 1009T964
751V253Q964 104 1002 16V0H808ZM501 141Q588 141 666 186T779 303V525H634Q294 525 294 326Q294 239 352 190T501 141ZM259 1371Q259 1416 286 1446T368 1477T450 1447T478 1371T450 1296T368 1266T287 1296T259 1371ZM689 1369Q689 1414 716 1445T798 1476T880
1445T908 1369T880 1294T798 1264T717 1294T689 1369Z" />
<glyph unicode="&#xe5;" horiz-adv-x="1114" d="M808 0Q792 32 782 114Q653 -20 474 -20Q314 -20 212 70T109 300Q109 469 237 562T599 656H779V741Q779 838 721 895T550 953Q451 953 384 903T317 782H131Q131 863 188 938T344 1058T561 1102Q748 1102 854 1009T964
751V253Q964 104 1002 16V0H808ZM501 141Q588 141 666 186T779 303V525H634Q294 525 294 326Q294 239 352 190T501 141ZM796 1419Q796 1332 734 1274T581 1215Q489 1215 428 1274T366 1419T427 1566T581 1627T734 1566T796 1419ZM465 1419Q465 1372 498 1338T581
1304Q629 1304 663 1337T697 1419T664 1502T581 1537Q531 1537 498 1502T465 1419Z" />
<glyph unicode="&#xe6;" horiz-adv-x="1729" d="M1262 -20Q1001 -20 865 160Q800 74 687 27T433 -20Q266 -20 172 66T78 304Q78 461 191 548T526 635H749V720Q749 827 694 888T535 950Q430 950 360 895T290 759L106 778Q106 921 227 1011T535 1102Q650 1102 738
1061T876 936Q939 1015 1026 1058T1218 1102Q1428 1102 1544 974T1660 612V497H932Q939 321 1026 226T1262 130Q1410 130 1531 206L1578 237L1642 101Q1484 -20 1262 -20ZM469 130Q541 130 620 167T749 258V495H521Q404 493 334 438T264 300Q264 223 317 177T469
130ZM1218 950Q1103 950 1029 865T937 640H1475V671Q1475 803 1408 876T1218 950Z" />
<glyph unicode="&#xe7;" horiz-adv-x="1072" d="M574 131Q673 131 747 191T829 341H1004Q999 248 940 164T783 30T574 -20Q353 -20 223 127T92 531V562Q92 720 150 843T316 1034T573 1102Q755 1102 875 993T1004 710H829Q821 815 750 882T573 950Q432 950 355
849T277 555V520Q277 333 354 232T574 131ZM604 -9L592 -61Q745 -88 745 -234Q745 -331 665 -387T442 -444L435 -337Q514 -337 557 -311T601 -238Q601 -194 569 -173T439 -143L471 -9H604Z" />
<glyph unicode="&#xe8;" horiz-adv-x="1085" d="M589 -20Q369 -20 231 124T93 511V545Q93 706 154 832T326 1030T566 1102Q777 1102 894 963T1011 565V488H278Q282 328 371 230T599 131Q697 131 765 171T884 277L997 189Q861 -20 589 -20ZM566 950Q454 950 378
869T284 640H826V654Q818 795 750 872T566 950ZM671 1242H512L254 1536H477L671 1242Z" />
<glyph unicode="&#xe9;" horiz-adv-x="1085" d="M589 -20Q369 -20 231 124T93 511V545Q93 706 154 832T326 1030T566 1102Q777 1102 894 963T1011 565V488H278Q282 328 371 230T599 131Q697 131 765 171T884 277L997 189Q861 -20 589 -20ZM566 950Q454 950 378
869T284 640H826V654Q818 795 750 872T566 950ZM656 1536H880L612 1242H463L656 1536Z" />
<glyph unicode="&#xea;" horiz-adv-x="1085" d="M589 -20Q369 -20 231 124T93 511V545Q93 706 154 832T326 1030T566 1102Q777 1102 894 963T1011 565V488H278Q282 328 371 230T599 131Q697 131 765 171T884 277L997 189Q861 -20 589 -20ZM566 950Q454 950 378
869T284 640H826V654Q818 795 750 872T566 950ZM868 1262V1252H715L565 1422L416 1252H263V1264L509 1536H621L868 1262Z" />
<glyph unicode="&#xeb;" horiz-adv-x="1085" d="M589 -20Q369 -20 231 124T93 511V545Q93 706 154 832T326 1030T566 1102Q777 1102 894 963T1011 565V488H278Q282 328 371 230T599 131Q697 131 765 171T884 277L997 189Q861 -20 589 -20ZM566 950Q454 950 378
869T284 640H826V654Q818 795 750 872T566 950ZM243 1371Q243 1416 270 1446T352 1477T434 1447T462 1371T434 1296T352 1266T271 1296T243 1371ZM673 1369Q673 1414 700 1445T782 1476T864 1445T892 1369T864 1294T782 1264T701 1294T673 1369Z" />
<glyph unicode="&#xec;" horiz-adv-x="506" d="M341 0H155V1082H341V0ZM615 1497H456L198 1791H421L615 1497Z" />
<glyph unicode="&#xed;" horiz-adv-x="506" d="M341 0H155V1082H341V0ZM343 1791H567L299 1497H150L343 1791Z" />
<glyph unicode="&#xee;" horiz-adv-x="506" d="M341 0H155V1082H341V0ZM556 1261V1251H403L253 1421L104 1251H-49V1263L197 1535H309L556 1261Z" />
<glyph unicode="&#xef;" horiz-adv-x="506" d="M341 0H155V1082H341V0ZM-69 1370Q-69 1415 -42 1445T40 1476T122 1446T150 1370T122 1295T40 1265T-41 1295T-69 1370ZM361 1368Q361 1413 388 1444T470 1475T552 1444T580 1368T552 1293T470 1263T389 1293T361 1368Z" />
<glyph unicode="&#xf0;" horiz-adv-x="1200" d="M820 1301Q1069 1037 1069 628V535Q1069 377 1011 251T844 52T602 -20Q467 -20 357 44T187 221T126 467Q126 614 182 730T341 912T574 977Q737 977 858 863Q810 1058 669 1199L451 1051L378 1150L570 1281Q438 1372
255 1421L312 1580Q551 1526 726 1387L915 1516L988 1416L820 1301ZM884 635L882 691Q849 752 780 788T618 825Q473 825 392 730T311 467Q311 327 394 229T606 131Q731 131 807 244T884 541V635Z" />
<glyph unicode="&#xf1;" horiz-adv-x="1130" d="M315 1082L321 946Q445 1102 645 1102Q988 1102 991 715V0H806V716Q805 833 753 889T589 945Q499 945 431 897T325 771V0H140V1082H315ZM927 1504Q927 1396 866 1329T712 1262Q671 1262 641 1272T563 1313T493 1350T443
1357Q402 1357 373 1326T344 1245L220 1252Q220 1359 280 1429T434 1499Q469 1499 497 1489T573 1450T646 1412T703 1403Q746 1403 774 1437T803 1516L927 1504Z" />
<glyph unicode="&#xf2;" horiz-adv-x="1168" d="M91 551Q91 710 153 837T327 1033T582 1102Q803 1102 939 949T1076 542V529Q1076 371 1016 246T843 50T584 -20Q364 -20 228 133T91 538V551ZM277 529Q277 349 360 240T584 131Q725 131 808 241T891 551Q891 729
807 839T582 950Q445 950 361 841T277 529ZM681 1242H522L264 1536H487L681 1242Z" />
<glyph unicode="&#xf3;" horiz-adv-x="1168" d="M91 551Q91 710 153 837T327 1033T582 1102Q803 1102 939 949T1076 542V529Q1076 371 1016 246T843 50T584 -20Q364 -20 228 133T91 538V551ZM277 529Q277 349 360 240T584 131Q725 131 808 241T891 551Q891 729
807 839T582 950Q445 950 361 841T277 529ZM666 1536H890L622 1242H473L666 1536Z" />
<glyph unicode="&#xf4;" horiz-adv-x="1168" d="M91 551Q91 710 153 837T327 1033T582 1102Q803 1102 939 949T1076 542V529Q1076 371 1016 246T843 50T584 -20Q364 -20 228 133T91 538V551ZM277 529Q277 349 360 240T584 131Q725 131 808 241T891 551Q891 729
807 839T582 950Q445 950 361 841T277 529ZM878 1262V1252H725L575 1422L426 1252H273V1264L519 1536H631L878 1262Z" />
<glyph unicode="&#xf5;" horiz-adv-x="1168" d="M91 551Q91 710 153 837T327 1033T582 1102Q803 1102 939 949T1076 542V529Q1076 371 1016 246T843 50T584 -20Q364 -20 228 133T91 538V551ZM277 529Q277 349 360 240T584 131Q725 131 808 241T891 551Q891 729
807 839T582 950Q445 950 361 841T277 529ZM930 1504Q930 1396 869 1329T715 1262Q674 1262 644 1272T566 1313T496 1350T446 1357Q405 1357 376 1326T347 1245L223 1252Q223 1359 283 1429T437 1499Q472 1499 500 1489T576 1450T649 1412T706 1403Q749 1403 777
1437T806 1516L930 1504Z" />
<glyph unicode="&#xf6;" horiz-adv-x="1168" d="M91 551Q91 710 153 837T327 1033T582 1102Q803 1102 939 949T1076 542V529Q1076 371 1016 246T843 50T584 -20Q364 -20 228 133T91 538V551ZM277 529Q277 349 360 240T584 131Q725 131 808 241T891 551Q891 729
807 839T582 950Q445 950 361 841T277 529ZM253 1371Q253 1416 280 1446T362 1477T444 1447T472 1371T444 1296T362 1266T281 1296T253 1371ZM683 1369Q683 1414 710 1445T792 1476T874 1445T902 1369T874 1294T792 1264T711 1294T683 1369Z" />
<glyph unicode="&#xf7;" horiz-adv-x="1169" d="M1069 600H71V784H1069V600ZM461 1098Q461 1146 489 1178T575 1210T661 1178T691 1098Q691 1051 662 1020T575 989T490 1020T461 1098ZM461 281Q461 329 489 361T575 393T661 361T691 281Q691 235 662 204T575 172T490
203T461 281Z" />
<glyph unicode="&#xf8;" horiz-adv-x="1160" d="M91 551Q91 710 152 836T326 1032T582 1102Q692 1102 786 1060L859 1208H983L881 1003Q1076 849 1076 529Q1076 371 1014 244T840 49T584 -20Q480 -20 394 15L320 -134H196L296 69Q91 218 91 551ZM276 529Q276 335
373 224L716 918Q654 950 582 950Q444 950 360 841T276 529ZM890 551Q890 733 803 844L463 156Q518 131 584 131Q723 131 806 240T890 535V551Z" />
<glyph unicode="&#xf9;" horiz-adv-x="1129" d="M808 107Q700 -20 491 -20Q318 -20 228 80T136 378V1082H321V383Q321 137 521 137Q733 137 803 295V1082H988V0H812L808 107ZM673 1242H514L256 1536H479L673 1242Z" />
<glyph unicode="&#xfa;" horiz-adv-x="1129" d="M808 107Q700 -20 491 -20Q318 -20 228 80T136 378V1082H321V383Q321 137 521 137Q733 137 803 295V1082H988V0H812L808 107ZM658 1536H882L614 1242H465L658 1536Z" />
<glyph unicode="&#xfb;" horiz-adv-x="1129" d="M808 107Q700 -20 491 -20Q318 -20 228 80T136 378V1082H321V383Q321 137 521 137Q733 137 803 295V1082H988V0H812L808 107ZM870 1262V1252H717L567 1422L418 1252H265V1264L511 1536H623L870 1262Z" />
<glyph unicode="&#xfc;" horiz-adv-x="1129" d="M808 107Q700 -20 491 -20Q318 -20 228 80T136 378V1082H321V383Q321 137 521 137Q733 137 803 295V1082H988V0H812L808 107ZM245 1371Q245 1416 272 1446T354 1477T436 1447T464 1371T436 1296T354 1266T273 1296T245
1371ZM675 1369Q675 1414 702 1445T784 1476T866 1445T894 1369T866 1294T784 1264T703 1294T675 1369Z" />
<glyph unicode="&#xfd;" horiz-adv-x="969" d="M494 271L746 1082H944L509 -167Q408 -437 188 -437L153 -434L84 -421V-271L134 -275Q228 -275 280 -237T367 -98L408 12L22 1082H224L494 271ZM599 1536H823L555 1242H406L599 1536Z" />
<glyph unicode="&#xfe;" horiz-adv-x="1180" d="M1063 529Q1063 282 950 131T644 -20Q447 -20 334 105V-416H149V1536H334V970Q447 1102 641 1102Q836 1102 949 955T1063 546V529ZM878 550Q878 733 800 839T586 945Q418 945 334 796V279Q417 131 588 131Q721 131
799 236T878 550Z" />
<glyph unicode="&#xff;" horiz-adv-x="969" d="M494 271L746 1082H944L509 -167Q408 -437 188 -437L153 -434L84 -421V-271L134 -275Q228 -275 280 -237T367 -98L408 12L22 1082H224L494 271ZM186 1371Q186 1416 213 1446T295 1477T377 1447T405 1371T377 1296T295
1266T214 1296T186 1371ZM616 1369Q616 1414 643 1445T725 1476T807 1445T835 1369T807 1294T725 1264T644 1294T616 1369Z" />
<glyph unicode="&#x2013;" horiz-adv-x="1344" d="M1421 651H419V802H1421V651Z" />
<glyph unicode="&#x2014;" horiz-adv-x="1599" d="M1737 651H401V802H1737V651Z" />
<glyph unicode="&#x2018;" horiz-adv-x="409" d="M270 1555L376 1483Q283 1356 280 1209V1073H96V1189Q96 1291 144 1391T270 1555Z" />
<glyph unicode="&#x2019;" horiz-adv-x="409" d="M153 1046L48 1118Q141 1248 144 1392V1536H327V1406Q326 1306 278 1207T153 1046Z" />
<glyph unicode="&#x201a;" horiz-adv-x="407" d="M141 -283L36 -210Q127 -83 130 63V181H315V81Q315 -20 266 -121T141 -283Z" />
<glyph unicode="&#x201c;" horiz-adv-x="724" d="M278 1555L384 1483Q291 1356 288 1209V1073H104V1189Q104 1291 152 1391T278 1555ZM593 1555L699 1483Q606 1356 603 1209V1073H419V1189Q419 1291 467 1391T593 1555Z" />
<glyph unicode="&#x201d;" horiz-adv-x="731" d="M165 1046L60 1118Q153 1248 156 1392V1536H339V1406Q338 1306 290 1207T165 1046ZM472 1046L367 1118Q460 1248 463 1392V1536H646V1406Q645 1306 597 1207T472 1046Z" />
<glyph unicode="&#x201e;" horiz-adv-x="705" d="M141 -301L36 -229Q127 -92 130 61V246H315V82Q315 -26 266 -131T141 -301ZM437 -301L332 -229Q423 -92 426 61V246H612V82Q612 -25 564 -129T437 -301Z" />
<glyph unicode="&#x2022;" horiz-adv-x="690" d="M138 772Q138 859 193 915T341 971Q432 971 489 917T546 769V732Q546 645 491 590T342 535Q249 535 194 590T138 734V772Z" />
<glyph unicode="&#x2039;" horiz-adv-x="614" d="M286 550L544 153H403L108 541V560L403 949H544L286 550Z" />
<glyph unicode="&#x203a;" horiz-adv-x="614" d="M231 949L526 560V541L231 152H89L347 550L89 949H231Z" />
</font>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 48 KiB

BIN
gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.ttf

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff2

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/themify.eot

Binary file not shown.

362
gui_wails01_learn/frontend/src/assets/fonts/themify.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 229 KiB

BIN
gui_wails01_learn/frontend/src/assets/fonts/themify.ttf

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/fonts/themify.woff

Binary file not shown.

BIN
gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Sm-Black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Sm-Black2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Sm-White.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-Sm-White2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/Constellation-Logo-White.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/blockchain.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/dotz.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/faces/face-0.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/nodes.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

BIN
gui_wails01_learn/frontend/src/assets/img/nodes.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/nodes2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/nodes2_dark.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/nodes_dark.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

BIN
gui_wails01_learn/frontend/src/assets/img/protocol-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/spots.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
gui_wails01_learn/frontend/src/assets/img/spots4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

20
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_animated.scss

@ -0,0 +1,20 @@
// Animated Icons
// --------------------------
.#{$fa-css-prefix}-spin {
animation: fa-spin 2s infinite linear;
}
.#{$fa-css-prefix}-pulse {
animation: fa-spin 1s infinite steps(8);
}
@keyframes fa-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

20
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_bordered-pulled.scss

@ -0,0 +1,20 @@
// Bordered & Pulled
// -------------------------
.#{$fa-css-prefix}-border {
border: solid .08em $fa-border-color;
border-radius: .1em;
padding: .2em .25em .15em;
}
.#{$fa-css-prefix}-pull-left { float: left; }
.#{$fa-css-prefix}-pull-right { float: right; }
.#{$fa-css-prefix},
.fas,
.far,
.fal,
.fab {
&.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
&.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
}

21
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_core.scss

@ -0,0 +1,21 @@
// Base Class Definition
// -------------------------
.#{$fa-css-prefix},
.fas,
.far,
.fal,
.fad,
.fab {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
}
%fa-icon {
@include fa-icon;
}

6
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_fixed-width.scss

@ -0,0 +1,6 @@
// Fixed Width Icons
// -------------------------
.#{$fa-css-prefix}-fw {
text-align: center;
width: $fa-fw-width;
}

1388
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_icons.scss

File diff suppressed because it is too large

23
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_larger.scss

@ -0,0 +1,23 @@
// Icon Sizes
// -------------------------
// makes the font 33% larger relative to the icon container
.#{$fa-css-prefix}-lg {
font-size: (4em / 3);
line-height: (3em / 4);
vertical-align: -.0667em;
}
.#{$fa-css-prefix}-xs {
font-size: .75em;
}
.#{$fa-css-prefix}-sm {
font-size: .875em;
}
@for $i from 1 through 10 {
.#{$fa-css-prefix}-#{$i}x {
font-size: $i * 1em;
}
}

18
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_list.scss

@ -0,0 +1,18 @@
// List Icons
// -------------------------
.#{$fa-css-prefix}-ul {
list-style-type: none;
margin-left: $fa-li-width * 5/4;
padding-left: 0;
> li { position: relative; }
}
.#{$fa-css-prefix}-li {
left: -$fa-li-width;
position: absolute;
text-align: center;
width: $fa-li-width;
line-height: inherit;
}

56
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_mixins.scss

@ -0,0 +1,56 @@
// Mixins
// --------------------------
@mixin fa-icon {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: inline-block;
font-style: normal;
font-variant: normal;
font-weight: normal;
line-height: 1;
}
@mixin fa-icon-rotate($degrees, $rotation) {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
transform: rotate($degrees);
}
@mixin fa-icon-flip($horiz, $vert, $rotation) {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
transform: scale($horiz, $vert);
}
// Only display content to screen readers. A la Bootstrap 4.
//
// See: http://a11yproject.com/posts/how-to-hide-content/
@mixin sr-only {
border: 0;
clip: rect(0, 0, 0, 0);
height: 0.0625em;
margin: -0.0625em;
overflow: hidden;
padding: 0;
position: absolute;
width: 0.0625em;
}
// Use in conjunction with .sr-only to only display content when it's focused.
//
// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
//
// Credit: HTML5 Boilerplate
@mixin sr-only-focusable {
&:active,
&:focus {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
width: auto;
}
}

24
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_rotated-flipped.scss

@ -0,0 +1,24 @@
// Rotated & Flipped Icons
// -------------------------
.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
.#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); }
// Hook for IE8-9
// -------------------------
:root {
.#{$fa-css-prefix}-rotate-90,
.#{$fa-css-prefix}-rotate-180,
.#{$fa-css-prefix}-rotate-270,
.#{$fa-css-prefix}-flip-horizontal,
.#{$fa-css-prefix}-flip-vertical,
.#{$fa-css-prefix}-flip-both {
filter: none;
}
}

5
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_screen-reader.scss

@ -0,0 +1,5 @@
// Screen Readers
// -------------------------
.sr-only { @include sr-only; }
.sr-only-focusable { @include sr-only-focusable; }

2062
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_shims.scss

File diff suppressed because it is too large

31
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_stacked.scss

@ -0,0 +1,31 @@
// Stacked Icons
// -------------------------
.#{$fa-css-prefix}-stack {
display: inline-block;
height: 2em;
line-height: 2em;
position: relative;
vertical-align: middle;
width: ($fa-fw-width*2);
}
.#{$fa-css-prefix}-stack-1x,
.#{$fa-css-prefix}-stack-2x {
left: 0;
position: absolute;
text-align: center;
width: 100%;
}
.#{$fa-css-prefix}-stack-1x {
line-height: inherit;
}
.#{$fa-css-prefix}-stack-2x {
font-size: 2em;
}
.#{$fa-css-prefix}-inverse {
color: $fa-inverse;
}

1405
gui_wails01_learn/frontend/src/assets/sass/font_awesome/_variables.scss

File diff suppressed because it is too large

22
gui_wails01_learn/frontend/src/assets/sass/font_awesome/brands.scss

@ -0,0 +1,22 @@
/*!
* Font Awesome Free 5.10.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@font-face {
font-family: 'Font Awesome 5 Brands';
font-style: normal;
font-weight: normal;
font-display: $fa-font-display;
src: url('#{$fa-font-path}/fa-brands-400.eot');
src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'),
url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'),
url('#{$fa-font-path}/fa-brands-400.woff') format('woff'),
url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'),
url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg');
}
.fab {
font-family: 'Font Awesome 5 Brands';
}

16
gui_wails01_learn/frontend/src/assets/sass/font_awesome/fontawesome.scss

@ -0,0 +1,16 @@
/*!
* Font Awesome Free 5.10.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@import 'mixins';
@import 'core';
@import 'larger';
@import 'fixed-width';
@import 'list';
@import 'bordered-pulled';
@import 'animated';
@import 'rotated-flipped';
@import 'stacked';
@import 'icons';
@import 'screen-reader';

23
gui_wails01_learn/frontend/src/assets/sass/font_awesome/regular.scss

@ -0,0 +1,23 @@
/*!
* Font Awesome Free 5.10.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 400;
font-display: $fa-font-display;
src: url('#{$fa-font-path}/fa-regular-400.eot');
src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'),
url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'),
url('#{$fa-font-path}/fa-regular-400.woff') format('woff'),
url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'),
url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg');
}
.far {
font-family: 'Font Awesome 5 Free';
font-weight: 400;
}

24
gui_wails01_learn/frontend/src/assets/sass/font_awesome/solid.scss

@ -0,0 +1,24 @@
/*!
* Font Awesome Free 5.10.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 900;
font-display: $fa-font-display;
src: url('#{$fa-font-path}/fa-solid-900.eot');
src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'),
url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'),
url('#{$fa-font-path}/fa-solid-900.woff') format('woff'),
url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'),
url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg');
}
.fa,
.fas {
font-family: 'Font Awesome 5 Free';
font-weight: 900;
}

6
gui_wails01_learn/frontend/src/assets/sass/font_awesome/v4-shims.scss

@ -0,0 +1,6 @@
/*!
* Font Awesome Free 5.10.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
@import 'variables';
@import 'shims';

47
gui_wails01_learn/frontend/src/assets/sass/paper-dashboard.scss

@ -0,0 +1,47 @@
/*!
=========================================================
* Vue Paper Dashboard - v2.0.0
=========================================================
* Product Page: http://www.creative-tim.com/product/paper-dashboard
* Copyright 2019 Creative Tim (http://www.creative-tim.com)
* Licensed under MIT (https://github.com/creativetimofficial/paper-dashboard/blob/master/LICENSE.md)
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
@import url('https://fonts.googleapis.com/css?family=Raleway&display=swap');
@import url('https://fonts.googleapis.com/css?family=Poppins&display=swap');
@import url('https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap');
@import url('https://fonts.googleapis.com/css?family=Major+Mono+Display&display=swap');
@import "font_awesome/fontawesome.scss";
@import "font_awesome/solid.scss";
@import "font_awesome/brands.scss";
@import "paper/variables";
@import "paper/mixins";
@import "paper/typography";
// Core CSS
@import "paper/misc";
@import "paper/sidebar-and-main-panel";
@import "paper/buttons";
@import "paper/inputs";
@import "paper/alerts";
@import "paper/tables";
@import "paper/checkbox-radio";
@import "paper/navbars";
@import "paper/footers";
// Fancy Stuff
@import "paper/dropdown";
@import "paper/cards";
@import "paper/chartist";
@import "paper/responsive";
@import "paper/sweetalert2";
// Constellation Wallet
@import "paper/wallet";
@import "paper/select";

68
gui_wails01_learn/frontend/src/assets/sass/paper/_alerts.scss

@ -0,0 +1,68 @@
.alert {
border: 0;
border-radius: 0;
color: #FFFFFF;
padding: 0.625em 0.9375em;
font-size: 0.875rem;
.container & {
border-radius: 0.25em;
}
.navbar & {
border-radius: 0;
left: 0;
position: absolute;
right: 0;
top: 5.3125em;
width: 100%;
z-index: 3;
}
.navbar:not(.navbar-transparent) & {
top: 4.375em;
}
span[data-notify="icon"] {
font-size: 1.875rem;
display: block;
left: 0.9375em;
position: absolute;
top: 50%;
margin-top: -1.25em;
}
.close ~ span {
display: block;
max-width: 89%;
}
&[data-notify="container"] {
padding: 0.625em 0.625em 0.625em 1.25em;
border-radius: $border-radius-base;
}
&.alert-with-icon {
padding-left: 4.0625em;
}
}
.alert-info {
background-color: $bg-info;
color: $info-states-color;
}
.alert-success {
background-color: $bg-success;
color: $success-states-color;
}
.alert-warning {
background-color: $bg-warning;
color: $warning-states-color;
}
.alert-danger {
background-color: $bg-danger;
color: $danger-states-color;
}

228
gui_wails01_learn/frontend/src/assets/sass/paper/_buttons.scss

@ -0,0 +1,228 @@
.btn{
box-sizing: border-box;
border-width: $border-thick;
font-size: $font-size-small;
font-weight: $font-weight-bold;
padding: .5rem $padding-base-horizontal;
line-height: 1.75;
cursor: pointer;
text-transform: uppercase;
&.btn-border,
&.btn-link{
background-color: $transparent-bg;
}
@include btn-styles($default-color, $default-states-color);
@include transition($fast-transition-time, linear);
&:hover,
&:focus{
outline: 0 !important;
@include box-shadow(none);
}
&:active,
&.active,
.open > &.dropdown-toggle {
@include box-shadow(none);
outline: 0 !important;
}
&[class*="btn-outline-"]{
background-image: none;
background-color: transparent;
}
}
.btn-just-icon{
border-radius: 0.25em;
height: 1.875em;
width: 1.875em;
min-width: 1.875em;
padding: 0em;
margin-top: 0.625em;
&.btn-sm{
padding: 0.25em !important;
}
i{
font-size: $font-size-medium;
padding: 0.125em 0em;
}
}
.upgrade-pro{
.btn{
margin-top: 1.875em;
}
}
.btn-link.btn-just-icon{
padding: 0.5em;
}
.btn-group .btn + .btn,
.btn-group .btn + .btn-group,
.btn-group .btn-group + .btn,
.btn-group .btn-group + .btn-group{
margin-left: -0.125em;
}
// Apply the mixin to the buttons
.btn-primary { @include btn-styles($primary-color, $primary-states-color); }
.btn-success { @include btn-styles($success-color, $success-states-color); }
.btn-info { @include btn-styles($info-color, $info-states-color); }
.btn-warning { @include btn-styles($warning-color, $warning-states-color); }
.btn-danger { @include btn-styles($danger-color, $danger-states-color); }
.theme--dark .btn-primary { @include btn-styles($primary-color-dark, $primary-states-color-dark); }
.theme--dark .btn-success { @include btn-styles($success-color-dark, $success-states-color-dark); }
.theme--dark .btn-info { @include btn-styles($info-color-dark, $info-states-color-dark); }
.btn-outline-default { @include btn-outline-styles($default-color, $default-states-color); }
.btn-outline-primary { @include btn-outline-styles($primary-color, $primary-states-color); }
.btn-outline-success { @include btn-outline-styles($success-color, $success-states-color); }
.btn-outline-info { @include btn-outline-styles($info-color, $info-states-color); }
.btn-outline-warning { @include btn-outline-styles($warning-color, $warning-states-color); }
.btn-outline-danger { @include btn-outline-styles($danger-color, $danger-states-color); }
.theme--dark .btn-outline-primary { @include btn-outline-styles($primary-color-dark, $primary-states-color-dark); }
.theme--dark .btn-outline-success { @include btn-outline-styles($success-color-dark, $success-states-color-dark); }
.theme--dark .btn-outline-info { @include btn-outline-styles($info-color-dark, $info-states-color-dark); }
.btn-neutral { @include btn-styles($white-color, $default-states-color); }
.btn-outline-neutral { @include btn-outline-styles($white-color, $default-states-color);
&:hover,
&:focus{
color: $default-states-color;
background-color: $white-color;
}
}
.btn-neutral {
@include btn-styles($white-color, $white-color);
color: $default-color;
&:hover,
&:focus{
color: $default-states-color;
}
&.btn-border{
&:hover,
&:focus{
color: $default-color;
}
&:active,
&.active,
.open > &.dropdown-toggle{
background-color: $white-color;
color: $default-color;
}
}
&.btn-link:active,
&.btn-link.active{
background-color: transparent;
}
}
.btn{
&:disabled,
&[disabled],
&.disabled{
@include opacity(.5);
}
}
.btn-link{
border-color: transparent !important;
padding: $padding-base-vertical $padding-base-horizontal;
&:hover,
&:focus,
&:active{
text-decoration: none;
border-color: transparent;
}
&.btn-icon{
padding: $padding-base-vertical;
}
}
.btn-lg{
@include btn-size($padding-large-vertical, $padding-large-horizontal, $font-size-base, $line-height-small);
}
.btn-sm{
@include btn-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small);
}
.btn-wd {
min-width: 8.75em;
}
.btn-group.select{
width: 100%;
}
.btn-group.select .btn{
text-align: left;
}
.btn-group.select .caret{
position: absolute;
top: 50%;
margin-top: -0.0625em;
right: 0.5em;
}
.btn-just-icon{
&.btn-sm{
height: 1.875em;
width: 1.875em;
min-width: 1.875em;
padding: 0;
i{
font-size: $font-size-small;
}
}
&.btn-lg{
height: 3.125em;
width: 3.125em;
min-width: 3.125em;
padding: 0.8125em;
i{
font-size: 1.125rem;
padding: 0;
}
}
}
.btn-round{
border-radius: 1.875em;
}
.btn.btn-link:focus{
box-shadow: none !important;
text-decoration: none;
}
.column .btn-link{
padding: 0.4375em 0;
}
.share-buttons .btn-outline-default{
margin-top: 1.5em;
}
#modals .btn-outline-neutral{
margin-bottom: 0.625em;
}
.btn-group.select{
overflow: visible !important;
}
.media{
.media-body{
.media-footer{
.btn-neutral{
margin: $navbar-margin-btn;
font-size: $font-size-base;
i{
margin-right: 0 !important;
}
}
}
}
}

269
gui_wails01_learn/frontend/src/assets/sass/paper/_cards.scss

@ -0,0 +1,269 @@
@import "themes";
.card {
border-radius: $border-radius-extreme;
box-shadow: 0em 0.125em 0.125em rgba(204, 197, 185, 0.5);
margin-bottom: 1.25em;
position: relative;
z-index: 1;
border: none;
@include themed() {
background-color: t('cardBackgroundColor');
color: t('cardTextColor');
}
.card-image {
width: 100%;
overflow: hidden;
height: 17.625em;
border-radius: $border-radius-extreme $border-radius-extreme 0 0;
position: relative;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
img {
width: 100%;
}
}
.card-body {
padding: 0.9375em 0.9375em 0.625em 0.9375em;
}
.card-header {
padding: 1.25em 1.25em 0em;
border-bottom: 0em;
background-color: transparent;
}
.description {
font-size: $font-paragraph;
@include themed() {
color: t('cardTextColor');
}
}
h6 {
font-size: $font-size-small;
margin: 0;
}
.card-category,
label {
font-size: $font-size-base;
font-weight: $font-weight-normal;
margin-bottom: 0em;
i {
font-size: $font-paragraph;
}
@include themed() {
color: t('cardLabelColor');
}
}
label {
font-size: 0.9375rem;
margin-bottom: 0.3125em;
}
.card-title {
margin: $none;
font-weight: $font-weight-light;
@include themed() {
color: t('cardTitleColor');
}
}
.avatar {
width: 3.125em;
height: 3.125em;
overflow: hidden;
border-radius: 50%;
margin-right: 0.3125em;
}
.footer {
padding: 0;
line-height: 1.875em;
overflow: hidden;
.legend {
padding: 0.3125em 0em;
}
hr {
margin-top: 0.3125em;
margin-bottom: 0.3125em;
}
}
.stats {
color: #a9a9a9;
flex-wrap: nowrap;
font-weight: 300;
i {
margin-right: 0.125em;
min-width: 0.9375em;
display: inline-block;
}
}
.footer div {
display: inline-block;
}
.author {
font-size: $font-size-small;
font-weight: $font-weight-bold;
text-transform: uppercase;
}
.author i {
font-size: $font-size-base;
}
&.card-separator:after {
height: 100%;
right: -0.9375em;
top: 0em;
width: 0.0625em;
background-color: $medium-gray;
content: "";
position: absolute;
}
.ct-chart {
margin: 1.875em 0em 1.875em;
height: 15.3125em;
}
.table {
tbody td:first-child,
tfoot th:first-child, tfoot td:first-child,
thead th:first-child, thead td:first-child, {
padding-left: 0.9375em;
}
tbody td:last-child,
tfoot th:last-child, tfoot td:last-child,
thead th:last-child, thead td:last-child, {
padding-right: 0.9375em;
}
}
.alert {
border-radius: $border-radius-base;
position: relative;
&.alert-with-icon {
padding-left: 4.0625em;
}
}
.icon-big {
font-size: 2.7rem;
margin-left: 0.625rem;
}
.numbers {
font-size: 1.5rem;
text-align: right;
p {
font-size: 0.875rem;
margin: 0;
}
}
ul.team-members {
li {
padding: 0.625em 0em;
&:not(:last-child) {
border-bottom: 0.0625em solid $medium-pale-bg;
}
}
}
}
.card-user {
.image {
border-radius: 0.5em 0.5em 0em 0em;
height: 9.375em;
position: relative;
overflow: hidden;
img {
width: 100%;
}
}
.image-plain {
height: 0;
margin-top: 6.875em;
}
.author {
text-align: center;
text-transform: none;
margin-top: -4.0625em;
.title {
color: $default-states-color;
small {
color: $muted-color;
}
}
}
.avatar {
width: 8.25em;
height: 8.25em;
border-radius: 50%;
position: relative;
margin-bottom: 0.9375em;
&.border-white {
border: 0.3125em solid $white-color;
}
&.border-gray {
border: 0.3125em solid $muted-color;
}
}
.card-title {
font-weight: 600;
line-height: 1.5em;
}
.description {
margin-top: 0.625em;
}
.card-body {
min-height: 12.5em;
}
&.card-plain {
.avatar {
height: 11.875em;
width: 11.875em;
}
}
}
.card-map {
.map {
height: 31.25em;
padding-top: 1.25em;
> div {
height: 100%;
}
}
}
.card-user,
.card-price {
.card-footer {
padding: 0.3125em 0.9375em 0.625em;
}
hr {
margin: 0.3125em 0.9375em;
}
}
.card-plain {
background-color: transparent;
box-shadow: none;
border-radius: 0;
.image {
border-radius: 0.25em;
}
}
.theme--dark .card {
webkit-box-shadow: none;
box-shadow: none;
}

229
gui_wails01_learn/frontend/src/assets/sass/paper/_chartist.scss

@ -0,0 +1,229 @@
@mixin ct-responsive-svg-container($width: 100%, $ratio: $ct-container-ratio) {
display: block;
position: relative;
width: $width;
&:before {
display: block;
float: left;
content: "";
width: 0;
height: 0;
padding-bottom: $ratio * 100%;
}
&:after {
content: "";
display: table;
clear: both;
}
> svg {
display: block;
position: absolute;
top: 0;
left: 0;
}
}
@mixin ct-align-justify($ct-text-align: $ct-text-align, $ct-text-justify: $ct-text-justify) {
-webkit-box-align: $ct-text-align;
-webkit-align-items: $ct-text-align;
-ms-flex-align: $ct-text-align;
align-items: $ct-text-align;
-webkit-box-pack: $ct-text-justify;
-webkit-justify-content: $ct-text-justify;
-ms-flex-pack: $ct-text-justify;
justify-content: $ct-text-justify;
// Fallback to text-align for non-flex browsers
@if ($ct-text-justify == 'flex-start') {
text-align: left;
} @else if ($ct-text-justify == 'flex-end') {
text-align: right;
} @else {
text-align: center;
}
}
@mixin ct-flex() {
// Fallback to block
display: block;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin ct-chart-label($ct-text-color: $ct-text-color, $ct-text-size: $ct-text-size, $ct-text-line-height: $ct-text-line-height) {
fill: $ct-text-color;
color: $ct-text-color;
font-size: $ct-text-size;
line-height: $ct-text-line-height;
}
@mixin ct-chart-grid($ct-grid-color: $ct-grid-color, $ct-grid-width: $ct-grid-width, $ct-grid-dasharray: $ct-grid-dasharray) {
stroke: $ct-grid-color;
stroke-width: $ct-grid-width;
@if ($ct-grid-dasharray) {
stroke-dasharray: $ct-grid-dasharray;
}
}
@mixin ct-chart-point($ct-point-size: $ct-point-size, $ct-point-shape: $ct-point-shape) {
stroke-width: $ct-point-size;
stroke-linecap: $ct-point-shape;
}
@mixin ct-chart-line($ct-line-width: $ct-line-width, $ct-line-dasharray: $ct-line-dasharray) {
fill: none;
stroke-width: $ct-line-width;
@if ($ct-line-dasharray) {
stroke-dasharray: $ct-line-dasharray;
}
}
@mixin ct-chart-area($ct-area-opacity: $ct-area-opacity) {
stroke: none;
fill-opacity: $ct-area-opacity;
}
@mixin ct-chart-bar($ct-bar-width: $ct-bar-width) {
fill: none;
stroke-width: $ct-bar-width;
}
@mixin ct-chart-donut($ct-donut-width: $ct-donut-width) {
fill: none;
stroke-width: $ct-donut-width;
}
@mixin ct-chart-series-color($color) {
.#{$ct-class-point}, .#{$ct-class-line}, .#{$ct-class-bar}, .#{$ct-class-slice-donut} {
stroke: $color;
}
.#{$ct-class-slice-pie}, .#{$ct-class-area} {
fill: $color;
}
}
@mixin ct-chart($ct-container-ratio: $ct-container-ratio, $ct-text-color: $ct-text-color, $ct-text-size: $ct-text-size, $ct-grid-color: $ct-grid-color, $ct-grid-width: $ct-grid-width, $ct-grid-dasharray: $ct-grid-dasharray, $ct-point-size: $ct-point-size, $ct-point-shape: $ct-point-shape, $ct-line-width: $ct-line-width, $ct-bar-width: $ct-bar-width, $ct-donut-width: $ct-donut-width, $ct-series-names: $ct-series-names, $ct-series-colors: $ct-series-colors) {
.#{$ct-class-label} {
@include ct-chart-label($ct-text-color, $ct-text-size);
}
.#{$ct-class-chart-line} .#{$ct-class-label},
.#{$ct-class-chart-bar} .#{$ct-class-label} {
@include ct-flex();
}
.#{$ct-class-label}.#{$ct-class-horizontal}.#{$ct-class-start} {
@include ct-align-justify(flex-end, flex-start);
// Fallback for browsers that don't support foreignObjects
text-anchor: start;
}
.#{$ct-class-label}.#{$ct-class-horizontal}.#{$ct-class-end} {
@include ct-align-justify(flex-start, flex-start);
// Fallback for browsers that don't support foreignObjects
text-anchor: start;
}
.#{$ct-class-label}.#{$ct-class-vertical}.#{$ct-class-start} {
@include ct-align-justify(flex-end, flex-end);
// Fallback for browsers that don't support foreignObjects
text-anchor: end;
}
.#{$ct-class-label}.#{$ct-class-vertical}.#{$ct-class-end} {
@include ct-align-justify(flex-end, flex-start);
// Fallback for browsers that don't support foreignObjects
text-anchor: start;
}
.#{$ct-class-chart-bar} .#{$ct-class-label}.#{$ct-class-horizontal}.#{$ct-class-start} {
@include ct-align-justify(flex-end, center);
// Fallback for browsers that don't support foreignObjects
text-anchor: start;
}
.#{$ct-class-chart-bar} .#{$ct-class-label}.#{$ct-class-horizontal}.#{$ct-class-end} {
@include ct-align-justify(flex-start, center);
// Fallback for browsers that don't support foreignObjects
text-anchor: start;
}
.#{$ct-class-chart-bar}.#{$ct-class-horizontal-bars} .#{$ct-class-label}.#{$ct-class-horizontal}.#{$ct-class-start} {
@include ct-align-justify(flex-end, flex-start);
// Fallback for browsers that don't support foreignObjects
text-anchor: start;
}
.#{$ct-class-chart-bar}.#{$ct-class-horizontal-bars} .#{$ct-class-label}.#{$ct-class-horizontal}.#{$ct-class-end} {
@include ct-align-justify(flex-start, flex-start);
// Fallback for browsers that don't support foreignObjects
text-anchor: start;
}
.#{$ct-class-chart-bar}.#{$ct-class-horizontal-bars} .#{$ct-class-label}.#{$ct-class-vertical}.#{$ct-class-start} {
//@include ct-chart-label($ct-text-color, $ct-text-size, center, $ct-vertical-text-justify);
@include ct-align-justify(center, flex-end);
// Fallback for browsers that don't support foreignObjects
text-anchor: end;
}
.#{$ct-class-chart-bar}.#{$ct-class-horizontal-bars} .#{$ct-class-label}.#{$ct-class-vertical}.#{$ct-class-end} {
@include ct-align-justify(center, flex-start);
// Fallback for browsers that don't support foreignObjects
text-anchor: end;
}
.#{$ct-class-grid} {
@include ct-chart-grid($ct-grid-color, $ct-grid-width, $ct-grid-dasharray);
}
.#{$ct-class-point} {
@include ct-chart-point($ct-point-size, $ct-point-shape);
}
.#{$ct-class-line} {
@include ct-chart-line($ct-line-width);
}
.#{$ct-class-area} {
@include ct-chart-area();
}
.#{$ct-class-bar} {
@include ct-chart-bar($ct-bar-width);
}
.#{$ct-class-slice-donut} {
@include ct-chart-donut($ct-donut-width);
}
@if $ct-include-colored-series {
@for $i from 0 to length($ct-series-names) {
.#{$ct-class-series}-#{nth($ct-series-names, $i + 1)} {
$color: nth($ct-series-colors, $i + 1);
@include ct-chart-series-color($color);
}
}
}
}
@if $ct-include-classes {
@include ct-chart();
@if $ct-include-alternative-responsive-containers {
@for $i from 0 to length($ct-scales-names) {
.#{nth($ct-scales-names, $i + 1)} {
@include ct-responsive-svg-container($ratio: nth($ct-scales, $i + 1));
}
}
}
}

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

Loading…
Cancel
Save