aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinteck <minteck@phoenixnet.tech>2021-10-31 11:49:13 +0100
committerMinteck <minteck@phoenixnet.tech>2021-10-31 11:49:13 +0100
commite8e6a0906702dc7b569ef4f0b2d9486d772ba562 (patch)
treefb1361db2820ee7182c5023f6fa03237c8f46367
downloadcore-e8e6a0906702dc7b569ef4f0b2d9486d772ba562.tar.gz
core-e8e6a0906702dc7b569ef4f0b2d9486d772ba562.tar.bz2
core-e8e6a0906702dc7b569ef4f0b2d9486d772ba562.zip
Initial commit
-rw-r--r--.gitignore5
-rw-r--r--.idea/.gitignore8
-rw-r--r--.idea/Familine.iml9
-rw-r--r--.idea/deployment.xml33
-rw-r--r--.idea/dictionaries/Minteck.xml3
-rw-r--r--.idea/inspectionProfiles/Project_Default.xml8
-rw-r--r--.idea/jsLibraryMappings.xml6
-rw-r--r--.idea/modules.xml8
-rw-r--r--.idea/php.xml4
-rw-r--r--.idea/sshConfigs.xml8
-rw-r--r--.idea/webServers.xml14
-rw-r--r--app/session.php34
-rw-r--r--dark.css92
-rw-r--r--favicon.svg69
-rw-r--r--icns/badge-filled.pngbin0 -> 3511 bytes
-rw-r--r--icns/badge-symbolic.pngbin0 -> 3984 bytes
-rw-r--r--icns/badge.pngbin0 -> 14049 bytes
-rw-r--r--icns/bucks.pngbin0 -> 13123 bytes
-rw-r--r--icns/cinema-filled.pngbin0 -> 3315 bytes
-rw-r--r--icns/cinema-symbolic.pngbin0 -> 4990 bytes
-rw-r--r--icns/cinema.pngbin0 -> 13823 bytes
-rw-r--r--icns/cloud-link.pngbin0 -> 33246 bytes
-rw-r--r--icns/contacts-filled.pngbin0 -> 3105 bytes
-rw-r--r--icns/contacts-symbolic.pngbin0 -> 4038 bytes
-rw-r--r--icns/contacts.pngbin0 -> 10925 bytes
-rw-r--r--icns/famidata.pngbin0 -> 375 bytes
-rw-r--r--icns/familine-camera.svg16
-rw-r--r--icns/familine-console.svg21
-rw-r--r--icns/familine-docs.svg13
-rw-r--r--icns/familine-help.svg13
-rw-r--r--icns/familine-money.svg15
-rw-r--r--icns/familine-movies.svg13
-rw-r--r--icns/familine-photos.svg34
-rw-r--r--icns/familine-planning.svg14
-rw-r--r--icns/familine-review.svg13
-rw-r--r--icns/familine-share.svg13
-rw-r--r--icns/familine-you.svg17
-rw-r--r--icns/familine.svg69
-rw-r--r--icns/help-filled.pngbin0 -> 5251 bytes
-rw-r--r--icns/help-symbolic.pngbin0 -> 6677 bytes
-rw-r--r--icns/help.pngbin0 -> 12722 bytes
-rw-r--r--icns/home-filled.pngbin0 -> 2557 bytes
-rw-r--r--icns/home-symbolic.pngbin0 -> 2886 bytes
-rw-r--r--icns/home.pngbin0 -> 9893 bytes
-rw-r--r--icns/money-filled.pngbin0 -> 4441 bytes
-rw-r--r--icns/money-symbolic.pngbin0 -> 4977 bytes
-rw-r--r--icns/money.pngbin0 -> 9655 bytes
-rw-r--r--icns/music.pngbin0 -> 3450 bytes
-rw-r--r--icns/open-book-filled.pngbin0 -> 2493 bytes
-rw-r--r--icns/open-book-symbolic.pngbin0 -> 2735 bytes
-rw-r--r--icns/open-book.pngbin0 -> 2079 bytes
-rw-r--r--icns/opus.svg18
-rw-r--r--icns/pause-filled.pngbin0 -> 288 bytes
-rw-r--r--icns/pause-symbolic.pngbin0 -> 299 bytes
-rw-r--r--icns/pip.pngbin0 -> 974 bytes
-rw-r--r--icns/play-filled.pngbin0 -> 435 bytes
-rw-r--r--icns/play-symbolic.pngbin0 -> 580 bytes
-rw-r--r--icns/radio-filled.pngbin0 -> 4329 bytes
-rw-r--r--icns/radio-symbolic.pngbin0 -> 4514 bytes
-rw-r--r--icns/radio.pngbin0 -> 8243 bytes
-rw-r--r--icns/settings-filled.pngbin0 -> 5192 bytes
-rw-r--r--icns/settings-symbolic.pngbin0 -> 7419 bytes
-rw-r--r--icns/settings.pngbin0 -> 12301 bytes
-rw-r--r--icns/share-filled.pngbin0 -> 3457 bytes
-rw-r--r--icns/share-symbolic.pngbin0 -> 4941 bytes
-rw-r--r--icns/share.pngbin0 -> 11049 bytes
-rw-r--r--icns/solve-filled.pngbin0 -> 5225 bytes
-rw-r--r--icns/solve-symbolic.pngbin0 -> 6088 bytes
-rw-r--r--icns/solve.pngbin0 -> 16776 bytes
-rw-r--r--icns/speaker.pngbin0 -> 722 bytes
-rw-r--r--icns/window-close.pngbin0 -> 220 bytes
-rw-r--r--icns/window-maximize.pngbin0 -> 223 bytes
-rw-r--r--icns/window-minimize.pngbin0 -> 263 bytes
-rw-r--r--icns/window-reduce.pngbin0 -> 468 bytes
-rw-r--r--index.php98
-rw-r--r--js/home.js12
-rw-r--r--js/iframe.js48
-rw-r--r--js/loading.js32
-rw-r--r--js/navigation.js110
-rw-r--r--js/statusbar.js4
-rw-r--r--loader.svg52
-rw-r--r--login/embed/index.php6
-rw-r--r--login/index.php6
-rw-r--r--native.css68
-rw-r--r--oauth/embed/index.php45
-rw-r--r--oauth/index.php45
-rw-r--r--private/.htaccess1
-rw-r--r--private/session.php30
-rw-r--r--radio.css52
-rw-r--r--radio.embed.css3
-rw-r--r--robots.txt3
-rw-r--r--sample.html11
-rw-r--r--statusbar.php134
-rw-r--r--styles.css233
-rw-r--r--version.txt1
-rw-r--r--welcome/index.php4
96 files changed, 1568 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0698a7f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+private/app.json
+app/console
+app/help
+app/money
+private/FamilineConfig.json \ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..73a9019
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/../../../../:\Projets\Familine\.idea/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/Familine.iml b/.idea/Familine.iml
new file mode 100644
index 0000000..efaccc6
--- /dev/null
+++ b/.idea/Familine.iml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+ <component name="NewModuleRootManager">
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="mobile-detect" level="application" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/deployment.xml b/.idea/deployment.xml
new file mode 100644
index 0000000..6d5cc82
--- /dev/null
+++ b/.idea/deployment.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="PublishConfigData" autoUpload="Always" serverName="Familine" createEmptyFolders="true" autoUploadExternalChanges="true">
+ <serverData>
+ <paths name="CamView Server">
+ <serverdata>
+ <mappings>
+ <mapping local="$PROJECT_DIR$" web="/" />
+ </mappings>
+ </serverdata>
+ </paths>
+ <paths name="Familine">
+ <serverdata>
+ <mappings>
+ <mapping deploy="/mnt/familine" local="$PROJECT_DIR$" web="/" />
+ </mappings>
+ <excludedPaths>
+ <excludedPath path="/mnt/familine/app/photos" />
+ <excludedPath path="/mnt/familine/app/money/public/" />
+ </excludedPaths>
+ </serverdata>
+ </paths>
+ <paths name="Familine (project level)">
+ <serverdata>
+ <mappings>
+ <mapping local="$PROJECT_DIR$" web="/" />
+ </mappings>
+ </serverdata>
+ </paths>
+ </serverData>
+ <option name="myAutoUpload" value="ALWAYS" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/dictionaries/Minteck.xml b/.idea/dictionaries/Minteck.xml
new file mode 100644
index 0000000..61a53e6
--- /dev/null
+++ b/.idea/dictionaries/Minteck.xml
@@ -0,0 +1,3 @@
+<component name="ProjectDictionaryState">
+ <dictionary name="Minteck" />
+</component> \ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..8e370fa
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,8 @@
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0">
+ <option name="myName" value="Project Default" />
+ <inspection_tool class="CssUnresolvedCustomProperty" enabled="false" level="ERROR" enabled_by_default="false" />
+ <inspection_tool class="JsonSchemaCompliance" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="PhpUndefinedFunctionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
+ </profile>
+</component> \ No newline at end of file
diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
new file mode 100644
index 0000000..61a4bd9
--- /dev/null
+++ b/.idea/jsLibraryMappings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="JavaScriptLibraryMappings">
+ <file url="PROJECT" libraries="{mobile-detect}" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..e03b09a
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/.idea/Familine.iml" filepath="$PROJECT_DIR$/.idea/Familine.iml" />
+ </modules>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/php.xml b/.idea/php.xml
new file mode 100644
index 0000000..7341688
--- /dev/null
+++ b/.idea/php.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="PhpProjectSharedConfiguration" php_language_level="7.4" />
+</project> \ No newline at end of file
diff --git a/.idea/sshConfigs.xml b/.idea/sshConfigs.xml
new file mode 100644
index 0000000..f4cd94d
--- /dev/null
+++ b/.idea/sshConfigs.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="SshConfigs">
+ <configs>
+ <sshConfig host="familine.ddns.net" id="d74d45ad-c752-4bdf-82c1-85cbd6c8e458" keyPath="$USER_HOME$/.ssh/id_rsa" port="22465" nameFormat="DESCRIPTIVE" username="root" />
+ </configs>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/webServers.xml b/.idea/webServers.xml
new file mode 100644
index 0000000..c2a0bab
--- /dev/null
+++ b/.idea/webServers.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="WebServers">
+ <option name="servers">
+ <webServer id="dd27d6eb-cb58-4445-81e2-75460b980d8f" name="Familine (project level)" url="https://familine.mooo.com">
+ <fileTransfer accessType="SFTP" host="familine.ddns.net" port="22465" sshConfigId="d74d45ad-c752-4bdf-82c1-85cbd6c8e458" sshConfig="root@familine.ddns.net:22465 key" keyPair="true">
+ <advancedOptions>
+ <advancedOptions dataProtectionLevel="Private" keepAliveTimeout="0" passiveMode="true" shareSSLContext="true" />
+ </advancedOptions>
+ </fileTransfer>
+ </webServer>
+ </option>
+ </component>
+</project> \ No newline at end of file
diff --git a/app/session.php b/app/session.php
new file mode 100644
index 0000000..9f38ca4
--- /dev/null
+++ b/app/session.php
@@ -0,0 +1,34 @@
+<?php
+
+global $_CONFIG;
+$_CONFIG = json_decode(file_get_contents("/mnt/familine/private/FamilineConfig.json"), true);
+
+if ($_SERVER['REMOTE_ADDR'] !== "127.0.0.1" && $_SERVER['REMOTE_ADDR'] !== "::0") {
+ if (isset($_COOKIE['FL_SESSION_TOKEN'])) {
+ if (file_exists("/mnt/familine/private/tokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['FL_SESSION_TOKEN'])))) {
+ $_PROFILE = json_decode(file_get_contents("/mnt/familine/private/tokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['FL_SESSION_TOKEN']))), true);
+
+ if (isset($_PROFILE['familine'])) {
+ header("Location: https://" . $_CONFIG["Global"]["domain"] . "/welcome");
+ die();
+ }
+
+ $_USER = $_PROFILE['login'];
+ $_SUID = $_PROFILE['login'];
+ $_FULLNAME = $_PROFILE['name'];
+ } else {
+ header("Location: https://" . $_CONFIG["Global"]["domain"] . "/welcome");
+ die();
+ }
+ } else {
+ header("Location: https://" . $_CONFIG["Global"]["domain"] . "/welcome");
+ die();
+ }
+
+}
+
+if (isset($_PROFILE["projectRoles"]) && is_array($_PROFILE["projectRoles"]) && isset($_PROFILE["projectRoles"][0]) && is_array($_PROFILE["projectRoles"][0]) && isset($_PROFILE["projectRoles"][0]["role"]) && is_array($_PROFILE["projectRoles"][0]["role"]) && isset($_PROFILE["projectRoles"][0]["role"]["key"]) && is_string($_PROFILE["projectRoles"][0]["role"]["key"]) && $_PROFILE["projectRoles"][0]["role"]["key"] === "system-admin") {
+ $_ADMIN = true;
+} else {
+ $_ADMIN = false;
+}
diff --git a/dark.css b/dark.css
new file mode 100644
index 0000000..f5db643
--- /dev/null
+++ b/dark.css
@@ -0,0 +1,92 @@
+@media (prefers-color-scheme: dark) {
+
+ html, body {
+ background: black !important;
+ color: white !important;
+ }
+
+ #statusbar, #tabs {
+ background: #222 !important;
+ color: white !important;
+ }
+
+ .tab:not(.tab-active) img {
+ filter: invert(1) !important;
+ }
+
+ .loader {
+ background: rgba(10, 10, 10, .75) !important;
+ }
+
+ .loader img {
+ filter: invert(1) !important;
+ }
+
+ #tabs .tab.tab-active {
+ border-bottom-color: white !important;
+ }
+
+ .list-group-item {
+ background-color: #151515 !important;
+ }
+
+ .btn-light {
+ background: transparent !important;
+ color: white !important;
+ }
+
+ .dropdown-menu {
+ filter: invert(1) !important;
+ }
+
+ #panes {
+ background: black !important;
+ }
+
+ .list-group-item-action {
+ color: white !important;
+ }
+
+ .modal-content {
+ background-color: #151515 !important;
+ }
+
+ .modal-header button.close {
+ filter: invert(1) !important;
+ }
+
+ .modal-header {
+ border-bottom: 1px solid #222 !important;
+ }
+
+ .modal-footer {
+ border-top: 1px solid #222 !important;
+ }
+
+ #radio-bar {
+ background-color: whitesmoke !important;
+ color: black !important;
+ filter: invert(1) !important;
+ }
+
+ #radio-bar .badge {
+ filter: invert(1) !important;
+ }
+
+ .window-btn {
+ border-color: #333 !important;
+ }
+
+ .window-btn img {
+ filter: invert(1);
+ }
+
+ .window-btn:hover {
+ background: rgba(0, 0, 0, .25);
+ }
+
+ .window-btn:active {
+ background: rgba(0, 0, 0, .5);
+ }
+
+} \ No newline at end of file
diff --git a/favicon.svg b/favicon.svg
new file mode 100644
index 0000000..05c2b04
--- /dev/null
+++ b/favicon.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{clip-path:url(#SVGID_2_);}
+ .st2{clip-path:url(#SVGID_4_);}
+</style>
+<rect class="st0" width="24" height="24"/>
+<g>
+ <g>
+ <g>
+ <defs>
+ <path id="SVGID_1_" d="M4892.49,715.22C4892.49,321.85,5207,0,5591.41,0c384.41,0,698.93,321.85,698.93,715.22
+ s-314.52,715.22-698.93,715.22C5207,1430.45,4892.49,1108.6,4892.49,715.22z M6290.34,7152.24V5006.57H7164l-873.66-2717.85
+ c-104.84-286.09-349.46-500.66-663.98-500.66h-34.95c-314.52,0-559.14,214.57-663.98,500.66l-314.52,929.79
+ c384.41,214.57,629.03,607.94,629.03,1108.6V7188h1048.39V7152.24z M3669.37,3397.31c279.57,0,524.2-250.33,524.2-536.42
+ s-244.62-536.42-524.2-536.42s-524.2,250.33-524.2,536.42S3389.8,3397.31,3669.37,3397.31z M1223.12,1430.45
+ c384.41,0,698.93-321.85,698.93-715.22S1607.53,0,1223.12,0S524.2,321.85,524.2,715.22S838.71,1430.45,1223.12,1430.45z
+ M1922.05,7152.24V4648.96h524.2V2503.28c0-393.37-314.52-715.22-698.93-715.22H698.93C314.52,1788.06,0,2109.91,0,2503.28
+ v2145.67h524.2v2503.28H1922.05z M4193.56,7152.24V5721.79h349.46V4291.34c0-286.09-244.62-536.42-524.2-536.42H3319.9
+ c-279.57,0-524.2,250.33-524.2,536.42v1430.45h349.46v1430.45H4193.56z"/>
+ </defs>
+ <clipPath id="SVGID_2_">
+ <use xlink:href="#SVGID_1_" style="overflow:visible;"/>
+ </clipPath>
+ <g class="st1">
+ <g>
+ <g>
+ <defs>
+ <rect id="SVGID_3_" x="-1747.32" y="-1788.06" width="10658.63" height="10728.36"/>
+ </defs>
+ <clipPath id="SVGID_4_">
+ <use xlink:href="#SVGID_3_" style="overflow:visible;"/>
+ </clipPath>
+ <g class="st2">
+
+ <image style="overflow:visible;enable-background:new ;" width="67" height="67" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEAlgCWAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
+EAMCAwYAAAKNAAADPQAABNz/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
+Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
+JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAEMAQwMBIgACEQEDEQH/
+xAC5AAACAwEBAQAAAAAAAAAAAAAABQIDBgEEBwEAAwEBAQAAAAAAAAAAAAAAAwQFAgEAEAACAgED
+BAIBBQAAAAAAAAABAgADBBEFBhASExQhMSNBMhU1FhEAAgEBAwcGCQ0AAAAAAAAAAQIRAwAhEhAx
+QSIyEwQgUWFxkVIwoUJicqMUFUWBscHRgpKistIzg0Q1EgABAgMHAgcAAAAAAAAAAAABABEQMQIh
+QVGBEjJDYYIgcZGhIoNE/9oADAMBAAIRAxEAAAD6Ak9/zzjbpvkPQBndJlfV47l3i3RV3oDbmfyb
+xUCnH1R9KvQtrzHg0Vel+ZsACV8iteJVqErqZczbVGqhInGEXVNOKBZzQ5ba4xKrHhEh+V9g7zjB
+bqSrviZMUFYe0skHTU9AmpagMhAMD//aAAgBAgABBQAnSNYVlmQ7NRa5Mdvm1iZVWWNdBHRwe5at
+Tj0KAtQnirjD5rWVy1+2voIJZ9z/2gAIAQMAAQUAxMdbJbRV239yynIJeY+i1O3xmMBK3AulR1rs
+10ya3YnHad1kxSChTWeupl9CKsT90/W37n//2gAIAQEAAQUAm78lx8Bv9ZupfbOT15LZ24UYKWcg
+zWbG5C4NdiWpN2ymw9uJZ2RZWka2249OO5Dd05ZmBMYJESVpFSEQzjyhs2cm1bdAsRJWs0GjGEza
+sr18+cjGu5gRRFOkLxnhaFp/M2ePkuI4vEBndGeM0LTunqXeDkP9bNYTGaEwmbHi05m4eOuZ+N7e
+JbVZTYYYxhhnFtttpHTd+3X8M/H4j4Jb4u/D8XsdP//aAAgBAgIGPwBOvidI6LTWXeRgYSQLSgYS
+hPl05YeAl2LMPON+S5MkN/fD/9oACAEDAgY/ADVXtpLNiVZSKeoTAoUVWvIwpa+31gVQTLVClsGj
+aFLi98UabwYSRJygN3bNc6/Qhv8AsnD/2gAIAQEBBj8AsaFACvxIuYTCofOOnqFsUUgLtQKY8bT4
+7LR4xBRqNcKi7BPTOawNTWdtimM5+q0oqIugRJ7TYDiaYK95Lj2Gy1KbBkYSCMnEcQu2iwh5mY4F
+PyE2LMSzMZJN5JOk5Q1Vi5ChQTzKIAy1OGMlY3i8wgwe2RkTgl2qxDudGFT9J5bsfJpmOeSQMhky
+AigdGc8uk5OqxwN1Nd89+RvQXwG9nV9j3mn97ebn81k4sCabAIx5mEx2jwGbW9k3+HTg32f7t9m9
+NeWlGuCaYBYgGJw6D0W2F2cOYbPd6rVKGlhqk94Xixp1VKOtxU8p+NrKUNRcFJTcSpIYtHTAjKmL
+2SI/szjz+Rhvi3w/1tj/AJmHpx4v1W+G+utre6p83eR+C6y4Pdk/yYvs47py/wD/2Q==" transform="matrix(161.4882 0 0 165.2537 -1831.3508 -1959.8796)">
+ </image>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/icns/badge-filled.png b/icns/badge-filled.png
new file mode 100644
index 0000000..6b29fc8
--- /dev/null
+++ b/icns/badge-filled.png
Binary files differ
diff --git a/icns/badge-symbolic.png b/icns/badge-symbolic.png
new file mode 100644
index 0000000..93d28cf
--- /dev/null
+++ b/icns/badge-symbolic.png
Binary files differ
diff --git a/icns/badge.png b/icns/badge.png
new file mode 100644
index 0000000..339b169
--- /dev/null
+++ b/icns/badge.png
Binary files differ
diff --git a/icns/bucks.png b/icns/bucks.png
new file mode 100644
index 0000000..eb81f63
--- /dev/null
+++ b/icns/bucks.png
Binary files differ
diff --git a/icns/cinema-filled.png b/icns/cinema-filled.png
new file mode 100644
index 0000000..41b13f9
--- /dev/null
+++ b/icns/cinema-filled.png
Binary files differ
diff --git a/icns/cinema-symbolic.png b/icns/cinema-symbolic.png
new file mode 100644
index 0000000..d594e70
--- /dev/null
+++ b/icns/cinema-symbolic.png
Binary files differ
diff --git a/icns/cinema.png b/icns/cinema.png
new file mode 100644
index 0000000..4ba70ec
--- /dev/null
+++ b/icns/cinema.png
Binary files differ
diff --git a/icns/cloud-link.png b/icns/cloud-link.png
new file mode 100644
index 0000000..7ab6584
--- /dev/null
+++ b/icns/cloud-link.png
Binary files differ
diff --git a/icns/contacts-filled.png b/icns/contacts-filled.png
new file mode 100644
index 0000000..0129625
--- /dev/null
+++ b/icns/contacts-filled.png
Binary files differ
diff --git a/icns/contacts-symbolic.png b/icns/contacts-symbolic.png
new file mode 100644
index 0000000..aa88c7f
--- /dev/null
+++ b/icns/contacts-symbolic.png
Binary files differ
diff --git a/icns/contacts.png b/icns/contacts.png
new file mode 100644
index 0000000..ab2c527
--- /dev/null
+++ b/icns/contacts.png
Binary files differ
diff --git a/icns/famidata.png b/icns/famidata.png
new file mode 100644
index 0000000..4709e1d
--- /dev/null
+++ b/icns/famidata.png
Binary files differ
diff --git a/icns/familine-camera.svg b/icns/familine-camera.svg
new file mode 100644
index 0000000..c736d0c
--- /dev/null
+++ b/icns/familine-camera.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#808080;}
+ .st1{fill:none;}
+</style>
+<path class="st0" d="M18,10.5V6c0-1.1-0.9-2-2-2H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-4.5l4,4v-11L18,10.5z
+ M16,9.7V18H4V6h12V9.7z"/>
+<circle class="st0" cx="10" cy="10" r="2"/>
+<path class="st0" d="M14,15.4c0-0.8-0.5-1.5-1.2-1.9C11.9,13.2,11,13,10,13s-1.9,0.2-2.8,0.6c-0.7,0.3-1.2,1-1.2,1.9V16h8V15.4z"/>
+<g>
+ <rect class="st1" width="24" height="24"/>
+</g>
+</svg>
diff --git a/icns/familine-console.svg b/icns/familine-console.svg
new file mode 100644
index 0000000..a07610a
--- /dev/null
+++ b/icns/familine-console.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#808080;}
+</style>
+<path class="st0" d="M0,0h24v24H0V0z"/>
+<path class="st1" d="M19.4,13c0-0.3,0.1-0.6,0.1-1c0-0.3,0-0.7-0.1-1l2.1-1.6c0.2-0.1,0.2-0.4,0.1-0.6l-2-3.5
+ C19.6,5.1,19.4,5,19.2,5c-0.1,0-0.1,0-0.2,0l-2.5,1c-0.5-0.4-1.1-0.7-1.7-1l-0.4-2.7C14.5,2.2,14.3,2,14,2h-4C9.8,2,9.5,2.2,9.5,2.4
+ L9.1,5.1C8.5,5.3,8,5.7,7.4,6.1l-2.5-1C4.9,5,4.8,5,4.8,5C4.6,5,4.4,5.1,4.3,5.3l-2,3.5C2.2,8.9,2.3,9.2,2.5,9.4L4.6,11
+ c0,0.3-0.1,0.6-0.1,1c0,0.3,0,0.7,0.1,1l-2.1,1.6c-0.2,0.1-0.2,0.4-0.1,0.6l2,3.5C4.4,18.9,4.6,19,4.8,19c0.1,0,0.1,0,0.2,0l2.5-1
+ c0.5,0.4,1.1,0.7,1.7,1l0.4,2.6c0,0.2,0.2,0.4,0.5,0.4h4c0.3,0,0.5-0.2,0.5-0.4l0.4-2.6c0.6-0.3,1.2-0.6,1.7-1l2.5,1
+ c0.1,0,0.1,0,0.2,0c0.2,0,0.3-0.1,0.4-0.3l2-3.5c0.1-0.2,0.1-0.5-0.1-0.6L19.4,13z M17.5,11.3c0,0.3,0,0.5,0,0.7c0,0.2,0,0.4,0,0.7
+ l-0.1,1.1l0.9,0.7l1.1,0.8l-0.7,1.2l-1.3-0.5l-1-0.4l-0.9,0.7c-0.4,0.3-0.8,0.6-1.3,0.7l-1.1,0.4l-0.2,1.1L12.7,20h-1.4l-0.2-1.4
+ L11,17.5l-1.1-0.4c-0.4-0.2-0.8-0.4-1.2-0.7l-0.9-0.7l-1.1,0.4l-1.3,0.5l-0.7-1.2l1.1-0.8l0.9-0.7l-0.1-1.1c0-0.3-0.1-0.5-0.1-0.7
+ s0-0.4,0.1-0.7l0.1-1.1L5.8,9.4L4.7,8.6l0.7-1.2l1.3,0.5l1,0.4l0.9-0.7c0.4-0.3,0.8-0.6,1.3-0.7l1.1-0.4l0.2-1.1L11.3,4h1.4l0.2,1.3
+ L13,6.5l1.1,0.4c0.4,0.2,0.8,0.4,1.2,0.7l0.9,0.7l1.1-0.4l1.3-0.5l0.7,1.2l-1.1,0.9l-0.9,0.7C17.3,10.1,17.5,11.3,17.5,11.3z M12,8
+ c-2.2,0-4,1.8-4,4s1.8,4,4,4s4-1.8,4-4S14.2,8,12,8z M12,14c-1.1,0-2-0.9-2-2s0.9-2,2-2s2,0.9,2,2S13.1,14,12,14z"/>
+</svg>
diff --git a/icns/familine-docs.svg b/icns/familine-docs.svg
new file mode 100644
index 0000000..a351c85
--- /dev/null
+++ b/icns/familine-docs.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#EF3D3B;}
+</style>
+<path class="st0" d="M0,0h7164v7188H0V0z"/>
+<path class="st1" d="M2388,4792h2388v599H2388V4792z M2388,3594h2388v599H2388V3594z M4179,599H1791c-328.35,0-597,269.55-597,599
+ v4792c0,329.45,268.65,599,597,599h3582c328.35,0,597-269.55,597-599V2396L4179,599z M5373,5990H1791V1198h2089.5v1497.5H5373V5990z
+ "/>
+</svg>
diff --git a/icns/familine-help.svg b/icns/familine-help.svg
new file mode 100644
index 0000000..64873a9
--- /dev/null
+++ b/icns/familine-help.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#EF713B;}
+</style>
+<path class="st0" d="M0,0h7164v7188H0V0z"/>
+<path class="st1" d="M5373,599H1791c-328.35,0-597,269.55-597,599v4792c0,329.45,268.65,599,597,599h3582
+ c328.35,0,597-269.55,597-599V1198C5970,868.55,5701.35,599,5373,599z M2686.5,1198h597v1497.5L2985,2455.9l-298.5,239.6V1198z
+ M5373,5990H1791V1198h298.5v2695.5l895.5-688.85l895.5,688.85V1198H5373V5990z"/>
+</svg>
diff --git a/icns/familine-money.svg b/icns/familine-money.svg
new file mode 100644
index 0000000..f0c8227
--- /dev/null
+++ b/icns/familine-money.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#EFE63B;}
+</style>
+<path class="st0" d="M0,0h7164v7188H0V0z"/>
+<path class="st1" d="M6268.5,2186.35V1497.5c0-329.45-268.65-599-597-599h-4179c-328.35,0-597,269.55-597,599v4193
+ c0,329.45,268.65,599,597,599h4179c328.35,0,597-269.55,597-599v-688.85c179.1-119.8,298.5-299.5,298.5-509.15v-1797
+ C6567,2485.85,6447.6,2276.2,6268.5,2186.35z M5970,2695.5v1797H3880.5v-1797H5970z M1492.5,5690.5v-4193h4179v599h-1791
+ c-328.35,0-597,269.55-597,599v1797c0,329.45,268.65,599,597,599h1791v599H1492.5z"/>
+<ellipse class="st1" cx="4776" cy="3594" rx="447.75" ry="449.25"/>
+</svg>
diff --git a/icns/familine-movies.svg b/icns/familine-movies.svg
new file mode 100644
index 0000000..25db0e5
--- /dev/null
+++ b/icns/familine-movies.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#41EF3B;}
+</style>
+<path class="st0" d="M0,0h7164v7188H0V0z"/>
+<path class="st1" d="M5373,898.5v599h-597v-599H2388v599h-597v-599h-597v5391h597v-599h597v599h2388v-599h597v599h597v-5391H5373z
+ M2388,5091.5h-597v-599h597V5091.5z M2388,3893.5h-597v-599h597V3893.5z M2388,2695.5h-597v-599h597V2695.5z M4179,5690.5H2985
+ v-4193h1194V5690.5z M5373,5091.5h-597v-599h597V5091.5z M5373,3893.5h-597v-599h597V3893.5z M5373,2695.5h-597v-599h597V2695.5z"/>
+</svg>
diff --git a/icns/familine-photos.svg b/icns/familine-photos.svg
new file mode 100644
index 0000000..ff9dd77
--- /dev/null
+++ b/icns/familine-photos.svg
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#3BEF80;}
+</style>
+<path class="st0" d="M0,0h7164v7188H0V0z"/>
+<path class="st1" d="M5581.95,3713.8c-89.55-59.9-179.1-89.85-268.65-119.8c89.55-29.95,179.1-59.9,268.65-119.8
+ c567.15-329.45,895.5-928.45,895.5-1557.4c-268.65-149.75-597-239.6-895.5-239.6s-597,89.85-895.5,239.6
+ c-89.55,59.9-149.25,89.85-238.8,149.75c29.85-89.85,29.85-179.7,29.85-269.55c0-658.9-358.2-1257.9-895.5-1557.4
+ c-537.3,299.5-895.5,898.5-895.5,1557.4c0,89.85,0,179.7,29.85,269.55c-89.55-29.95-149.25-89.85-238.8-149.75
+ c-268.65-149.75-597-239.6-895.5-239.6c-328.35,0-626.85,89.85-895.5,239.6c0,628.95,328.35,1227.95,895.5,1557.4
+ c89.55,59.9,179.1,89.85,268.65,119.8c-89.55,29.95-179.1,59.9-268.65,119.8c-567.15,329.45-895.5,928.45-895.5,1557.4
+ c268.65,149.75,567.15,239.6,895.5,239.6c298.5,0,626.85-89.85,895.5-239.6c89.55-59.9,149.25-119.8,238.8-149.75
+ c-29.85,89.85-29.85,179.7-29.85,269.55c0,658.9,358.2,1227.95,895.5,1557.4c537.3-299.5,895.5-898.5,895.5-1557.4
+ c0-89.85,0-179.7-29.85-299.5c59.7,59.9,149.25,119.8,238.8,149.75c268.65,149.75,597,239.6,895.5,239.6s626.85-89.85,895.5-239.6
+ C6477.45,4642.25,6149.1,4043.25,5581.95,3713.8z M4835.7,2545.75c59.7-59.9,119.4-89.85,149.25-119.8
+ c179.1-89.85,388.05-149.75,597-149.75c89.55,0,149.25,0,238.8,29.95c-89.55,269.55-268.65,509.15-537.3,658.9
+ c-59.7,29.95-119.4,59.9-179.1,89.85l-417.9,149.75c-59.7-149.75-119.4-269.55-208.95-359.4
+ C4477.5,2815.3,4835.7,2545.75,4835.7,2545.75z M3582,1018.3c179.1,209.65,298.5,479.2,298.5,778.7c0,59.9,0,119.8-29.85,179.7
+ l-59.7,419.3c-59.7,0-149.25,0-208.95,0s-149.25,0-208.95,29.95l-59.7-419.3c-29.85-89.85-29.85-149.75-29.85-209.65
+ C3283.5,1497.5,3402.9,1227.95,3582,1018.3z M1343.25,2306.15c89.55-29.95,149.25-29.95,238.8-29.95c208.95,0,417.9,59.9,597,149.75
+ c59.7,29.95,89.55,59.9,149.25,119.8l328.35,299.5c-89.55,119.8-149.25,239.6-208.95,359.4l-417.9-149.75
+ c-59.7-59.9-89.55-59.9-149.25-89.85C1611.9,2815.3,1432.8,2575.7,1343.25,2306.15z M2328.3,4642.25
+ c-59.7,59.9-119.4,89.85-149.25,119.8c-179.1,89.85-388.05,149.75-597,149.75c-89.55,0-149.25,0-238.8-29.95
+ c89.55-269.55,268.65-509.15,537.3-658.9c59.7-29.95,119.4-59.9,179.1-89.85l417.9-149.75c59.7,149.75,119.4,269.55,208.95,359.4
+ C2686.5,4372.7,2328.3,4642.25,2328.3,4642.25z M3582,6169.7c-179.1-209.65-298.5-509.15-298.5-778.7c0-59.9,0-119.8,29.85-179.7
+ l59.7-419.3c59.7,0,149.25,29.95,208.95,29.95s149.25,0,208.95-29.95l59.7,419.3c0,59.9,29.85,119.8,29.85,179.7
+ C3880.5,5690.5,3761.1,5960.05,3582,6169.7z M5581.95,4911.8c-208.95,0-417.9-59.9-597-149.75c-59.7-29.95-89.55-59.9-149.25-89.85
+ l-328.35-299.5c89.55-119.8,149.25-239.6,208.95-359.4l417.9,149.75c59.7,29.95,119.4,59.9,179.1,89.85
+ c268.65,149.75,447.75,389.35,537.3,658.9C5731.2,4911.8,5671.5,4911.8,5581.95,4911.8z"/>
+</svg>
diff --git a/icns/familine-planning.svg b/icns/familine-planning.svg
new file mode 100644
index 0000000..a0f6833
--- /dev/null
+++ b/icns/familine-planning.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#3BE0EF;}
+</style>
+<path class="st0" d="M0,0h7164v7188H0V0z"/>
+<path class="st1" d="M5671.5,898.5H5373v-599h-597v599H2388v-599h-597v599h-298.5c-328.35,0-597,269.55-597,599v4193
+ c0,329.45,268.65,599,597,599h4179c328.35,0,597-269.55,597-599v-4193C6268.5,1168.05,5999.85,898.5,5671.5,898.5z M5671.5,5690.5
+ h-4179v-2995h4179V5690.5z M1492.5,2096.5v-599h4179v599H1492.5z M2089.5,3294.5h2985v599h-2985V3294.5z M2089.5,4492.5H4179v599
+ H2089.5V4492.5z"/>
+</svg>
diff --git a/icns/familine-review.svg b/icns/familine-review.svg
new file mode 100644
index 0000000..fa60445
--- /dev/null
+++ b/icns/familine-review.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#35B7FF;}
+</style>
+<path class="st0" d="M0,0h24v24H0V0z"/>
+<path class="st1" d="M19.4,10c-0.7-3.4-3.7-6-7.4-6C9.1,4,6.6,5.6,5.4,8C2.3,8.4,0,10.9,0,14c0,3.3,2.7,6,6,6h13c2.8,0,5-2.2,5-5
+ C24,12.4,22,10.2,19.4,10z M19,18H6c-2.2,0-4-1.8-4-4s1.8-4,4-4s4,1.8,4,4h2c0-2.8-1.9-5.1-4.4-5.8C8.6,6.9,10.2,6,12,6
+ c3,0,5.5,2.5,5.5,5.5V12H19c1.6,0,3,1.4,3,3S20.6,18,19,18z"/>
+</svg>
diff --git a/icns/familine-share.svg b/icns/familine-share.svg
new file mode 100644
index 0000000..08995e5
--- /dev/null
+++ b/icns/familine-share.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#953BEF;}
+</style>
+<path class="st0" d="M0,0h7164v7188H0V0z"/>
+<path class="st1" d="M6268.5,898.5h-5373c-328.35,0-597,269.55-597,599v4193c0,329.45,268.65,599,597,599h5373
+ c328.35,0,597-269.55,597-599v-4193C6865.5,1168.05,6596.85,898.5,6268.5,898.5z M6268.5,5690.5h-5373v-4193h5373V5690.5z
+ M2985,3594h-597l1194-1198l1194,1198h-597v1198H2985V3594z"/>
+</svg>
diff --git a/icns/familine-you.svg b/icns/familine-you.svg
new file mode 100644
index 0000000..6c3a35d
--- /dev/null
+++ b/icns/familine-you.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#EF3BD4;}
+</style>
+<path class="st0" d="M0,0h7164v7188H0V0z"/>
+<path class="st1" d="M5671.5,599h-4179c-328.35,0-597,269.55-597,599v4193c0,329.45,268.65,599,597,599h1194l895.5,898.5
+ l895.5-898.5h1194c328.35,0,597-269.55,597-599V1198C6268.5,868.55,5999.85,599,5671.5,599z M5671.5,5391H4238.7l-179.1,179.7
+ L3582,6049.9l-477.6-479.2L2925.3,5391H1492.5V1198h4179V5391z M3582,3294.5c477.6,0,895.5-419.3,895.5-898.5
+ s-417.9-898.5-895.5-898.5s-895.5,389.35-895.5,898.5S3104.4,3294.5,3582,3294.5z M3582,2096.5c179.1,0,298.5,119.8,298.5,299.5
+ c0,179.7-119.4,299.5-298.5,299.5s-298.5-119.8-298.5-299.5S3402.9,2096.5,3582,2096.5z M5373,4672.2
+ c0-748.75-1194-1078.2-1791-1078.2s-1791,329.45-1791,1078.2v419.3h3582V4672.2z M2537.25,4492.5
+ C2746.2,4342.75,3193.95,4193,3582,4193s835.8,149.75,1044.75,299.5H2537.25z"/>
+</svg>
diff --git a/icns/familine.svg b/icns/familine.svg
new file mode 100644
index 0000000..05c2b04
--- /dev/null
+++ b/icns/familine.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 7164 7188" style="enable-background:new 0 0 7164 7188;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{clip-path:url(#SVGID_2_);}
+ .st2{clip-path:url(#SVGID_4_);}
+</style>
+<rect class="st0" width="24" height="24"/>
+<g>
+ <g>
+ <g>
+ <defs>
+ <path id="SVGID_1_" d="M4892.49,715.22C4892.49,321.85,5207,0,5591.41,0c384.41,0,698.93,321.85,698.93,715.22
+ s-314.52,715.22-698.93,715.22C5207,1430.45,4892.49,1108.6,4892.49,715.22z M6290.34,7152.24V5006.57H7164l-873.66-2717.85
+ c-104.84-286.09-349.46-500.66-663.98-500.66h-34.95c-314.52,0-559.14,214.57-663.98,500.66l-314.52,929.79
+ c384.41,214.57,629.03,607.94,629.03,1108.6V7188h1048.39V7152.24z M3669.37,3397.31c279.57,0,524.2-250.33,524.2-536.42
+ s-244.62-536.42-524.2-536.42s-524.2,250.33-524.2,536.42S3389.8,3397.31,3669.37,3397.31z M1223.12,1430.45
+ c384.41,0,698.93-321.85,698.93-715.22S1607.53,0,1223.12,0S524.2,321.85,524.2,715.22S838.71,1430.45,1223.12,1430.45z
+ M1922.05,7152.24V4648.96h524.2V2503.28c0-393.37-314.52-715.22-698.93-715.22H698.93C314.52,1788.06,0,2109.91,0,2503.28
+ v2145.67h524.2v2503.28H1922.05z M4193.56,7152.24V5721.79h349.46V4291.34c0-286.09-244.62-536.42-524.2-536.42H3319.9
+ c-279.57,0-524.2,250.33-524.2,536.42v1430.45h349.46v1430.45H4193.56z"/>
+ </defs>
+ <clipPath id="SVGID_2_">
+ <use xlink:href="#SVGID_1_" style="overflow:visible;"/>
+ </clipPath>
+ <g class="st1">
+ <g>
+ <g>
+ <defs>
+ <rect id="SVGID_3_" x="-1747.32" y="-1788.06" width="10658.63" height="10728.36"/>
+ </defs>
+ <clipPath id="SVGID_4_">
+ <use xlink:href="#SVGID_3_" style="overflow:visible;"/>
+ </clipPath>
+ <g class="st2">
+
+ <image style="overflow:visible;enable-background:new ;" width="67" height="67" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEAlgCWAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA
+EAMCAwYAAAKNAAADPQAABNz/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
+Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
+JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAEMAQwMBIgACEQEDEQH/
+xAC5AAACAwEBAQAAAAAAAAAAAAAABQIDBgEEBwEAAwEBAQAAAAAAAAAAAAAAAwQFAgEAEAACAgED
+BAIBBQAAAAAAAAABAgADBBEFBhASExQhMSNBMhU1FhEAAgEBAwcGCQ0AAAAAAAAAAQIRAwAhEhAx
+QSIyEwQgUWFxkVIwoUJicqMUFUWBscHRgpKistIzg0Q1EgABAgMHAgcAAAAAAAAAAAABABEQMQIh
+QVGBEjJDYYIgcZGhIoNE/9oADAMBAAIRAxEAAAD6Ak9/zzjbpvkPQBndJlfV47l3i3RV3oDbmfyb
+xUCnH1R9KvQtrzHg0Vel+ZsACV8iteJVqErqZczbVGqhInGEXVNOKBZzQ5ba4xKrHhEh+V9g7zjB
+bqSrviZMUFYe0skHTU9AmpagMhAMD//aAAgBAgABBQAnSNYVlmQ7NRa5Mdvm1iZVWWNdBHRwe5at
+Tj0KAtQnirjD5rWVy1+2voIJZ9z/2gAIAQMAAQUAxMdbJbRV239yynIJeY+i1O3xmMBK3AulR1rs
+10ya3YnHad1kxSChTWeupl9CKsT90/W37n//2gAIAQEAAQUAm78lx8Bv9ZupfbOT15LZ24UYKWcg
+zWbG5C4NdiWpN2ymw9uJZ2RZWka2249OO5Dd05ZmBMYJESVpFSEQzjyhs2cm1bdAsRJWs0GjGEza
+sr18+cjGu5gRRFOkLxnhaFp/M2ePkuI4vEBndGeM0LTunqXeDkP9bNYTGaEwmbHi05m4eOuZ+N7e
+JbVZTYYYxhhnFtttpHTd+3X8M/H4j4Jb4u/D8XsdP//aAAgBAgIGPwBOvidI6LTWXeRgYSQLSgYS
+hPl05YeAl2LMPON+S5MkN/fD/9oACAEDAgY/ADVXtpLNiVZSKeoTAoUVWvIwpa+31gVQTLVClsGj
+aFLi98UabwYSRJygN3bNc6/Qhv8AsnD/2gAIAQEBBj8AsaFACvxIuYTCofOOnqFsUUgLtQKY8bT4
+7LR4xBRqNcKi7BPTOawNTWdtimM5+q0oqIugRJ7TYDiaYK95Lj2Gy1KbBkYSCMnEcQu2iwh5mY4F
+PyE2LMSzMZJN5JOk5Q1Vi5ChQTzKIAy1OGMlY3i8wgwe2RkTgl2qxDudGFT9J5bsfJpmOeSQMhky
+AigdGc8uk5OqxwN1Nd89+RvQXwG9nV9j3mn97ebn81k4sCabAIx5mEx2jwGbW9k3+HTg32f7t9m9
+NeWlGuCaYBYgGJw6D0W2F2cOYbPd6rVKGlhqk94Xixp1VKOtxU8p+NrKUNRcFJTcSpIYtHTAjKmL
+2SI/szjz+Rhvi3w/1tj/AJmHpx4v1W+G+utre6p83eR+C6y4Pdk/yYvs47py/wD/2Q==" transform="matrix(161.4882 0 0 165.2537 -1831.3508 -1959.8796)">
+ </image>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/icns/help-filled.png b/icns/help-filled.png
new file mode 100644
index 0000000..68c9bde
--- /dev/null
+++ b/icns/help-filled.png
Binary files differ
diff --git a/icns/help-symbolic.png b/icns/help-symbolic.png
new file mode 100644
index 0000000..d34d296
--- /dev/null
+++ b/icns/help-symbolic.png
Binary files differ
diff --git a/icns/help.png b/icns/help.png
new file mode 100644
index 0000000..48351c8
--- /dev/null
+++ b/icns/help.png
Binary files differ
diff --git a/icns/home-filled.png b/icns/home-filled.png
new file mode 100644
index 0000000..1b60d9c
--- /dev/null
+++ b/icns/home-filled.png
Binary files differ
diff --git a/icns/home-symbolic.png b/icns/home-symbolic.png
new file mode 100644
index 0000000..245c1ed
--- /dev/null
+++ b/icns/home-symbolic.png
Binary files differ
diff --git a/icns/home.png b/icns/home.png
new file mode 100644
index 0000000..2ea5ba9
--- /dev/null
+++ b/icns/home.png
Binary files differ
diff --git a/icns/money-filled.png b/icns/money-filled.png
new file mode 100644
index 0000000..88ffac6
--- /dev/null
+++ b/icns/money-filled.png
Binary files differ
diff --git a/icns/money-symbolic.png b/icns/money-symbolic.png
new file mode 100644
index 0000000..0cdf491
--- /dev/null
+++ b/icns/money-symbolic.png
Binary files differ
diff --git a/icns/money.png b/icns/money.png
new file mode 100644
index 0000000..f54c90f
--- /dev/null
+++ b/icns/money.png
Binary files differ
diff --git a/icns/music.png b/icns/music.png
new file mode 100644
index 0000000..c75888a
--- /dev/null
+++ b/icns/music.png
Binary files differ
diff --git a/icns/open-book-filled.png b/icns/open-book-filled.png
new file mode 100644
index 0000000..767c991
--- /dev/null
+++ b/icns/open-book-filled.png
Binary files differ
diff --git a/icns/open-book-symbolic.png b/icns/open-book-symbolic.png
new file mode 100644
index 0000000..7513aa9
--- /dev/null
+++ b/icns/open-book-symbolic.png
Binary files differ
diff --git a/icns/open-book.png b/icns/open-book.png
new file mode 100644
index 0000000..5310c50
--- /dev/null
+++ b/icns/open-book.png
Binary files differ
diff --git a/icns/opus.svg b/icns/opus.svg
new file mode 100644
index 0000000..9e18abe
--- /dev/null
+++ b/icns/opus.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="3600" height="2045.1">
+ <defs>
+ <linearGradient y1="1" x2="0" id="linearGradient1">
+ <stop style="stop-color:#8e8e8e"/>
+ <stop style="stop-color:#b5b5b5" offset="1"/>
+ </linearGradient>
+ <linearGradient x2="0" y2="1" id="linearGradient2">
+ <stop style="stop-color:#484848"/>
+ <stop style="stop-color:#000" offset="1"/>
+ </linearGradient>
+ </defs>
+ <path d="m 2573.55,139.96167 c -74.12,-61.7 -188.22,-103.01 -342.02,-124.08 l -113.02,359.34 c -2.44,13.19 -6.64,28.16 -13.15,45.41 -11.54,28.82 -25.43,52.57 -41.75,71.27 -16.34,18.73 -34.63,33.34 -54.89,44 -20.28,10.58 -42.32,17.9 -66.14,21.93 -23.83,4.01 -48.47,5.26 -73.93,3.78 -25.49,-1.48 -47.17,-4.95 -65.01,-10.42 -17.86,-5.46 -34.28,-14.52 -49.26,-27.2 -11.07,-12.45 -17.51,-28.77 -19.27,-49.02 -1.77,-20.24 3.14,-45.27 14.71,-75.09 10.36,-25.91 23.46,-48.51 39.34,-67.71 15.86,-19.21 34.42,-34.11 55.65,-44.67 20.27,-10.59 42.06,-17.68 65.39,-21.25 23.27,-3.55 49.14,-4.48 77.55,-2.83 23.52,1.39 45.42,4.85 65.74,10.48 9.64,2.64 18.08,6.13 25.42,10.33 l 86.76,-275.91 c -21.41,-2.02 -43.32,-3.79 -66.09,-5.1 -219.01,-12.79 -403.08,12.51 -552.29,75.76 -149.18,63.31 -248.65,157.15 -298.33,281.55 -14.91,38.14 -22.92,74.08 -24.1,107.85 -14.35,244.68 142.95,382.45 240.07,443.73 38.97,26.09 73.62,39.01 73.62,39.01 l 44.51,-142.24 13.16,-34.96 c 58.59,11.08 123.75,18.79 195.73,22.97 220.53,12.87 405.39,-12.32 554.58,-75.64 149.16,-63.25 247.8,-156.38 295.91,-279.42 48.08,-122.96 25.16,-223.58 -68.8,-301.82" style="fill:url(#linearGradient1)"/>
+ <path d="m 2695.31,1395 c -25.1,77.18 -82.3,138.07 -171.56,182.7 -89.25,44.621 -202.22,66.942 -338.9,66.942 -134.84,0 -232.92,-22.079 -294.3,-66.258 -61.36,-44.153 -79.04,-105.282 -52.99,-183.383 l 75.31,-232.91 256.62,0 -72.52,231.511 c -9.31,28.829 -12.32,52.79 -9.06,71.829 3.25,19.07 10.45,34.171 21.62,45.332 13.94,11.129 29.5,18.8 46.72,22.988 17.19,4.191 37.87,6.293 62.06,6.293 24.18,0 47.42,-2.551 69.74,-7.692 22.31,-5.089 42.75,-13.23 61.37,-24.378 18.58,-11.161 35.09,-26.024 49.51,-44.633 14.4,-18.59 26.26,-41.86 35.57,-69.739 l 75.31,-231.511 256.63,0 -71.13,232.91" style="fill:url(#linearGradient2)"/>
+ <path d="m 607.93,1405.4437 c -9.309,29.77 -20.696,52.996 -34.168,69.738 -13.492,16.739 -30.465,31.16 -50.907,43.231 -17.679,11.16 -37.652,18.828 -59.964,23.019 -22.317,4.192 -44.629,6.27 -66.957,6.27 -26.969,0 -49.993,-2.309 -69.036,-6.969 -19.07,-4.652 -34.168,-12.562 -45.332,-23.711 -12.097,-11.16 -19.054,-26.262 -20.921,-45.328 -1.875,-19.043 1.394,-41.141 9.769,-66.25 9.293,-28.801 21.613,-52.754 36.965,-71.832 15.336,-19.039 32.293,-34.172 50.902,-45.328 21.383,-11.152 42.063,-18.82 62.067,-23.012 19.988,-4.191 42.062,-6.269 66.254,-6.269 24.16,0 46.027,2.57 65.546,7.668 19.528,5.121 34.864,13.25 46.028,24.402 11.148,11.168 17.886,26.059 20.215,44.629 2.308,18.609 -1.172,41.859 -10.461,69.742 z m 260.816,-1.402 c 25.102,-77.16 7.426,-138.071 -53.008,-182.7 -60.445,-44.628 -158.996,-66.949 -295.676,-66.949 -134.832,0 -246.855,22.098 -336.113,66.25 -89.277,44.168 -146.933,105.309 -172.953,183.399 -25.102,77.199 -7.2148,137.859 53.695,182.011 60.895,44.18 159.219,66.258 294.98,66.258 135.754,0 248.258,-22.078 337.531,-66.258 89.262,-44.152 146.434,-104.812 171.543,-182.011" style="fill:url(#linearGradient2)"/>
+ <path d="m 3101.4,1268.0727 c 29.27,-6.992 90.41,-10.461 183.39,-10.461 48.34,0 95.06,4.871 140.18,14.648 45.07,9.75 90.41,22.09 135.97,36.961 l 39.06,-118.558 c -26.98,-7.442 -66.25,-14.871 -117.86,-22.313 -51.59,-7.437 -106.7,-11.156 -165.26,-11.156 -175.75,0 -304.05,15.117 -384.94,45.328 -80.89,30.219 -128.79,68.11 -143.66,113.66 -11.15,34.41 -3.48,63.461 23.02,87.168 26.51,23.711 73.22,41.153 140.16,52.293 25.11,4.668 66.25,8.379 123.43,11.18 57.18,2.789 94.6,5.559 112.28,8.359 37.17,3.731 62.05,8.36 74.62,13.95 12.54,5.582 16.95,13.941 13.24,25.109 -4.66,13.031 -19.76,22.793 -45.33,29.281 -25.59,6.52 -63,9.762 -112.26,9.762 -7.7,0 -15.13,-0.031 -22.42,-0.07 -18.46,-1 -38.57,-2.723 -57.91,-4.75 -20.6,-2.204 -41.18,-4.864 -61.61,-7.954 -40.9,-6.199 -81.32,-14.187 -120.58,-24.398 -39.21,-10.219 -77.34,-22.66 -112.6,-38.129 -4.74,-2.082 -9.31,-4.332 -13.93,-6.543 -24.76,39.781 -59.05,74.512 -102.7,103.961 22.59,10.852 45.39,19.762 68.07,27.422 45.2,15.059 90.34,25.199 135.25,32.66 44.94,7.41 89.7,12.027 134.31,14.719 22.31,1.32 44.6,2.14 66.91,2.48 19.67,0.262 38.82,0.192 59.02,-0.449 122.16,-0.73 223.18,-15.312 302.94,-43.859 81.8,-29.293 130.62,-68.102 146.44,-116.453 11.16,-33.481 4.41,-61.368 -20.22,-83.688 -24.66,-22.312 -68.13,-38.57 -130.4,-48.82 -28.83,-3.711 -57.68,-7.18 -86.47,-10.449 -28.84,-3.25 -55.33,-6.282 -79.51,-9.071 -95.77,-6.5 -149.24,-12.551 -160.39,-18.133 -11.16,-5.578 -14.88,-13.937 -11.16,-25.109 4.65,-12.078 21.62,-21.617 50.92,-28.578" style="fill:url(#linearGradient2)"/>
+ <path d="m 1728.38,1222.0417 c -60.91,-44.149 -159.23,-66.25 -294.98,-66.25 -135.77,0 -248.26,22.101 -337.52,66.25 -89.25,44.172 -144,104.152 -169.103,181.308 l -127.976,395.391 c -52.606,176.312 175.261,246.121 175.261,246.121 l 82.358,-267.18 c 5.92,-19.832 11.92,-39.64 17.81,-59.492 l 16.86,-55.308 c 6.03,-18.321 12.06,-36.622 18.49,-54.809 l 59.72,-163.109 14.29,-37.18 c 0.51,-1.723 0.99,-3.391 1.55,-5.133 8.36,-25.09 19.53,-47.18 33.47,-66.238 13.95,-19.051 30.69,-34.172 50.21,-45.34 18.59,-11.152 38.82,-19.039 60.67,-23.711 21.83,-4.641 46.25,-6.961 73.22,-6.961 22.31,0 43.25,2.082 62.77,6.27 19.52,4.191 34.38,11.863 44.63,23.011 13.01,12.09 20.68,26.5 23.01,43.231 2.3,16.75 -1.18,39.988 -10.46,69.738 -9.31,27.902 -21.17,51.16 -35.57,69.731 -14.42,18.628 -30.91,33.48 -49.51,44.64 -18.61,11.149 -39.04,19.309 -61.36,24.41 -22.31,5.11 -45.58,7.66 -69.73,7.66 -24.2,0 -44.87,-2.082 -62.07,-6.269 -17.21,-4.191 -33.26,-11.852 -48.13,-23.02 -1.12,-1.121 -2,-2.472 -3.04,-3.66 l -36.74,106.578 c -2.06,6.141 -4.03,12.282 -6.01,18.422 34.79,7.078 75.07,11.301 121.11,12.559 136.68,0 249.65,-22.309 338.93,-66.942 89.25,-44.636 146.43,-105.519 171.54,-182.718 25.11,-77.16 7.18,-137.828 -53.7,-182" style="fill:url(#linearGradient2)"/>
+</svg> \ No newline at end of file
diff --git a/icns/pause-filled.png b/icns/pause-filled.png
new file mode 100644
index 0000000..01c3a52
--- /dev/null
+++ b/icns/pause-filled.png
Binary files differ
diff --git a/icns/pause-symbolic.png b/icns/pause-symbolic.png
new file mode 100644
index 0000000..99b9d7e
--- /dev/null
+++ b/icns/pause-symbolic.png
Binary files differ
diff --git a/icns/pip.png b/icns/pip.png
new file mode 100644
index 0000000..3f9a6bf
--- /dev/null
+++ b/icns/pip.png
Binary files differ
diff --git a/icns/play-filled.png b/icns/play-filled.png
new file mode 100644
index 0000000..823cf38
--- /dev/null
+++ b/icns/play-filled.png
Binary files differ
diff --git a/icns/play-symbolic.png b/icns/play-symbolic.png
new file mode 100644
index 0000000..289f629
--- /dev/null
+++ b/icns/play-symbolic.png
Binary files differ
diff --git a/icns/radio-filled.png b/icns/radio-filled.png
new file mode 100644
index 0000000..b952384
--- /dev/null
+++ b/icns/radio-filled.png
Binary files differ
diff --git a/icns/radio-symbolic.png b/icns/radio-symbolic.png
new file mode 100644
index 0000000..5003c35
--- /dev/null
+++ b/icns/radio-symbolic.png
Binary files differ
diff --git a/icns/radio.png b/icns/radio.png
new file mode 100644
index 0000000..6891474
--- /dev/null
+++ b/icns/radio.png
Binary files differ
diff --git a/icns/settings-filled.png b/icns/settings-filled.png
new file mode 100644
index 0000000..f9aeffe
--- /dev/null
+++ b/icns/settings-filled.png
Binary files differ
diff --git a/icns/settings-symbolic.png b/icns/settings-symbolic.png
new file mode 100644
index 0000000..fe7a7e7
--- /dev/null
+++ b/icns/settings-symbolic.png
Binary files differ
diff --git a/icns/settings.png b/icns/settings.png
new file mode 100644
index 0000000..da4dd81
--- /dev/null
+++ b/icns/settings.png
Binary files differ
diff --git a/icns/share-filled.png b/icns/share-filled.png
new file mode 100644
index 0000000..956d7d6
--- /dev/null
+++ b/icns/share-filled.png
Binary files differ
diff --git a/icns/share-symbolic.png b/icns/share-symbolic.png
new file mode 100644
index 0000000..dd273e4
--- /dev/null
+++ b/icns/share-symbolic.png
Binary files differ
diff --git a/icns/share.png b/icns/share.png
new file mode 100644
index 0000000..66b2f45
--- /dev/null
+++ b/icns/share.png
Binary files differ
diff --git a/icns/solve-filled.png b/icns/solve-filled.png
new file mode 100644
index 0000000..e5fcbbb
--- /dev/null
+++ b/icns/solve-filled.png
Binary files differ
diff --git a/icns/solve-symbolic.png b/icns/solve-symbolic.png
new file mode 100644
index 0000000..eb94636
--- /dev/null
+++ b/icns/solve-symbolic.png
Binary files differ
diff --git a/icns/solve.png b/icns/solve.png
new file mode 100644
index 0000000..e55fd0a
--- /dev/null
+++ b/icns/solve.png
Binary files differ
diff --git a/icns/speaker.png b/icns/speaker.png
new file mode 100644
index 0000000..0d297ea
--- /dev/null
+++ b/icns/speaker.png
Binary files differ
diff --git a/icns/window-close.png b/icns/window-close.png
new file mode 100644
index 0000000..648e661
--- /dev/null
+++ b/icns/window-close.png
Binary files differ
diff --git a/icns/window-maximize.png b/icns/window-maximize.png
new file mode 100644
index 0000000..da48657
--- /dev/null
+++ b/icns/window-maximize.png
Binary files differ
diff --git a/icns/window-minimize.png b/icns/window-minimize.png
new file mode 100644
index 0000000..8a4716e
--- /dev/null
+++ b/icns/window-minimize.png
Binary files differ
diff --git a/icns/window-reduce.png b/icns/window-reduce.png
new file mode 100644
index 0000000..8093d6e
--- /dev/null
+++ b/icns/window-reduce.png
Binary files differ
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..009d90b
--- /dev/null
+++ b/index.php
@@ -0,0 +1,98 @@
+<?php
+
+require_once $_SERVER['DOCUMENT_ROOT'] . "/private/session.php";
+
+/** @var string $_FULLNAME
+ * @var string $_USER
+ * @var array $_PROFILE
+ * @var boolean $_ADMIN
+ * @var array $_CONFIG
+ */
+
+?>
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Familine</title>
+ <link rel="icon" href="/favicon.svg">
+ <link rel="stylesheet" href="/styles.css">
+ <?= strpos($_SERVER['HTTP_USER_AGENT'], "+Familine/") !== false ? '<link rel="stylesheet" href="/native.css">' : "" ?>
+ <?= strpos($_SERVER['HTTP_USER_AGENT'], "+Familine/") !== false ? '<script>$ = require(\'jquery\');jQuery = require(\'jquery\');</script>' : '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>' ?>
+</head>
+<body>
+ <div class='progress' style="display:none;" id="progress_div">
+ <div class='bar' id='bar1'></div>
+ <div class='percent' id='percent1'></div>
+ </div>
+ <input type="hidden" id="progress_width" value="0">
+ <script src="/js/loading.js"></script>
+ <div id="loading">
+ <img src="/loader.svg" style="filter:invert(1);width:96px;">
+ </div>
+
+ <div id="explore">
+ <div>
+ <img src="/favicon.svg" width="128px" height="128px">
+ <h1 style="font-size: 48px;">Familine</h1>
+ <div id="explore-grid"<?php if ($_ADMIN): ?> class="admin"<?php endif; ?>>
+ <?php if ($_ADMIN): ?>
+ <a href="https://console.<?= $_CONFIG["Global"]["domain"] ?>" class="explore-btn">
+ <img src="/icns/familine-camera.svg" width="48px" height="48px" style="margin: 0 20px;"><br>
+ <span>Camera</span>
+ </a>
+ <?php endif; ?>
+ <a href="https://docs.<?= $_CONFIG["Global"]["domain"] ?>" class="explore-btn">
+ <img src="/icns/familine-docs.svg" width="48px" height="48px" style="margin: 0 20px;"><br>
+ <span>Docs</span>
+ </a>
+ <a href="https://support.<?= $_CONFIG["Global"]["domain"] ?>" class="explore-btn">
+ <img src="/icns/familine-help.svg" width="48px" height="48px" style="margin: 0 20px;"><br>
+ <span>Help</span>
+ </a>
+ <a href="https://money.<?= $_CONFIG["Global"]["domain"] ?>" class="explore-btn">
+ <img src="/icns/familine-money.svg" width="48px" height="48px" style="margin: 0 20px;"><br>
+ <span>Money</span>
+ </a>
+ <a href="https://cinema.<?= $_CONFIG["Global"]["domain"] ?>" class="explore-btn">
+ <img src="/icns/familine-movies.svg" width="48px" height="48px" style="margin: 0 20px;"><br>
+ <span>Movies</span>
+ </a>
+ <a href="https://photos.<?= $_CONFIG["Global"]["domain"] ?>" class="explore-btn">
+ <img src="/icns/familine-photos.svg" width="48px" height="48px" style="margin: 0 20px;"><br>
+ <span>Photos</span>
+ </a>
+ <a href="https://cloud.<?= $_CONFIG["Global"]["domain"] ?>" class="explore-btn">
+ <img src="/icns/familine-review.svg" width="48px" height="48px" style="margin: 0 20px;"><br>
+ <span>Review</span>
+ </a>
+ <a href="https://share.<?= $_CONFIG["Global"]["domain"] ?>" class="explore-btn">
+ <img src="/icns/familine-share.svg" width="48px" height="48px" style="margin: 0 20px;"><br>
+ <span>Share</span>
+ </a>
+ <a href="https://chat.<?= $_CONFIG["Global"]["domain"] ?>" class="explore-btn">
+ <img src="/icns/familine-you.svg" width="48px" height="48px" style="margin: 0 20px;"><br>
+ <span>Yikes</span>
+ </a>
+ </div>
+ </div>
+ </div>
+
+ <?php
+
+ $icons = scandir($_SERVER['DOCUMENT_ROOT'] . "/icns");
+ foreach ($icons as $icon) {
+ if ($icon != "." && $icon != ".." && $icon != ".htaccess") {
+ echo("<img src='/icns/{$icon}' style='opacity:0;pointer-events:none;width:0;'>");
+ }
+ }
+
+ ?>
+
+ <script src="/js/iframe.js"></script>
+ <script src="/js/navigation.js"></script>
+ <script src="/js/statusbar.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/js/home.js b/js/home.js
new file mode 100644
index 0000000..7751ae9
--- /dev/null
+++ b/js/home.js
@@ -0,0 +1,12 @@
+setInterval(() => {
+ window.fetch("/app/radio/song.php").then((raw) => {
+ raw.text().then((text) => {
+ document.getElementById('radio-now').innerText = text;
+ })
+ })
+ window.fetch("/app/radio/next.php").then((raw) => {
+ raw.text().then((text) => {
+ document.getElementById('radio-next').innerText = text;
+ })
+ })
+}, 2000) \ No newline at end of file
diff --git a/js/iframe.js b/js/iframe.js
new file mode 100644
index 0000000..415f095
--- /dev/null
+++ b/js/iframe.js
@@ -0,0 +1,48 @@
+function iframeURLChange(iframe, callback) {
+ var unloadHandler = function () {
+ setTimeout(function () {
+ callback(iframe.contentWindow.location.href);
+ }, 0);
+ };
+
+ function attachUnload() {
+ iframe.contentWindow.removeEventListener("pagehide", unloadHandler);
+ iframe.contentWindow.addEventListener("pagehide", unloadHandler);
+ iframe.contentWindow.removeEventListener("unload", unloadHandler);
+ iframe.contentWindow.addEventListener("unload", unloadHandler);
+ }
+
+ iframe.addEventListener("load", attachUnload);
+ attachUnload();
+}
+
+Array.from(document.getElementsByTagName("iframe")).forEach((par) => {
+ iframeURLChange(par, function (newURL) {
+ $(".loader").fadeIn(200);
+ });
+})
+
+function unload() {
+ $(".loader").fadeIn(200);
+}
+
+Array.from(document.getElementsByTagName("iframe")).forEach((par) => {
+ par.onbeforeunload = unload
+})
+
+function loaded () {
+ $(".loader").fadeOut(200);
+
+ setTimeout(() => {
+ $(".loader").fadeOut(200);
+ }, 300)
+
+ setTimeout(() => {
+ $(".loader").fadeOut(200);
+ }, 1500);
+}
+
+Array.from(document.getElementsByTagName("iframe")).forEach((par) => {
+ par.onload = loaded;
+ par.onabort = loaded;
+}) \ No newline at end of file
diff --git a/js/loading.js b/js/loading.js
new file mode 100644
index 0000000..dc021a5
--- /dev/null
+++ b/js/loading.js
@@ -0,0 +1,32 @@
+document.onreadystatechange = function(e) {
+ if (document.readyState == "interactive") {
+ var all = document.getElementsByTagName("*");
+ for (var i = 0, max = all.length; i < max; i++) {
+ set_ele(all[i]);
+ }
+ }
+}
+
+function check_element(ele) {
+ var all = document.getElementsByTagName("*");
+ var totalele = all.length;
+ var per_inc = 100 / all.length;
+
+ if ($(ele).on()) {
+ var prog_width = per_inc + Number(document.getElementById("progress_width").value);
+ document.getElementById("progress_width").value = prog_width;
+ $("#bar1").animate({
+ width: prog_width + "%"
+ }, 10, function() {
+ if (document.getElementById("bar1").style.width === "100%") {
+ $(".progress").fadeOut("slow");
+ }
+ });
+ } else {
+ set_ele(ele);
+ }
+}
+
+function set_ele(set_element) {
+ check_element(set_element);
+} \ No newline at end of file
diff --git a/js/navigation.js b/js/navigation.js
new file mode 100644
index 0000000..a76b19e
--- /dev/null
+++ b/js/navigation.js
@@ -0,0 +1,110 @@
+window.addEventListener('load', () => {
+ document.getElementById('loading').style.display = "none";
+})
+
+function setImageSource(image, source) {
+ if (image.src !== source) {
+ image.src = source;
+ }
+}
+
+doCheckForActiveItem = true;
+
+Array.from(document.getElementsByClassName("tab")).forEach((par) => {
+ item = par.children[0];
+ if (typeof item.getAttribute("data-image-hover") === "string") {
+ item.setAttribute("data-image-normal", item.src)
+ par.addEventListener('mouseenter', (e) => {
+ doCheckForActiveItem = false;
+
+ if (e.target.classList.contains("tab-active")) {
+ item = e.target.children[0];
+ item.style.opacity = ".75";
+ } else {
+ item = e.target.children[0];
+ setImageSource(item, item.getAttribute("data-image-hover"));
+ }
+ })
+ par.addEventListener('mouseleave', (e) => {
+ doCheckForActiveItem = true;
+
+ if (e.target.classList.contains("tab-active")) {
+ item = e.target.children[0];
+ item.style.opacity = "1";
+ } else {
+ item = e.target.children[0];
+ setImageSource(item, item.getAttribute("data-image-normal"));
+ }
+ })
+ }
+})
+
+setInterval(() => {
+ Array.from(document.getElementsByClassName("tab")).forEach((par) => {
+ if (!doCheckForActiveItem) { return; }
+ item = par.children[0];
+ if (par.classList.contains("tab-active")) {
+ setImageSource(item, item.getAttribute("data-image-active"));
+ } else {
+ setImageSource(item, item.getAttribute("data-image-normal"));
+ }
+ })
+}, 100)
+
+function openTab(tab) {
+ Array.from(document.getElementsByClassName("tab")).forEach((par) => {
+ if (par.classList.contains("tab-active")) {
+ par.classList.remove("tab-active");
+ }
+ })
+ document.getElementById('tab-' + tab).classList.add("tab-active");
+ doCheckForActiveItem = true;
+}
+
+function openPane(pane) {
+ Array.from(document.getElementsByTagName("iframe")).forEach((par) => {
+ par.src = "about:blank";
+ })
+ Array.from(document.getElementsByClassName("pane")).forEach((par) => {
+ $("#" + par.id).fadeOut(200);
+ })
+ $("#pane-" + pane).fadeIn(200);
+ $(".loader").fadeIn(200);
+ switch (pane) {
+ case "radio":
+ document.getElementById('frame-' + pane).src = "/app/radio"
+ break;
+ case "money":
+ document.getElementById('frame-' + pane).src = "/app/money"
+ break;
+ case "contacts":
+ document.getElementById('frame-' + pane).src = "/app/contacts"
+ break;
+ case "home":
+ document.getElementById('frame-' + pane).src = "/app/home"
+ break;
+ case "space":
+ if (navigator.userAgent.includes("+Familine/")) {
+ $(".loader").fadeOut(200);
+ document.getElementById('frame-' + pane).loadURL("https://chat.familine.minteck.org");
+ document.getElementById('frame-' + pane).setZoomFactor(0.9);
+ break;
+ } else {
+ document.getElementById('frame-' + pane).src = "/app/space"
+ break;
+ }
+ case "cinema":
+ document.getElementById('frame-' + pane).src = "https://cinema.familine.minteck.org"
+ break;
+ case "share":
+ document.getElementById('frame-' + pane).src = "https://share.familine.minteck.org"
+ break;
+ case "help":
+ document.getElementById('frame-' + pane).src = "/app/help"
+ break;
+ }
+}
+
+window.addEventListener('load', () => {
+ try { openPane('home'); } catch (e) {}
+}) \ No newline at end of file
diff --git a/js/statusbar.js b/js/statusbar.js
new file mode 100644
index 0000000..42ee461
--- /dev/null
+++ b/js/statusbar.js
@@ -0,0 +1,4 @@
+window.addEventListener("load", () => {
+ window.fetch("/statusbar.php").then((a) => {a.text().then((b) => {document.body.innerHTML=document.body.innerHTML+b})});
+ $(".progress").fadeOut("slow");
+}) \ No newline at end of file
diff --git a/loader.svg b/loader.svg
new file mode 100644
index 0000000..087213f
--- /dev/null
+++ b/loader.svg
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%; display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
+<g transform="rotate(0 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.9166666666666666s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(30 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.8333333333333334s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(60 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.75s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(90 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.6666666666666666s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(120 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5833333333333334s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(150 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(180 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.4166666666666667s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(210 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.3333333333333333s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(240 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.25s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(270 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.16666666666666666s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(300 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.08333333333333333s" repeatCount="indefinite"></animate>
+ </rect>
+</g><g transform="rotate(330 50 50)">
+ <rect x="48.5" y="24" rx="0" ry="0" width="3" height="12" fill="#000000">
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animate>
+ </rect>
+</g>
+<!-- [ldio] generated by https://loading.io/ --></svg> \ No newline at end of file
diff --git a/login/embed/index.php b/login/embed/index.php
new file mode 100644
index 0000000..9fc6274
--- /dev/null
+++ b/login/embed/index.php
@@ -0,0 +1,6 @@
+<?php
+
+$_CONFIG = json_decode(file_get_contents($_SERVER["DOCUMENT_ROOT"] . "/private/FamilineConfig.json"), true);
+
+header("Location: https://" . $_CONFIG["Global"]["federation"] . "/hub/api/rest/oauth2/auth?client_id=" . json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/private/app.json"), true)["id"] . "&response_type=code&redirect_uri=https://" . $_CONFIG["Global"]["domain"] . "/oauth/embed&scope=hub&request_credentials=default&access_type=offline");
+die();
diff --git a/login/index.php b/login/index.php
new file mode 100644
index 0000000..67c01cf
--- /dev/null
+++ b/login/index.php
@@ -0,0 +1,6 @@
+<?php
+
+$_CONFIG = json_decode(file_get_contents($_SERVER["DOCUMENT_ROOT"] . "/private/FamilineConfig.json"), true);
+
+header("Location: https://" . $_CONFIG["Global"]["federation"] . "/hub/api/rest/oauth2/auth?client_id=" . json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/private/app.json"), true)["id"] . "&response_type=code&redirect_uri=https://" . $_CONFIG["Global"]["domain"] . "/oauth&scope=hub&request_credentials=default&access_type=offline");
+die();
diff --git a/native.css b/native.css
new file mode 100644
index 0000000..0471f6a
--- /dev/null
+++ b/native.css
@@ -0,0 +1,68 @@
+#dragspace {
+ -webkit-app-region: drag;
+ position: fixed;
+ top: 0;
+ right: 96px;
+ left: 0;
+ height: 33px;
+}
+
+::-webkit-scrollbar {
+ width: 10px;
+}
+
+::-webkit-scrollbar-track {
+ background: #f1f1f1;
+}
+
+::-webkit-scrollbar-thumb {
+ background: #888;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: #555;
+}
+
+#window {
+ position: fixed;
+ top: 0;
+ right: 0;
+ z-index: 9999999;
+}
+
+.window-btn img {
+ width: 16px;
+}
+
+.window-btn {
+ padding-bottom: 4px;
+ padding-left: 4px;
+ padding-right: 4px;
+ border: 1px solid lightgray;
+ border-top: none;
+ position: fixed;
+ top: 0;
+ right: 16px;
+ height: 16px;
+}
+
+#window-close {
+ border-bottom-right-radius: 5px;
+}
+
+#window-minimize {
+ border-bottom-left-radius: 5px;
+ right: 66px;
+}
+
+#window-maximize, #window-restore {
+ right: 41px;
+}
+
+.window-btn img {
+ pointer-events: none;
+}
+
+#copyright {
+ right: 114px !important;
+} \ No newline at end of file
diff --git a/oauth/embed/index.php b/oauth/embed/index.php
new file mode 100644
index 0000000..cba9ebc
--- /dev/null
+++ b/oauth/embed/index.php
@@ -0,0 +1,45 @@
+<?php
+
+// TODO: handle errors
+$_CONFIG = json_decode(file_get_contents($_SERVER["DOCUMENT_ROOT"] . "/private/FamilineConfig.json"), true);
+
+if (!isset($_GET['code'])) {
+ die();
+}
+
+$appdata = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/private/app.json"), true);
+
+$crl = curl_init('https://account.familine.minteck.org/hub/api/rest/oauth2/token');
+curl_setopt($crl, CURLOPT_RETURNTRANSFER, true);
+curl_setopt($crl, CURLINFO_HEADER_OUT, true);
+curl_setopt($crl, CURLOPT_POST, true);
+curl_setopt($crl, CURLOPT_HTTPHEADER, [
+ "Authorization: Basic " . base64_encode($appdata["id"] . ":" . $appdata["secret"]),
+ "Content-Type: application/x-www-form-urlencoded",
+ "Accept: application/json"
+]);
+curl_setopt($crl, CURLOPT_POSTFIELDS, "grant_type=authorization_code&redirect_uri=" . urlencode("https://" . $_CONFIG["Global"]["domain"] . "/oauth/embed") . "&code=" . $_GET['code']);
+
+$result = curl_exec($crl);
+$result = json_decode($result, true);
+
+curl_close($crl);
+
+if (isset($result["access_token"])) {
+ $crl = curl_init('https://' . $_CONFIG["Global"]["federation"]. '/hub/api/rest/users/me');
+ curl_setopt($crl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($crl, CURLINFO_HEADER_OUT, true);
+ curl_setopt($crl, CURLOPT_HTTPHEADER, [
+ "Authorization: Bearer " . $result["access_token"],
+ "Accept: application/json"
+ ]);
+
+ $result = curl_exec($crl);
+ $result = json_decode($result, true);
+
+ $token = bin2hex(random_bytes(32));
+ file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/private/tokens/" . $token, json_encode($result));
+ setcookie("FL_SESSION_TOKEN", $token, strtotime('+365 days'), "/", "." . $_CONFIG["Global"]["domain"], true, true);
+
+ header("Location: /statusbar.php");
+} \ No newline at end of file
diff --git a/oauth/index.php b/oauth/index.php
new file mode 100644
index 0000000..0660d6a
--- /dev/null
+++ b/oauth/index.php
@@ -0,0 +1,45 @@
+<?php
+
+// TODO: handle errors
+$_CONFIG = json_decode(file_get_contents($_SERVER["DOCUMENT_ROOT"] . "/private/FamilineConfig.json"), true);
+
+if (!isset($_GET['code'])) {
+ die();
+}
+
+$appdata = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/private/app.json"), true);
+
+$crl = curl_init('https://account.familine.minteck.org/hub/api/rest/oauth2/token');
+curl_setopt($crl, CURLOPT_RETURNTRANSFER, true);
+curl_setopt($crl, CURLINFO_HEADER_OUT, true);
+curl_setopt($crl, CURLOPT_POST, true);
+curl_setopt($crl, CURLOPT_HTTPHEADER, [
+ "Authorization: Basic " . base64_encode($appdata["id"] . ":" . $appdata["secret"]),
+ "Content-Type: application/x-www-form-urlencoded",
+ "Accept: application/json"
+]);
+curl_setopt($crl, CURLOPT_POSTFIELDS, "grant_type=authorization_code&redirect_uri=" . urlencode("https://" . $_CONFIG["Global"]["domain"] . "/oauth") . "&code=" . $_GET['code']);
+
+$result = curl_exec($crl);
+$result = json_decode($result, true);
+
+curl_close($crl);
+
+if (isset($result["access_token"])) {
+ $crl = curl_init('https://' . $_CONFIG["Global"]["federation"]. '/hub/api/rest/users/me');
+ curl_setopt($crl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($crl, CURLINFO_HEADER_OUT, true);
+ curl_setopt($crl, CURLOPT_HTTPHEADER, [
+ "Authorization: Bearer " . $result["access_token"],
+ "Accept: application/json"
+ ]);
+
+ $result = curl_exec($crl);
+ $result = json_decode($result, true);
+
+ $token = bin2hex(random_bytes(32));
+ file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/private/tokens/" . $token, json_encode($result));
+ setcookie("FL_SESSION_TOKEN", $token, strtotime('+365 days'), "/", "." . $_CONFIG["Global"]["domain"], true, true);
+
+ header("Location: /");
+} \ No newline at end of file
diff --git a/private/.htaccess b/private/.htaccess
new file mode 100644
index 0000000..2c73686
--- /dev/null
+++ b/private/.htaccess
@@ -0,0 +1 @@
+Deny from All \ No newline at end of file
diff --git a/private/session.php b/private/session.php
new file mode 100644
index 0000000..e0135db
--- /dev/null
+++ b/private/session.php
@@ -0,0 +1,30 @@
+<?php
+
+$_CONFIG = json_decode(file_get_contents($_SERVER["DOCUMENT_ROOT"] . "/private/FamilineConfig.json"), true);
+
+if (isset($_COOKIE['FL_SESSION_TOKEN'])) {
+ if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/private/tokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['FL_SESSION_TOKEN'])))) {
+ $_PROFILE = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/private/tokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['FL_SESSION_TOKEN']))), true);
+
+ if (isset($_PROFILE['familine'])) {
+ header("Location: /welcome");
+ die();
+ }
+
+ $_USER = $_PROFILE['login'];
+ $_SUID = $_PROFILE['login'];
+ $_FULLNAME = $_PROFILE['name'];
+ } else {
+ header("Location: /welcome");
+ die();
+ }
+} else {
+ header("Location: /welcome");
+ die();
+}
+
+if (isset($_PROFILE["projectRoles"]) && is_array($_PROFILE["projectRoles"]) && isset($_PROFILE["projectRoles"][0]) && is_array($_PROFILE["projectRoles"][0]) && isset($_PROFILE["projectRoles"][0]["role"]) && is_array($_PROFILE["projectRoles"][0]["role"]) && isset($_PROFILE["projectRoles"][0]["role"]["key"]) && is_string($_PROFILE["projectRoles"][0]["role"]["key"]) && $_PROFILE["projectRoles"][0]["role"]["key"] === "system-admin") {
+ $_ADMIN = true;
+} else {
+ $_ADMIN = false;
+}
diff --git a/radio.css b/radio.css
new file mode 100644
index 0000000..06e0556
--- /dev/null
+++ b/radio.css
@@ -0,0 +1,52 @@
+#radio-bar {
+ background-color: whitesmoke;
+ border-radius: 5px;
+ height: 36px;
+ padding: 5px;
+ margin-bottom: 10px;
+}
+
+#radio-action, #radio-popout {
+ cursor: pointer;
+ margin: -5px;
+ padding: 5px;
+ background: transparent;
+ height: 36px;
+ display: inline-block;
+ border-top-left-radius: 5px;
+ border-bottom-left-radius: 5px;
+ transition: background 200ms;
+ margin-right: 5px;
+}
+
+#radio-popout {
+ margin-right: -5px !important;
+ margin-left: 5px;
+ border-top-left-radius: 0 !important;
+ border-bottom-left-radius: 0 !important;
+ border-top-right-radius: 5px;
+ border-bottom-right-radius: 5px;
+ float: right;
+}
+
+#radio-action:hover, #radio-popout:hover {
+ background: lightgray;
+}
+
+#radio-action:active, #radio-popout:active {
+ background: gray;
+}
+
+#radio-late {
+ float: right;
+}
+
+#radio-clients {
+ float: right;
+}
+
+#radio-opus {
+ height: 24px;
+ filter: brightness(0);
+ vertical-align: middle;
+} \ No newline at end of file
diff --git a/radio.embed.css b/radio.embed.css
new file mode 100644
index 0000000..79bd075
--- /dev/null
+++ b/radio.embed.css
@@ -0,0 +1,3 @@
+#radio-bar, #radio-bar *:not(.badge) {
+ border-radius: 0 !important;
+} \ No newline at end of file
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 0000000..6ffbc30
--- /dev/null
+++ b/robots.txt
@@ -0,0 +1,3 @@
+User-agent: *
+Disallow: /
+
diff --git a/sample.html b/sample.html
new file mode 100644
index 0000000..8976eff
--- /dev/null
+++ b/sample.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Title</title>
+</head>
+<body>
+
+</body>
+</html> \ No newline at end of file
diff --git a/statusbar.php b/statusbar.php
new file mode 100644
index 0000000..ffb4ae9
--- /dev/null
+++ b/statusbar.php
@@ -0,0 +1,134 @@
+<?php
+
+if (isset($_COOKIE['FL_SESSION_TOKEN'])) {
+ if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/private/tokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['FL_SESSION_TOKEN'])))) {
+ $_PROFILE = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/private/tokens/" . str_replace(".", "", str_replace("/", "", $_COOKIE['FL_SESSION_TOKEN']))), true);
+
+ if (isset($_PROFILE['familine'])) {
+ header("Location: /login/embed");
+ die();
+ }
+
+ $_USER = $_PROFILE['login'];
+ $_SUID = $_PROFILE['login'];
+ $_FULLNAME = $_PROFILE['name'];
+ } else {
+ header("Location: /login/embed");
+ die();
+ }
+} else {
+ header("Location: /login/embed");
+ die();
+}
+
+if (isset($_PROFILE["projectRoles"]) && is_array($_PROFILE["projectRoles"]) && isset($_PROFILE["projectRoles"][0]) && is_array($_PROFILE["projectRoles"][0]) && isset($_PROFILE["projectRoles"][0]["role"]) && is_array($_PROFILE["projectRoles"][0]["role"]) && isset($_PROFILE["projectRoles"][0]["role"]["key"]) && is_string($_PROFILE["projectRoles"][0]["role"]["key"]) && $_PROFILE["projectRoles"][0]["role"]["key"] === "system-admin") {
+ $_ADMIN = true;
+} else {
+ $_ADMIN = false;
+}
+
+?>
+
+<!DOCTYPE html>
+<html>
+<head>
+ <title>frame</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="icon" href="/favicon.svg">
+ <link rel="stylesheet" href="/styles.css">
+</head>
+
+<body>
+ <style>
+ /* Statusbar */
+ #statusbar {
+ background: whitesmoke;
+ padding: 8px 32px;
+ font-size: 14px;
+ z-index: 99;
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ color: black;
+ }
+
+ #statusbar-tag {
+ opacity: .5;
+ }
+
+ .logo:hover {
+ background: rgba(0, 0, 0, .25);
+ }
+
+ .logo:active {
+ background: rgba(0, 0, 0, .5);
+ }
+
+ .logo {
+ cursor: pointer;
+ color: black;
+ }
+
+ .account:hover {
+ background: rgba(0, 0, 0, .25);
+ }
+
+ .account:active {
+ background: rgba(0, 0, 0, .5);
+ }
+
+ .account {
+ cursor: pointer;
+ color: black;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ .account {
+ color: white;
+ }
+
+ .logo {
+ color: white;
+ }
+ }
+
+ @media (max-width: 800px) {
+ #apps-desktop {
+ display: none;
+ }
+
+ #statusbar {
+ text-align: center;
+ }
+ }
+
+ @media (max-width: 1100px) {
+ #copyright {
+ display: none;
+ }
+ }
+ </style>
+ <div id="statusbar">
+ <a title="Accueil de Familine" href="https://familine.minteck.org" target="_parent"><span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 7px 7px 7px;margin: -11px 0;"><img src="https://familine.minteck.org/favicon.svg" style="width: 16px;vertical-align: middle;"> Familine</span></a>
+ <span style="opacity: .25;">|</span>
+ <span id="apps-desktop" <?= $_SERVER['HTTP_REFERER'] === "https://familine.minteck.org/" ? "style=\"display: none;\"" : "" ?>>
+ <a style="text-decoration: none;" title="Familine Docs" href="https://docs.familine.minteck.org" target="_parent">
+ <?php if ($_ADMIN): ?><a style="text-decoration: none;" title="Familine Camera" href="https://console.familine.minteck.org" target="_parent">
+ <span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 2px 7px 2px;margin: -11px 0;"><img src="https://familine.minteck.org/icns/familine-camera.svg" style="width: 20px;vertical-align: middle;"></span></a>
+ <?php endif; ?><span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 2px 7px 2px;margin: -11px 0;"><img src="https://familine.minteck.org/icns/familine-docs.svg" style="width: 20px;vertical-align: middle;"></span></a><a style="text-decoration: none;" title="Familine Help" href="https://support.familine.minteck.org" target="_parent">
+ <span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 2px 7px 2px;margin: -11px 0;"><img src="https://familine.minteck.org/icns/familine-help.svg" style="width: 20px;vertical-align: middle;"></span></a><a style="text-decoration: none;" title="Familine Money" href="https://money.familine.minteck.org" target="_parent">
+ <span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 2px 7px 2px;margin: -11px 0;"><img src="https://familine.minteck.org/icns/familine-money.svg" style="width: 20px;vertical-align: middle;"></span></a><a style="text-decoration: none;" title="Familine Movies" href="https://cinema.familine.minteck.org" target="_parent">
+ <span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 2px 7px 2px;margin: -11px 0;"><img src="https://familine.minteck.org/icns/familine-movies.svg" style="width: 20px;vertical-align: middle;"></span></a><a style="text-decoration: none;" title="Familine Photos" href="https://photos.familine.minteck.org" target="_parent">
+ <span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 2px 7px 2px;margin: -11px 0;"><img src="https://familine.minteck.org/icns/familine-photos.svg" style="width: 20px;vertical-align: middle;"></span></a><a style="text-decoration: none;" title="Familine Review" href="https://cloud.familine.minteck.org" target="_parent">
+ <span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 2px 7px 2px;margin: -11px 0;"><img src="https://familine.minteck.org/icns/familine-review.svg" style="width: 20px;vertical-align: middle;"></span></a><a style="text-decoration: none;" title="Familine Share" href="https://share.familine.minteck.org" target="_parent">
+ <span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 2px 7px 2px;margin: -11px 0;"><img src="https://familine.minteck.org/icns/familine-share.svg" style="width: 20px;vertical-align: middle;"></span></a><a style="text-decoration: none;" title="Familine Yikes" href="https://chat.familine.minteck.org" target="_parent">
+ <span class="logo" style="display: inline-block;top: 0;position: relative;padding: 8px 2px 7px 2px;margin: -11px 0;"><img src="https://familine.minteck.org/icns/familine-you.svg" style="width: 20px;vertical-align: middle;"></span></a>
+ <span style="opacity: .25;">|</span>
+ </span>
+ <a title="Mon compte" href="https://account.familine.minteck.org/hub/users/me" target="_parent"><span class="account" style="display: inline-block;top: 0;position: relative;padding: 8px 7px 7px 7px;margin: -11px 0;"><?= $_FULLNAME ?> <span id="statusbar-tag">@<?= $_USER ?></span></span></a>
+ <a id="copyright">version <?= file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/version.txt") ?> · © 2020-<?= date('Y') ?> Familine</a>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/styles.css b/styles.css
new file mode 100644
index 0000000..efd78c4
--- /dev/null
+++ b/styles.css
@@ -0,0 +1,233 @@
+/* Dark Theme */
+@import "dark.css";
+
+/* Globals */
+* {
+ font-family: sans-serif;
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+}
+
+#copyright {
+ float: right;
+ vertical-align: middle;
+ display: inline-block;
+ position: fixed;
+ top: 8px;
+ opacity: .5;
+ right: 32px;
+}
+
+/* Loader */
+#loading {
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+ z-index: 999999;
+ background: #222;
+ color: white;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+
+}
+
+.progress {
+ position: fixed;
+ left: 35%;
+ top: 65%;
+ height: 5px;
+ z-index: 99999999;
+ background-color: rgba(255, 255, 255, .25);
+ right: 35%;
+ border-radius: 1000px;
+}
+
+.bar {
+ background-color: rgba(255, 255, 255, .25);
+ width: 0%;
+ height: 5px;
+ border-radius: 1000px;
+}
+
+.percent {
+ position: absolute;
+ display: inline-block;
+ top: 3px;
+ left: 48%;
+}
+
+/* Tabs */
+#tabs {
+ background: whitesmoke;
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
+ width: 100vw;
+}
+
+#tabs img {
+ width: 36px;
+ vertical-align: middle;
+ filter: invert(0);
+ transition: width 200ms, filter 200ms;
+}
+
+#tabs .tab {
+ border-bottom: 1px solid;
+ border-bottom-color: transparent;
+ text-align: center;
+ margin: 8px 8px 0;
+ padding-bottom: 8px;
+ cursor: pointer;
+ height: 48px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: border-bottom-color 200ms;
+}
+
+#tabs .tab.tab-active img {
+ width: 48px;
+}
+
+#tabs .tab.tab-active {
+ border-bottom-color: black;
+}
+
+#panes, .pane {
+ position: fixed;
+ top: 98px;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+
+.pane {
+ display: none;
+}
+
+/* IFrame */
+.loader {
+ background: rgba(255, 255, 255, .75);
+ top: 98px;
+ bottom: 0;
+ position: fixed;
+ left: 0;
+ right: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 999999;
+ cursor: wait;
+}
+
+.loader img {
+ height: 96px;
+ width: 96px;
+}
+
+.frame {
+ border: none;
+ width: 100%;
+ height: 100%;
+}
+
+/* Home */
+.home-grid {
+ display: grid;
+ grid-template-columns: 96px 1fr;
+ grid-column-gap: 10px;
+}
+
+.home-grid > * {
+ display: flex;
+ align-items: center;
+}
+
+/* Bootstrap Fixes */
+.dropdown-item {
+ cursor: pointer;
+}
+
+.list-group {
+ margin-bottom: 10px !important;
+}
+
+/* Responsiveness */
+@media (max-width: 550px) {
+ #copyright {
+ display: none;
+ }
+}
+
+#explore {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ position: fixed;
+ inset: 0;
+}
+
+#explore-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
+}
+
+#explore-grid.admin {
+ grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
+}
+
+@media (max-width: 800px) {
+ #explore-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ }
+
+ #explore-grid.admin {
+ grid-template-columns: 1fr 1fr 1fr;
+ }
+}
+
+.explore-btn {
+ color: white;
+ border-radius: 5px;
+ padding: 10px;
+ text-decoration: none;
+}
+
+.explore-btn:hover {
+ background: rgba(255, 255, 255, .25);
+ box-shadow: 1px 5px 12px rgba(255, 255, 255, .25);
+}
+
+.explore-btn:active, .explore-btn:focus {
+ background: rgba(255, 255, 255, .5);
+ box-shadow: 1px 5px 12px rgba(255, 255, 255, .5);
+}
+
+@media (prefers-color-scheme: light) {
+ .explore-btn {
+ color: black;
+ }
+
+ .explore-btn:hover {
+ background: rgba(0, 0, 0, 0.25);
+ box-shadow: 1px 5px 12px rgba(0, 0, 0, 0.25);
+ }
+
+ .explore-btn:active, .explore-btn:focus {
+ background: rgba(0, 0, 0, .5);
+ box-shadow: 1px 5px 12px rgba(0, 0, 0, .5);
+ }
+
+ #data-loader-img {
+ filter: none !important;
+ }
+} \ No newline at end of file
diff --git a/version.txt b/version.txt
new file mode 100644
index 0000000..a22fed3
--- /dev/null
+++ b/version.txt
@@ -0,0 +1 @@
+4.3.1 (Accès anticipé) \ No newline at end of file
diff --git a/welcome/index.php b/welcome/index.php
new file mode 100644
index 0000000..aecdc34
--- /dev/null
+++ b/welcome/index.php
@@ -0,0 +1,4 @@
+<?php
+
+header("Location: /login");
+die(); \ No newline at end of file