diff --git a/content-scripts.css b/content-scripts.css index 6246b33d7..565570135 100644 --- a/content-scripts.css +++ b/content-scripts.css @@ -1,4 +1,4 @@ - + /*----------------------------------------------------------------------------- >>> APPEARANCE ------------------------------------------------------------------------------- @@ -25,6 +25,7 @@ 6.1 Live chat 6.2 Playlist 6.3 Related videos + 6.4 Sidebar and thumbnail position 7.0 Footer -----------------------------------------------------------------------------*/ @@ -193,23 +194,17 @@ html[it-player-hide-cards=true] .ytp-ce-element, html[it-player-hide-cards=true] .ytp-ce-video, html[it-player-hide-cards=true] .ytp-cards-button, html[it-player-hide-cards=true] .ytp-cards-teaser, -html[it-player-show-cards-on-mouse-hover=true] .html5-video-player:not(:hover) .ytp-ce-element, -html[it-player-show-cards-on-mouse-hover=true] .html5-video-player:not(:hover) .ytp-ce-video, -html[it-player-show-cards-on-mouse-hover=true] .html5-video-player:not(:hover) .ytp-cards-button, -html[it-player-show-cards-on-mouse-hover=true] .html5-video-player:not(:hover) .ytp-cards-teaser +html[it-player-show-cards-on-mouse-hover=true] .ytp-cards-button { display: none !important; } -html[it-player-show-cards-on-mouse-hover=true] .html5-video-player:hover .ytp-ce-element, -html[it-player-show-cards-on-mouse-hover=true] .html5-video-player:hover .ytp-ce-video, -html[it-player-show-cards-on-mouse-hover=true] .html5-video-player:hover .ytp-cards-button, -html[it-player-show-cards-on-mouse-hover=true] .html5-video-player:hover .ytp-cards-teaser +html[it-player-show-cards-on-mouse-hover=true] .html5-video-player:hover .iv-drawer { display: block !important; + transform: none; } - /*----------------------------------------------------------------------------- 2.4 Color -----------------------------------------------------------------------------*/ @@ -757,6 +752,19 @@ html[it-related-videos=collapsed].related-videos-collapsed #improvedtube-collaps box-shadow: inset 0 1px 0 #ddd; } +/*----------------------------------------------------------------------------- +6.4 Sidebar and thumbnail position +-----------------------------------------------------------------------------*/ + +html[it-sidebar-left='true'] #columns>#primary, +html[it-sidebar-left='true'] #head>#upnext /* also moving autoplay button to the outside as the glow bothers next to the video */ +{ + order:7; +} +html[it-thumbnails-right='true'] #dismissable>ytd-thumbnail +{ + order:7; +} /*----------------------------------------------------------------------------- 7.0 Footer @@ -767,7 +775,7 @@ html[it-hide-footer=true] #footer-container.yt-base-gutter { display: none !important; } - + /*----------------------------------------------------------------------------- >>> APPEARANCE: PLAYER SIZE ------------------------------------------------------------------------------- @@ -1285,7 +1293,7 @@ html[it-page-type="video"][it-header-position='hover_on_video_page'][it-player-s { margin-top: 14px !important; } - + .improvedtube-add-to-blacklist { font-size: 32px; @@ -1322,7 +1330,7 @@ html[it-page-type="video"][it-header-position='hover_on_video_page'][it-player-s { transform: scale(1.25); } - + /*----------------------------------------------------------------------------- >>> CHANNEL ------------------------------------------------------------------------------- @@ -1345,7 +1353,7 @@ html[it-channel-hide-featured-content=true] #secondary ytd-browse-secondary-cont width: fit-content; height: fit-content; } - + /*----------------------------------------------------------------------------- >>> GENERAL ------------------------------------------------------------------------------- @@ -1625,7 +1633,7 @@ html[it-remove-related-search-results=true] li > div.search-refinements { display: none; }*/ - + .it-rate-notify { position: fixed; @@ -1773,7 +1781,7 @@ html:not([it-page-type='video']) .it-rate-notify.it-rate-notify--show transform: scale(1); } } - + /*----------------------------------------------------------------------------- >>> PLAYER ------------------------------------------------------------------------------- @@ -2124,7 +2132,7 @@ html[it-player-crop-chapter-titles='false'] .ytp-chapter-title { width: auto !important; } - + html[it-youtube-version=new] #it-playlist-reverse { display: flex; @@ -2173,7 +2181,7 @@ html[it-youtube-version=old] #it-playlist-reverse svg { fill: #fff; } - + /*----------------------------------------------------------------------------- >>> SETTINGS ------------------------------------------------------------------------------- @@ -2344,7 +2352,7 @@ html[it-improvedtube-youtube-icon='draggable'] .it-btn { opacity: .75 !important; } - + #it-status { font-size: 5rem; @@ -2356,7 +2364,7 @@ html[it-improvedtube-youtube-icon='draggable'] .it-btn color: #0ff; text-shadow: 1px 1px 2px #000; } - + /*----------------------------------------------------------------------------- >>> THEMES ------------------------------------------------------------------------------- @@ -2444,7 +2452,7 @@ html[it-bluelight][it-youtube-version=old] body { visibility: visible !important; } - + [it-black-theme=true]:not([it-schedule=system_peference_dark]):not([it-schedule=system_peference_light]) { --yt-swatch-primary: #000!important; @@ -3077,7 +3085,7 @@ html[it-black-theme=true]:not([it-schedule=system_peference_dark]):not([it-sched --yt-chat-bubble-self-background-color: #000; --yt-blue-suggestive: transparent; } -} +} [it-dawn-theme=true]:not([it-schedule=system_peference_dark]):not([it-schedule=system_peference_light]) { --yt-swatch-primary: #d44d5c!important; @@ -3714,7 +3722,7 @@ html[it-dawn-theme=true]:not([it-schedule=system_peference_dark]):not([it-schedu { -webkit-filter: grayscale(1) brightness(4); filter: grayscale(1) brightness(4); - } + } [it-youtube-version=old][it-default-dark-theme=true]:not([it-schedule=system_peference_dark]):not([it-schedule=system_peference_light]) { --yt-swatch-header-primary: rgb(34,38,42)!important; @@ -4277,7 +4285,7 @@ html[it-dawn-theme=true]:not([it-schedule=system_peference_dark]):not([it-schedu background: rgb(19,19,19)!important; } -} +} [it-desert-theme=true]:not([it-schedule=system_peference_dark]):not([it-schedule=system_peference_light]) { --yt-swatch-primary: #faf9f9!important; @@ -4900,7 +4908,7 @@ html[it-desert-theme=true]:not([it-schedule=system_peference_dark]):not([it-sche --yt-chat-bubble-self-background-color: #faf9f9; --yt-blue-suggestive: transparent; } -} +} html[it-theme=true] #author-name.style-scope.yt-live-chat-message-input-renderer, html[it-theme=true] #content #message.yt-live-chat-text-message-renderer, html[it-theme=true] #delete-account-confirm, @@ -10137,7 +10145,7 @@ html[it-theme=true] .yt-uix-shelfslider-prev-arrow.yt-uix-tooltip.yt-sprite -webkit-filter: brightness(3)!important ; filter: brightness(3)!important; } - + [it-night-theme=true]:not([it-schedule=system_peference_dark]):not([it-schedule=system_peference_light]) { --yt-swatch-primary: #003459!important; @@ -10772,7 +10780,7 @@ html[it-night-theme=true]:not([it-schedule=system_peference_dark]):not([it-sched --yt-chat-bubble-self-background-color: #003459; --yt-blue-suggestive: transparent; } -} +} [it-plain-theme=true]:not([it-schedule=system_peference_dark]):not([it-schedule=system_peference_light]) { --yt-swatch-primary: #c7efcf!important; @@ -11395,7 +11403,7 @@ html[it-plain-theme=true]:not([it-schedule=system_peference_dark]):not([it-sched --yt-chat-bubble-self-background-color: #c7efcf; --yt-blue-suggestive: transparent; } -} +} [it-sunset-theme=true]:not([it-schedule=system_peference_dark]):not([it-schedule=system_peference_light]) { --yt-swatch-primary: #2f3364!important; diff --git a/content-scripts.js b/content-scripts.js index ccc91cc50..9cc4669cc 100644 --- a/content-scripts.js +++ b/content-scripts.js @@ -1,4 +1,4 @@ - + /*----------------------------------------------------------------------------- >>> CORE ------------------------------------------------------------------------------- @@ -184,7 +184,7 @@ ImprovedTube.init = function() { function withoutInjection(object) { youtubeHomePage__documentStart(object.youtube_home_page); } - + /*----------------------------------------------------------------------------- >>> EVENTS ------------------------------------------------------------------------------- @@ -263,6 +263,24 @@ ImprovedTube.events = function() { window.addEventListener('resize', function() { ImprovedTube.fitToWindow(); ImprovedTube.improvedtube_youtube_icon_resize(); + + setTimeout(function() { + if (document.querySelector('.html5-video-player video') && document.querySelector('.it-rotate-styles')) { + var video = document.querySelector('.html5-video-player video'), + transform = '', + rotate = (document.querySelector('.it-rotate-styles') && document.querySelector('.it-rotate-styles').textContent.match(/rotate\([0-9.]+deg\)/g) || [''])[0]; + + rotate = Number((rotate.match(/[0-9.]+/g) || [])[0]) || 0; + + transform += 'rotate(' + rotate + 'deg)'; + + if (rotate == 90 || rotate == 270) { + transform += ' scale(' + video.offsetHeight / video.offsetWidth + ')'; + } + + document.querySelector('.it-rotate-styles').textContent = '.html5-video-player:not(it-mini-player) video {transform:' + transform + '}'; + } + }, 500); }); window.addEventListener('scroll', function() { @@ -331,7 +349,7 @@ ImprovedTube.events = function() { } }, true); }; - + chrome.storage.local.get(function(items) { document.addEventListener('ImprovedTubeAnalyzer', function() { if (items.analyzer_activation !== false) { @@ -344,7 +362,7 @@ chrome.storage.local.get(function(items) { } }); }); - + /*----------------------------------------------------------------------------- >>> APPEARANCE ------------------------------------------------------------------------------- @@ -797,7 +815,7 @@ ImprovedTube.related_videos = function() { }, 260); } }; - + // TODO: HIGH CPU USAGE document.addEventListener('ImprovedTubeBlacklist', function(event) { @@ -1013,7 +1031,7 @@ ImprovedTube.blacklist = function() { } } }; - + /*----------------------------------------------------------------------------- >>> CHANNEL ------------------------------------------------------------------------------- @@ -1068,7 +1086,7 @@ ImprovedTube.channel_default_tab = function() { } } }; - + /*----------------------------------------------------------------------------- >>> GENERAL ------------------------------------------------------------------------------- @@ -1355,7 +1373,7 @@ ImprovedTube.mark_watched_videos = function() { } } }; - + /*----------------------------------------------------------------------------- >>> PLAYER ------------------------------------------------------------------------------- @@ -2127,7 +2145,7 @@ ImprovedTube.player_rotate_button = function() { onclick: function() { var video = document.querySelector('.html5-video-player video'), transform = '', - rotate = (video.style.transform.match(/rotate\([0-9.]+deg\)/g) || [''])[0]; + rotate = (document.querySelector('.it-rotate-styles') && document.querySelector('.it-rotate-styles').textContent.match(/rotate\([0-9.]+deg\)/g) || [''])[0]; rotate = Number((rotate.match(/[0-9.]+/g) || [])[0]) || 0; @@ -2143,12 +2161,23 @@ ImprovedTube.player_rotate_button = function() { transform += ' scale(' + video.offsetHeight / video.offsetWidth + ')'; } - video.style.transform = transform; + //video.style.transform = transform; + + if (!document.querySelector('.it-rotate-styles')) { + var styles = document.createElement('style'); + + styles.className = 'it-rotate-styles'; + + document.body.appendChild(styles); + } + + document.querySelector('.it-rotate-styles').textContent = '.html5-video-player:not(it-mini-player) video {transform:' + transform + '}'; }, title: 'Rotate' }); } else if (document.querySelector('.it-rotate-button')) { document.querySelector('.it-rotate-button').remove(); + document.querySelector('.it-rotate-styles').remove(); } }; @@ -2214,7 +2243,7 @@ ImprovedTube.player_loudness_normalization = function() { } } }; - + /*----------------------------------------------------------------------------- >>> PLAYLIST ------------------------------------------------------------------------------- @@ -2460,7 +2489,7 @@ ImprovedTube.playlist_up_next_autoplay = function(player) { player.querySelector('video').removeEventListener('timeupdate', ImprovedTube.playlist_up_next_autoplay_f, true); player.querySelector('video').addEventListener('timeupdate', ImprovedTube.playlist_up_next_autoplay_f, true); }; - + /*----------------------------------------------------------------------------- >>> SETTINGS ------------------------------------------------------------------------------- @@ -2694,7 +2723,7 @@ ImprovedTube.youtube_language = function() { location.reload(); }, 100); }; - + /*----------------------------------------------------------------------------- >>> SHORTCUTS ------------------------------------------------------------------------------- @@ -3087,7 +3116,7 @@ ImprovedTube.shortcuts = function() { capture: true }); }; - + /*----------------------------------------------------------------------------- >>> THEMES ------------------------------------------------------------------------------- @@ -3325,7 +3354,7 @@ ImprovedTube.themeEditor = function() { document.documentElement.appendChild(style); } - + /*----------------------------------------------------------------------------- >>> VOLUME MIXER ------------------------------------------------------------------------------- @@ -3336,7 +3365,7 @@ ImprovedTube.themeEditor = function() { 1.0 Inject -----------------------------------------------------------------------------*/ -ImprovedTube.volumeMixer = function() {}; +ImprovedTube.volumeMixer = function() {}; /*----------------------------------------------------------------------------- >>> FUNCTIONS ------------------------------------------------------------------------------- @@ -3438,7 +3467,7 @@ ImprovedTube.pageType = function() { chrome.runtime.sendMessage({ enabled: true -}); +}); /*----------------------------------------------------------------------------- >>> INJECTION ------------------------------------------------------------------------------- @@ -3581,7 +3610,7 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { }, 250); } }); - + /*----------------------------------------------------------------------------- >>> MIGRATION ------------------------------------------------------------------------------- @@ -4118,7 +4147,7 @@ chrome.storage.local.get(function(object) { location.reload(); } -}); +}); /*----------------------------------------------------------------------------- >>> MUTATIONS ------------------------------------------------------------------------------- diff --git a/manifest.json b/manifest.json index d8f2113f2..0121921fa 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "short_name" : "ImprovedTube", "name": "Improve YouTube! (Open-Source for YouTube)", - "version": "3.80", + "version": "3.100", "icons": { "16": "assets/icons/16.png", "32": "assets/icons/32.png", diff --git a/popup.js b/popup.js index f9c2c2dc5..5ad669c1d 100644 --- a/popup.js +++ b/popup.js @@ -1,4 +1,4 @@ - + var Menu = { header: { type: 'header', @@ -95,7 +95,7 @@ var Menu = { } } }; - + Menu.main = { type: 'main', appearanceId: 'home', @@ -122,7 +122,7 @@ Menu.main = { found_a_bug: { type: 'button', class: 'satus-button--found-a-bug', - label: 'foundABug', + label: 'found a bug?', title: '/ImprovedTube/ImprovedTube', onclick: function(){ window.open('https://github.com/ImprovedTube/ImprovedTube/issues/new', '_blank'); @@ -154,7 +154,7 @@ Menu.main = { } } }; - + Menu.header.section_end.button_vert.onClickRender.active_features = { type: 'folder', before: '', @@ -214,7 +214,7 @@ Menu.header.section_end.button_vert.onClickRender.active_features = { }); } } -}; +}; Menu.header.section_end.button_vert.onClickRender.mixer = { type: 'folder', before: '', @@ -329,7 +329,7 @@ Menu.header.section_end.button_vert.onClickRender.mixer = { } } }; - + Menu.header.section_end.button_vert.onClickRender.settings = { type: 'folder', before: '', @@ -1201,7 +1201,7 @@ Menu.header.section_end.button_vert.onClickRender.settings = { } } }; - + Menu.main.section.general = { type: 'folder', before: '', @@ -1295,7 +1295,7 @@ Menu.main.section.general = { } } }; - + Menu.main.section.appearance = { type: 'folder', before: '', @@ -1355,11 +1355,11 @@ Menu.main.section.appearance = { section: { type: 'section', - player_hide_annotations: { + /*player_hide_annotations: { type: 'switch', label: 'hideAnnotations', tags: 'hide,remove,elements' - }, + },*/ player_hide_cards: { type: 'switch', label: 'hideCards', @@ -1575,7 +1575,30 @@ Menu.main.section.appearance = { section: { type: 'section', - + sidebar_left: { + type: 'switch', + label: 'Sidebar on the Left' + }, + thumbnails_right: { + type: 'switch', + label: 'Thumbnails on the Right' + }, + related_videos: { + type: 'select', + label: 'relatedVideos', + options: [{ + label: 'normal', + value: 'normal' + }, { + label: 'collapsed', + value: 'collapsed' + }, { + label: 'hidden', + value: 'hidden' + }], + tags: 'right' + }, + livechat: { type: 'select', label: 'liveChat', @@ -1606,21 +1629,6 @@ Menu.main.section.appearance = { hide_playlist: { type: 'switch', label: 'hidePlaylist' - }, - related_videos: { - type: 'select', - label: 'relatedVideos', - options: [{ - label: 'normal', - value: 'normal' - }, { - label: 'collapsed', - value: 'collapsed' - }, { - label: 'hidden', - value: 'hidden' - }], - tags: 'right' } } }, @@ -1665,7 +1673,7 @@ Menu.main.section.appearance = { } } }; - + function themePopupChange() { if (Satus.storage.get('red_popup_theme') === true) { document.documentElement.setAttribute('popup-theme', 'red'); @@ -2080,7 +2088,7 @@ Menu.main.section.themes = { onchange: themeChange } }; - + Menu.main.section.player = { type: 'folder', before: '', @@ -2358,7 +2366,7 @@ Menu.main.section.player = { } } }; - + Menu.main.section.playlist = { type: 'folder', before: '', @@ -2397,7 +2405,7 @@ Menu.main.section.playlist = { label: 'shuffle' } } -}; +}; Menu.main.section.channel = { type: 'folder', before: '', @@ -2432,7 +2440,7 @@ Menu.main.section.channel = { label: 'hideFeaturedContent' } } -}; +}; Menu.main.section.shortcuts = { type: 'folder', before: '', @@ -2657,7 +2665,7 @@ Menu.main.section.shortcuts = { } } }; - + Menu.main.section.blacklist = { type: 'folder', before: '', @@ -2819,7 +2827,7 @@ Menu.main.section.blacklist = { } } }; - + Menu.main.section.analyzer = { type: 'folder', before: '', @@ -2966,7 +2974,7 @@ Menu.main.section.analyzer = { } } }; - + chrome.storage.local.get(function(items) { for (var key in items) { document.documentElement.setAttribute('it-' + key.replace(/_/g, '-'), items[key]); diff --git a/satus.css b/satus.css index 7f032cc4c..bf6648b33 100644 --- a/satus.css +++ b/satus.css @@ -1,291 +1,187 @@ -/*-------------------------------------------------------------- ->>> BUTTON ---------------------------------------------------------------*/ - -.satus-button -{ - font-size: inherit; - - position: relative; - - display: flex; - - margin: 0; - - cursor: pointer; - - color: inherit; - border: none; - outline: none; - background-color: var(--satus-theme-button); - - -webkit-tap-highlight-color: transparent; - align-items: center; - -webkit-appearance: none; -} - -.satus-button::before -{ - position: absolute; - top: 0; - left: 0; - - width: 100%; - height: 100%; - - content: ''; - - opacity: 0; - background-color: var(--satus-theme-ripple); -} - -.satus-button:focus::before, -.satus-button:hover::before -{ - opacity: 1; -} - -.satus-button__icon -{ - width: 24px; - height: 24px; -} - -.satus-button svg -{ - width: 100%; - - color: inherit; - - fill: var(--satus-theme-primary); -} - -.satus-button__icon + .satus-button__label -{ - margin-left: 8px; -} - -/*-------------------------------------------------------------- ->>> COLOR PICKER ---------------------------------------------------------------*/ - -.satus-color-picker -{ - font-size: inherit; - - position: relative; - - display: flex; - - box-sizing: border-box; - margin: 0; - - cursor: pointer; - - color: inherit; - border: none; - outline: none; - background-color: var(--satus-theme-button); - - justify-content: space-between; - -webkit-tap-highlight-color: transparent; - align-items: center; - -webkit-appearance: none; -} +/*----------------------------------------------------------------------------- +>>> ANIMATIONS +-----------------------------------------------------------------------------*/ -.satus-color-picker__value +.satus-animation--fade-in { - width: 24px; - height: 24px; - - border-radius: 50%; + animation: fadeIn 250ms; } -.satus-dialog--color-picker .satus-scrollbar__content +.satus-animation--fade-out { - display: flex; - flex-direction: column; - - align-items: center; + animation: fadeOut 250ms; } -.satus-dialog--color-picker .satus-button +.satus-animation--fade-in-left { - box-sizing: unset; - width: 24px; - height: 24px; - margin: 0 0 8px; - padding: 8px; - - border-radius: 50%; -} - -.satus-dialog--color-picker .satus-button:hover -{ - background-color: var(--satus-theme-ripple); + animation: fadeInLeft 250ms; } -.satus-dialog--color-picker .satus-button::before +.satus-animation--fade-in-right { - content: unset; + animation: fadeInRight 250ms; } -.satus-dialog--color-picker .satus-button svg +.satus-animation--fade-out-left { - fill: transparent; - stroke: var(--satus-theme-primary); + animation: fadeOutLeft 250ms; } -.satus-dialog--color-picker canvas +.satus-animation--fade-out-right { - width: 200px; - height: 200px; - margin: 0 0 16px; + animation: fadeOutRight 250ms; } - -/*-------------------------------------------------------------- ->>> DIALOG ---------------------------------------------------------------*/ -.satus-dialog +@keyframes fadeIn { - position: absolute; - z-index: 100; - top: 0; - left: 0; - - display: flex; - - width: 100%; - height: 100vh; + from + { + opacity: 0; + } + to + { + transform: translateX(0%); - justify-content: center; - align-items: center; + opacity: 1; + } } -.satus-dialog__scrim +@keyframes fadeOut { - position: absolute; - top: 0; - left: 0; - - width: 100%; - height: 100%; - - animation: fadeIn 150ms linear forwards; - - opacity: 0; - background: rgba(25,25,25,.2); + from + { + opacity: 1; + } + to + { + transform: translateX(0%); - fill: var(--satus-theme-dialog-text); - backdrop-filter: blur(8px); + opacity: 0; + } } -.satus-dialog__surface +@keyframes fadeInLeft { - font-size: 14px; - - display: flex; - flex-direction: column; - - width: 95%; - min-width: 240px; - max-width: 560px; - max-height: 80%; - padding: 8px 0; - - transform: scale(.8); - animation: zoomIn 150ms linear forwards; - animation-delay: 20ms; - - opacity: 0; - color: var(--satus-theme-dialog-text); - border-radius: 6px; - background-color: var(--satus-theme-dialog); - box-shadow: inset 0 -1px 1px 1px rgba(0,0,0,.1), 0 2px 6px rgba(0, 0, 0, .15); -} + from + { + transform: translateX(-10%); -.satus-dialog--closing .satus-dialog__scrim -{ - animation: fadeOut 70ms linear forwards; -} + opacity: 0; + } + to + { + transform: translateX(0%); -.satus-dialog--closing .satus-dialog__surface -{ - animation: zoomOut 70ms linear forwards; + opacity: 1; + } } -@keyframes fadeIn +@keyframes fadeInRight { from { + transform: translateX(10%); + opacity: 0; } to { + transform: translateX(0%); + opacity: 1; } } -@keyframes fadeOut +@keyframes fadeOutLeft { from { + transform: translateX(0%); + opacity: 1; } to { + transform: translateX(-10%); + opacity: 0; } } -@keyframes zoomIn +@keyframes fadeOutRight { from { - transform: scale(.8); + transform: translateX(0%); - opacity: 0; + opacity: 1; } to { - transform: scale(1); + transform: translateX(10%); - opacity: 1; + opacity: 0; } } + +/*----------------------------------------------------------------------------- +>>> THEMES +------------------------------------------------------------------------------- +1.0 Default +-----------------------------------------------------------------------------*/ -@keyframes zoomOut +html { - from - { - transform: scale(1); + --satus-theme-primary: #f6b465; - opacity: 1; - } - to - { - transform: scale(.8); + --satus-theme-dialog: #f7f7f6; + --satus-theme-dialog-text: #777; + + --satus-theme-header: #fff; + --satus-theme-header-text: #777; + + --satus-theme-main: #f7f7f6; + --satus-theme-main-text: #777; + + --satus-theme-section: #fff; + + --satus-theme-button: transparent; + + --satus-theme-scrollbar: rgba(0, 0, 0, .2); + --satus-theme-scrollbar-focus: rgba(0, 0, 0, .4); + + --satus-theme-tooltip: rgba(0, 0, 0, .4); - opacity: 0; - } + --satus-theme-ripple: rgba(0, 0, 0, .04); + + + + + --satus-theme-tabs-background: #efefef; + --satus-theme-tabs-border: #dfdfdf; } /*-------------------------------------------------------------- ->>> FOLDER +>>> TABLE --------------------------------------------------------------*/ -.satus-folder +.satus-table { - text-align: left + font-size: .875rem; + + position: relative; + + overflow: hidden; + display: flex; + flex-direction: column; + box-sizing: border-box; + + border: 1px solid #ececec; + border-radius: 6px; } - -/*-------------------------------------------------------------- ->>> HEADER ---------------------------------------------------------------*/ -.satus-header +.satus-table__head { position: relative; z-index: 1; @@ -294,246 +190,287 @@ box-sizing: border-box; width: 100%; - min-height: 58px; + height: 44px; padding: 0 8px; - color: var(--satus-theme-header-text); - background-color: var(--satus-theme-header); - box-shadow: 0 0 3px rgba(0,0,0,.1); - - fill: var(--satus-theme-header-text); + background: #fff; + box-shadow: 0 2px 4px rgba(0, 0, 0, .1); } -.satus-header .satus-text--title +.satus-table__head > div { - font-size: 15px; - font-weight: 400; + font-weight: 600; + + display: inline-flex; + + box-sizing: border-box; + padding: 0 8px 0 0; + + opacity: .7; + + flex-shrink: 0; + align-items: center; } - -/*-------------------------------------------------------------- ->>> LIST ---------------------------------------------------------------*/ -.satus-list--compact, -.satus-list--compact li +.satus-table__head > div:last-child { - margin: 0; padding: 0; +} - list-style: none; +.satus-table__head > div:hover +{ + cursor: pointer; + + opacity: 1; } - -/*----------------------------------------------------------------------------- ->>> MAIN -------------------------------------------------------------------------------- -1.0 General -2.0 Animations - 2.1 Opening - 2.2 Closing ------------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------- -1.0 General ------------------------------------------------------------------------------*/ +.satus-table__head > div[data-sorting=false]:hover +{ + cursor: default; +} -.satus-main +.satus-table__head > div > span { position: relative; +} - overflow: hidden; +.satus-table__head > div[data-sorting=asc] > span::after +{ + position: absolute; + top: calc(50% - 2px); + right: -14px; - width: 100%; - height: 100%; + width: 0; + height: 0; - color: var(--satus-theme-main-text); - background-color: var(--satus-theme-main); + content: ''; - fill: var(--satus-theme-main-text); + border-right: 4px solid transparent; + border-bottom: 5px solid currentColor; + border-left: 4px solid transparent; } -.satus-main__container +.satus-table__head > div[data-sorting=desc] > span::after { position: absolute; - top: 0; - left: 0; - - overflow: auto; - - box-sizing: border-box; - width: 100%; - height: 100%; + top: calc(50% - 2px); + right: -13px; - transition: 250ms; + width: 0; + height: 0; - background-color: var(--satus-theme-main); + content: ''; - will-change: transform; + border-top: 5px solid currentColor; + border-right: 4px solid transparent; + border-left: 4px solid transparent; } +.satus-table__body +{ + overflow: hidden; + flex: 1; -/*----------------------------------------------------------------------------- -2.0 Animations ------------------------------------------------------------------------------*/ + width: 100%; + height: calc(100% - 48px); -.satus-main__container--fade-in-left -{ - animation: fadeInLeft 250ms; + background: #fff; } -.satus-main__container--fade-in-right +.satus-table__row { - animation: fadeInRight 250ms; + display: flex; + + padding: 0 8px; + + box-sizing: border-box; + + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + + flex-wrap: wrap; } -.satus-main__container--fade-out-left +.satus-table__row:nth-child(2n) { - animation: fadeOutLeft 250ms; + background: rgba(0,0,0,.03) } -.satus-main__container--fade-out-right +.satus-table__cell { - animation: fadeOutRight 250ms; -} + overflow: hidden; -@keyframes fadeInLeft -{ - from - { - transform: translateX(-10%); + box-sizing: border-box; + padding: 8px 8px 8px 0; - opacity: 0; - } - to - { - transform: translateX(0%); + white-space: nowrap; + word-wrap: break-word; + -webkit-hyphens: auto; + -moz-hyphens: auto; + hyphens: auto; - opacity: 1; - } + overflow-wrap: break-word; + flex-shrink: 0; + + text-overflow: ellipsis; } -@keyframes fadeInRight +.satus-table__cell:last-child { - from - { - transform: translateX(10%); - - opacity: 0; - } - to - { - transform: translateX(0%); - - opacity: 1; - } + padding-right: 0; } -@keyframes fadeOutLeft +.satus-table__cell input { - from - { - transform: translateX(0%); + width: 100%; + margin: 5px 0; + border: 1px solid #d2d2d2; + box-sizing: border-box; + padding: 1px 2px; + border-radius: 4px; + height: calc(100% - 10px); + outline: none +} - opacity: 1; - } - to - { - transform: translateX(-10%); - opacity: 0; - } -} -@keyframes fadeOutRight +.satus-table__paging > button { - from - { - transform: translateX(0%); + min-width: 32px; + height: 32px; + padding: 0 8px; - opacity: 1; - } - to - { - transform: translateX(10%); + cursor: pointer; - opacity: 0; - } + color: var(--satus-theme-on-surface, #555); + border: none; + background: transparent; +} + +.satus-table__paging > button.active +{ + color: #2979ff; } -.satus-scrollbar +/*--------------------------------------------------------------- +>>> HEADER +----------------------------------------------------------------- +1.0 Basic +2.0 Buttons + 2.1 Back +3.0 Title +4.0 Vertical menu +---------------------------------------------------------------*/ + +/*--------------------------------------------------------------- +1.0 BASIC +---------------------------------------------------------------*/ + +.satus-header { position: relative; + z-index: 1; - overflow: hidden; + display: flex; + box-sizing: border-box; width: 100%; - height: 100%; + min-height: 58px; + padding: 0 8px; + + color: var(--satus-theme-header-text); + background-color: var(--satus-theme-header); + box-shadow: 0 0 3px rgba(0,0,0,.1); + + fill: var(--satus-theme-header-text); } -.satus-scrollbar__wrapper -{ - overflow-y: scroll; - width: 150%; - height: 100%; +/*--------------------------------------------------------------- +2.0 BUTTONS +---------------------------------------------------------------*/ + +.satus-header .satus-button +{ + width: 36px; + height: 36px; + padding: 6px; } -.satus-scrollbar__thumb +.satus-header .satus-button::before { - position: absolute; - z-index: 999; - top: 0; - right: 0; + border-radius: 50%; +} - min-height: 32px; - padding: 0 2px; - transition: background-color 200ms, opacity 300ms; +/*--------------------------------------------------------------- +3.0 BACK BUTTON +---------------------------------------------------------------*/ - opacity: 0; +.satus-button--back +{ + position: absolute; } -.satus-scrollbar__thumb::after +body[data-appearance='home'] .satus-button--back { - display: block; + visibility: hidden; +} - width: 3px; - height: 100%; - content: ''; +/*--------------------------------------------------------------- +3.0 TITLE +---------------------------------------------------------------*/ - background-color: var(--satus-theme-scrollbar); +.satus-header .satus-text--title +{ + font-size: 15px; + font-weight: 400; + + position: absolute; + left: 56px; } -.satus-scrollbar__thumb:hover::after +body[data-appearance='home'] .satus-text--title { - background-color: var(--satus-theme-scrollbar-focus); + left: 14px; } -.satus-scrollbar.active .satus-scrollbar__thumb, -.satus-scrollbar__thumb:hover + +/*--------------------------------------------------------------- +4.0 VERTICAL MENU +---------------------------------------------------------------*/ + +.satus-dialog--vertical-menu .satus-dialog__surface { - transition: background-color 200ms, opacity 100ms; + position: absolute; + top: 8px; + right: 8px; + left: auto; - opacity: 1; + min-width: 180px; + max-width: 220px; + + transform-origin: right top; } - -/*-------------------------------------------------------------- ->>> SECTION ---------------------------------------------------------------*/ -.satus-section +.satus-dialog--vertical-menu .satus-button, +.satus-dialog--vertical-menu .satus-folder { - display: inline-flex; - - box-sizing: border-box; + width: 100%; + height: 36px; + padding: 0 16px; - align-items: center; - flex: 1; + text-align: left; } -.satus-main .satus-section +.satus-dialog--vertical-menu .satus-folder svg, +.satus-dialog--vertical-menu .satus-button svg { - background-color: var(--satus-theme-section); + width: 20px; + height: 18px; + margin: 0 14px 0 0; + + opacity: .75; } /*-------------------------------------------------------------- @@ -602,8 +539,17 @@ opacity: 1; } } + +.satus-section--align-end +{ + justify-content: flex-end; +} -.satus-shortcut +/*-------------------------------------------------------------- +>>> SWITCH +--------------------------------------------------------------*/ + +.satus-switch { position: relative; @@ -612,209 +558,285 @@ box-sizing: border-box; width: 100%; height: 48px; - min-height: 48px; padding: 0 16px; cursor: pointer; + -webkit-user-select: none; + -moz-user-select: -moz-none; + user-select: none; + + background-color: transparent; - justify-content: space-between; align-items: center; + justify-content: space-between; } -.satus-shortcut:hover +.satus-switch:hover { background-color: var(--satus-theme-ripple); } -.satus-shortcut > .label +.satus-switch__input { - margin: 0 0 4px 0; -} + position: absolute; + z-index: 1; + top: 0; + left: 0; -.satus-shortcut > .value -{ - font-size: 13px; + width: 100%; + height: 100%; + margin: 0; + padding: 0; - opacity: .5; + opacity: 0; + outline: none; + + -webkit-appearance: none; } -.satus-shortcut-dialog-label -{ - font-size: 16px; - font-weight: 500; - box-sizing: border-box; - width: 100%; - margin: 4px 0 10px; - padding: 0 16px; -} +/* LABEL */ -.satus-shortcut__canvas +.satus-switch__label { - display: flex; + padding: 0 16px 0 0; +} - box-sizing: border-box; - width: 100%; - height: 68px; - padding: 16px; - background: #dedede; +/* TRACK*/ - align-items: center; +.satus-switch__track +{ + position: relative; + + width: 32px; + min-width: 32px; + height: 18px; + + border-radius: 18px; + background: #bdbdbd; } -.satus-shortcut__key +.satus-switch__track::before { - display: flex; + position: absolute; + top: -7px; + left: -7px; - box-sizing: border-box; - min-width: 32px; + width: 32px; height: 32px; - padding: 4px 8px; - border-radius: 4px; - background: #fff; - box-shadow: 0 1px 3px rgba(0,0,0,.15), inset 0 -3px 0 rgba(0,0,0,.1); + content: ''; + transition: left .1s cubic-bezier(.4, 0, .2, 1), transform 200ms, background-color 200ms; + transform: scale(0); - align-items: center; - justify-content: center; + opacity: 0; + border-radius: 50%; + background-color: #000; + + will-change: left, transform, background-color; } -.satus-shortcut__plus +.satus-switch__input:checked + .satus-switch__track::before { - position: relative; + left: 8px; - width: 12px; - height: 12px; - margin: 8px; + background-color: var(--satus-theme-primary, #54d2a3); } -.satus-shortcut__plus::before +.satus-switch__input:focus + .satus-switch__track::before { - position: absolute; - top: 0; - left: 5px; - - width: 2px; - height: 12px; + transform: scale(1); - content: ''; + opacity: .08; +} - background-color: #aaa; +.satus-switch__input:checked:focus + .satus-switch__track::before +{ + opacity: .25; } -.satus-shortcut__plus::after +.satus-switch__track::after { position: absolute; - top: 5px; - left: 0; - width: 12px; - height: 2px; + width: 14px; + height: 14px; content: ''; + transition: transform .1s cubic-bezier(.4, 0, .2, 1); + transform: translate(2px, 2px); + + border-radius: 50%; + background-color: #fff; + + will-change: transform; +} - background-color: #aaa; +.satus-switch__input:checked + .satus-switch__track +{ + background: var(--satus-theme-primary, #54d2a3); } -.satus-shortcut__mouse +.satus-switch__input:checked + .satus-switch__track::after +{ + transform: translate(16px, 2px); +} + +/*-------------------------------------------------------------- +>>> TABS +--------------------------------------------------------------*/ + +.satus-tabs__bar { position: relative; display: flex; + overflow: hidden; - width: 28px; - height: 36px; + box-sizing: border-box; + width: calc(100% - 16px); + margin: 16px 8px 4px; - border-radius: 50%; - border-top-left-radius: 12px; - border-top-right-radius: 12px; - background: #fff; - box-shadow: 0 1px 3px rgba(0,0,0,.15), inset 0 -3px 0 rgba(0,0,0,.1); + border: 1px solid var(--satus-theme-tabs-border); + border-radius: 18px; + background-color: var(--satus-theme-tabs-background); } -.satus-shortcut__mouse > div +.satus-tabs__bar > div:not(.satus-tabs__bar--select) { - position: absolute; - top: 0; - left: 13px; + z-index: 1; - width: 2px; - height: 11px; + display: flex; - border-radius: 2px; - background: #ccc; + height: 32px; + + cursor: pointer; + transition: opacity .25s; + + opacity: .5; + + flex: 1; + align-items: center; + justify-content: center; } -.satus-shortcut__mouse::before +.satus-tabs__bar > div.active +{ + opacity: 1; +} + +.satus-tabs__bar--select { position: absolute; - top: -4px; - left: 21px; + z-index: 0; + left: 0; - width: 2px; - height: 18px; + width: 50%; + height: 32px; - content: ''; + transition: left .25s; - background: #f96754; + border-radius: 18px; + background: var(--satus-theme-header); + box-shadow: 1px 0 4px rgba(0,0,0,.075); } -.satus-shortcut__mouse.false::after +.satus-tabs__main { - position: absolute; - top: -12px; - left: 17px; + position: relative +} - width: 0; - height: 0; +.satus-tabs__main > div +{ + display: inline-block; + width: 100%; + min-height: 100%; +} - content: ''; +.satus-tabs__main > .old +{ + position: absolute; + left: 0; + top: 0; +} + +.satus-tabs__tab.satus-animation--fade-out-left:not(.old) +{ + z-index: 1 +} + +/*-------------------------------------------------------------- +>>> FOLDER +--------------------------------------------------------------*/ - border-right: 5px solid transparent; - border-bottom: 8px solid #f96754; - border-left: 5px solid transparent; +.satus-folder +{ + text-align: left } + +/*-------------------------------------------------------------- +>>> TEXT +--------------------------------------------------------------*/ -.satus-shortcut__mouse.true::after +.satus-text-field { - position: absolute; - top: 14px; - left: 17px; - - width: 0; - height: 0; + font: inherit; - content: ''; + box-sizing: border-box; + width: 100%; + margin: 0; + padding: 0; + padding: 0 8px; - border-top: 8px solid #f96754; - border-right: 5px solid transparent; - border-left: 5px solid transparent; + color: inherit; + border: none; + outline: none; + background: unset; } + +/*----------------------------------------------------------------------------- +>>> MAIN +------------------------------------------------------------------------------- +1.0 General +-----------------------------------------------------------------------------*/ -.satus-section_shortcut +/*----------------------------------------------------------------------------- +1.0 General +-----------------------------------------------------------------------------*/ + +.satus-main { + position: relative; + + overflow: hidden; + width: 100%; - margin: 8px 0 0; + height: 100%; - justify-content: flex-end; + color: var(--satus-theme-main-text); + background-color: var(--satus-theme-main); + + fill: var(--satus-theme-main-text); } -.satus-button_shortcut +.satus-main__container { - font-weight: 500; + position: absolute; + top: 0; + left: 0; - overflow: hidden; + overflow: auto; - height: 28px; - min-height: 28px; - margin-right: 2px; - padding: 4px 8px; + box-sizing: border-box; + width: 100%; + height: 100%; - text-transform: uppercase; + transition: 250ms; - color: #f96754; - border-radius: 4px; + background-color: var(--satus-theme-main); + + will-change: transform; } /*-------------------------------------------------------------- @@ -987,416 +1009,684 @@ visibility: visible; } -.satus-slider__ring +.satus-slider__ring +{ + position: absolute; + top: -11px; + right: -18px; + + width: 24px; + height: 24px; + + transition: 100ms; + transform: scale(0); + + opacity: 0; + border-radius: 50%; + background-color: var(--satus-theme-primary); +} + +.satus-slider__range:focus + .satus-slider__container .satus-slider__ring +{ + transform: scale(1); + + opacity: .25; +} + +.satus-scrollbar +{ + position: relative; + + overflow: hidden; + + width: 100%; + height: 100%; +} + +.satus-scrollbar__wrapper +{ + overflow-y: scroll; + + width: 150%; + height: 100%; +} + +.satus-scrollbar__content +{ + min-height: 100%; +} + +.satus-scrollbar__thumb +{ + position: absolute; + z-index: 999; + top: 0; + right: 0; + + min-height: 32px; + padding: 0 2px; + + transition: background-color 200ms, opacity 300ms; + + opacity: 0; +} + +.satus-scrollbar__thumb::after +{ + display: block; + + width: 3px; + height: 100%; + + content: ''; + + background-color: var(--satus-theme-scrollbar); +} + +.satus-scrollbar__thumb:hover::after +{ + background-color: var(--satus-theme-scrollbar-focus); +} + +.satus-scrollbar.active .satus-scrollbar__thumb, +.satus-scrollbar__thumb:hover +{ + transition: background-color 200ms, opacity 100ms; + + opacity: 1; +} + +/*-------------------------------------------------------------- +>>> LIST +--------------------------------------------------------------*/ + +.satus-list--compact, +.satus-list--compact li +{ + margin: 0; + padding: 0; + + list-style: none; +} + +/*-------------------------------------------------------------- +>>> DIALOG +--------------------------------------------------------------*/ + +.satus-dialog +{ + position: absolute; + z-index: 100; + top: 0; + left: 0; + + display: flex; + + width: 100%; + height: 100vh; + + justify-content: center; + align-items: center; +} + +.satus-dialog__scrim +{ + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + animation: fadeIn 150ms linear forwards; + + opacity: 0; + background: rgba(25,25,25,.2); + + fill: var(--satus-theme-dialog-text); + backdrop-filter: blur(8px); +} + +.satus-dialog__surface +{ + font-size: 14px; + + display: flex; + flex-direction: column; + + width: 95%; + min-width: 240px; + max-width: 560px; + max-height: 80%; + padding: 8px 0; + + transform: scale(.8); + animation: zoomIn 150ms linear forwards; + animation-delay: 20ms; + + opacity: 0; + color: var(--satus-theme-dialog-text); + border-radius: 6px; + background-color: var(--satus-theme-dialog); + box-shadow: inset 0 -1px 1px 1px rgba(0,0,0,.1), 0 2px 6px rgba(0, 0, 0, .15); +} + +.satus-dialog--closing .satus-dialog__scrim +{ + animation: fadeOut 70ms linear forwards; +} + +.satus-dialog--closing .satus-dialog__surface +{ + animation: zoomOut 70ms linear forwards; +} + +@keyframes fadeIn +{ + from + { + opacity: 0; + } + to + { + opacity: 1; + } +} + +@keyframes fadeOut +{ + from + { + opacity: 1; + } + to + { + opacity: 0; + } +} + +@keyframes zoomIn { - position: absolute; - top: -11px; - right: -18px; - - width: 24px; - height: 24px; + from + { + transform: scale(.8); - transition: 100ms; - transform: scale(0); + opacity: 0; + } + to + { + transform: scale(1); - opacity: 0; - border-radius: 50%; - background-color: var(--satus-theme-primary); + opacity: 1; + } } -.satus-slider__range:focus + .satus-slider__container .satus-slider__ring +@keyframes zoomOut { - transform: scale(1); + from + { + transform: scale(1); - opacity: .25; + opacity: 1; + } + to + { + transform: scale(.8); + + opacity: 0; + } } /*-------------------------------------------------------------- ->>> SWITCH +>>> BUTTON --------------------------------------------------------------*/ -.satus-switch +.satus-button { + font-size: inherit; + font-family: inherit; + position: relative; display: flex; - box-sizing: border-box; - width: 100%; - height: 48px; - padding: 0 16px; + margin: 0; cursor: pointer; - -webkit-user-select: none; - -moz-user-select: -moz-none; - user-select: none; - background-color: transparent; + color: inherit; + border: none; + outline: none; + background-color: var(--satus-theme-button); + -webkit-tap-highlight-color: transparent; align-items: center; - justify-content: space-between; -} - -.satus-switch:hover -{ - background-color: var(--satus-theme-ripple); + -webkit-appearance: none; } -.satus-switch__input +.satus-button::before { position: absolute; - z-index: 1; top: 0; left: 0; width: 100%; height: 100%; - margin: 0; - padding: 0; - opacity: 0; - outline: none; + content: ''; - -webkit-appearance: none; + opacity: 0; + background-color: var(--satus-theme-ripple); } - -/* LABEL */ - -.satus-switch__label +.satus-button:focus::before, +.satus-button:hover::before { - padding: 0 16px 0 0; + opacity: 1; } +.satus-button__icon +{ + width: 24px; + height: 24px; +} -/* TRACK*/ - -.satus-switch__track +.satus-button svg { - position: relative; + width: 100%; - width: 32px; - min-width: 32px; - height: 18px; + color: inherit; +} - border-radius: 18px; - background: #bdbdbd; +.satus-button__icon + .satus-button__label +{ + margin-left: 8px; } + +/*-------------------------------------------------------------- +>>> TEXT +--------------------------------------------------------------*/ -.satus-switch__track::before +.satus-text { - position: absolute; - top: -7px; - left: -7px; + margin: 0; - width: 32px; - height: 32px; + color: inherit; + border: none; + font-family: inherit; +} + +/*-------------------------------------------------------------- +>>> SECTION +--------------------------------------------------------------*/ - content: ''; - transition: left .1s cubic-bezier(.4, 0, .2, 1), transform 200ms, background-color 200ms; - transform: scale(0); +.satus-section +{ + display: inline-flex; - opacity: 0; - border-radius: 50%; - background-color: #000; + box-sizing: border-box; - will-change: left, transform, background-color; + align-items: center; + flex: 1; } -.satus-switch__input:checked + .satus-switch__track::before +.satus-main .satus-section { - left: 8px; + background-color: var(--satus-theme-section); +} - background-color: var(--satus-theme-primary, #54d2a3); +.satus-section--label +{ + font-size: 17px; + display: block; + width: calc(100% - 16px); + max-width: 900px; + margin: 16px auto 8px; } + +/*-------------------------------------------------------------- +>>> COLOR PICKER +--------------------------------------------------------------*/ -.satus-switch__input:focus + .satus-switch__track::before +.satus-color-picker { - transform: scale(1); + font-size: inherit; - opacity: .08; + position: relative; + + display: flex; + + box-sizing: border-box; + margin: 0; + + cursor: pointer; + + color: inherit; + border: none; + outline: none; + background-color: var(--satus-theme-button); + + justify-content: space-between; + -webkit-tap-highlight-color: transparent; + align-items: center; + -webkit-appearance: none; } -.satus-switch__input:checked:focus + .satus-switch__track::before +.satus-color-picker__value { - opacity: .25; + width: 24px; + height: 24px; + + border-radius: 50%; } -.satus-switch__track::after +.satus-dialog--color-picker .satus-scrollbar__content { - position: absolute; + display: flex; + flex-direction: column; - width: 14px; - height: 14px; + align-items: center; +} - content: ''; - transition: transform .1s cubic-bezier(.4, 0, .2, 1); - transform: translate(2px, 2px); +.satus-dialog--color-picker .satus-button +{ + box-sizing: unset; + width: 24px; + height: 24px; + margin: 0 0 8px; + padding: 8px; border-radius: 50%; - background-color: #fff; +} - will-change: transform; +.satus-dialog--color-picker .satus-button:hover +{ + background-color: var(--satus-theme-ripple); } -.satus-switch__input:checked + .satus-switch__track +.satus-dialog--color-picker .satus-button::before { - background: var(--satus-theme-primary, #54d2a3); + content: unset; } -.satus-switch__input:checked + .satus-switch__track::after +.satus-dialog--color-picker .satus-button svg { - transform: translate(16px, 2px); + fill: transparent; + stroke: var(--satus-theme-primary); } - -/*-------------------------------------------------------------- ->>> TABLE ---------------------------------------------------------------*/ -.satus-table +.satus-dialog--color-picker canvas { - font-size: .875rem; + width: 200px; + height: 200px; + margin: 0 0 16px; +} + +/*--------------------------------------------------------------- +>>> SHORTCUT +----------------------------------------------------------------- +# Canvas +# Popup +---------------------------------------------------------------*/ +.satus-shortcut +{ position: relative; - overflow: hidden; display: flex; - flex-direction: column; + overflow: hidden; + box-sizing: border-box; + width: 100%; + height: 48px; + min-height: 48px; + padding: 0 16px; - border: 1px solid #ececec; - border-radius: 6px; + cursor: pointer; + + justify-content: space-between; + align-items: center; +} + +.satus-shortcut:hover +{ + background-color: var(--satus-theme-ripple); +} + +.satus-shortcut .satus-shortcut__label, +.satus-shortcut .satus-shortcut__value +{ + flex: 1 } -.satus-table__head +.satus-shortcut .satus-shortcut__label + .satus-shortcut__value { - position: relative; - z-index: 1; + justify-content: flex-end +} + +/*--------------------------------------------------------------- +# CANVAS +---------------------------------------------------------------*/ + +.satus-shortcut__value +{ display: flex; box-sizing: border-box; width: 100%; - height: 44px; - padding: 0 8px; + height: 48px; - background: #fff; - box-shadow: 0 2px 4px rgba(0, 0, 0, .1); + align-items: center; } -.satus-table__head > div + +.satus-shortcut__key { - font-weight: 600; + font-size: 12px; + line-height: 12px; - display: inline-flex; + display: flex; box-sizing: border-box; - padding: 0 8px 0 0; + min-width: 28px; + height: 28px; + padding: 4px 8px; - opacity: .7; + border: 1px solid rgba(0,0,0,.1); + border-radius: 4px; + background: #fff; + box-shadow: 0 1px 1px rgba(0,0,0,.1), inset 0 -1px 0 rgba(0,0,0,.1); - flex-shrink: 0; align-items: center; + justify-content: center; } -.satus-table__head > div:last-child -{ - padding: 0; -} - -.satus-table__head > div:hover -{ - cursor: pointer; - - opacity: 1; -} - -.satus-table__head > div[data-sorting=false]:hover -{ - cursor: default; -} - -.satus-table__head > div > span +.satus-shortcut__plus { position: relative; + + width: 10px; + height: 10px; + margin: 8px 6px; } -.satus-table__head > div[data-sorting=asc] > span::after +.satus-shortcut__plus::before { position: absolute; - top: calc(50% - 2px); - right: -14px; + top: 0; + left: 4px; - width: 0; - height: 0; + width: 2px; + height: 10px; content: ''; - border-right: 4px solid transparent; - border-bottom: 5px solid currentColor; - border-left: 4px solid transparent; + background-color: #ccc; } -.satus-table__head > div[data-sorting=desc] > span::after +.satus-shortcut__plus::after { position: absolute; - top: calc(50% - 2px); - right: -13px; + top: 4px; + left: 0; - width: 0; - height: 0; + width: 10px; + height: 2px; content: ''; - border-top: 5px solid currentColor; - border-right: 4px solid transparent; - border-left: 4px solid transparent; + background-color: #ccc; } -.satus-table__body +.satus-shortcut__mouse { - overflow: hidden; - flex: 1; + position: relative; - width: 100%; - height: calc(100% - 48px); + display: flex; + width: 24px; + height: 32px; + + border-radius: 50%; + border-top-left-radius: 12px; + border-top-right-radius: 12px; background: #fff; + box-shadow: 0 1px 3px rgba(0,0,0,.15), inset 0 -3px 0 rgba(0,0,0,.1); } -.satus-table__row +.satus-shortcut__mouse > div { - display: flex; - - padding: 0 8px; - - box-sizing: border-box; - - border-bottom: 1px solid rgba(0, 0, 0, 0.1); - - flex-wrap: wrap; -} + position: absolute; + top: 0; + left: 11px; -.satus-table__row:nth-child(2n) -{ - background: rgba(0,0,0,.03) + width: 2px; + height: 10px; + + border-radius: 2px; + background: #ccc; } -.satus-table__cell +.satus-shortcut__mouse::before { - overflow: hidden; + position: absolute; + top: 0; + left: 18px; - box-sizing: border-box; - padding: 8px 8px 8px 0; + width: 2px; + height: 14px; - white-space: nowrap; - word-wrap: break-word; - -webkit-hyphens: auto; - -moz-hyphens: auto; - hyphens: auto; + content: ''; - overflow-wrap: break-word; - flex-shrink: 0; - - text-overflow: ellipsis; + background: #f96754; } -.satus-table__cell:last-child +.satus-shortcut__mouse.false::after { - padding-right: 0; -} + position: absolute; + top: -5px; + left: 15px; -.satus-table__cell input -{ - width: 100%; - margin: 5px 0; - border: 1px solid #d2d2d2; - box-sizing: border-box; - padding: 1px 2px; - border-radius: 4px; - height: calc(100% - 10px); - outline: none -} + width: 0; + height: 0; + content: ''; + border-right: 4px solid transparent; + border-bottom: 6px solid #f96754; + border-left: 4px solid transparent; +} -.satus-table__paging > button +.satus-shortcut__mouse.true::after { - min-width: 32px; - height: 32px; - padding: 0 8px; + position: absolute; + top: 13px; + left: 15px; - cursor: pointer; + width: 0; + height: 0; - color: var(--satus-theme-on-surface, #555); - border: none; - background: transparent; + content: ''; + + border-top: 6px solid #f96754; + border-right: 4px solid transparent; + border-left: 4px solid transparent; } -.satus-table__paging > button.active -{ - color: #2979ff; +.satus-shortcut__mouse.click::before { + position: absolute; + top: 0px; + left: -1px; + width: 10px; + height: 10px; + content: ''; + background: #f96754; + border-radius: 50%; } - -/*-------------------------------------------------------------- ->>> TEXT ---------------------------------------------------------------*/ -.satus-text +.satus-shortcut__mouse.context::before { + position: absolute; + top: 0px; + left: 15px; + width: 10px; + height: 10px; + content: ''; + background: #f96754; + border-radius: 50%; +} + + +/*--------------------------------------------------------------- +# POPUP +---------------------------------------------------------------*/ + +.satus-shortcut-dialog-label { - margin: 0; + font-size: 16px; + font-weight: 500; - color: inherit; - border: none; + box-sizing: border-box; + width: 100%; + margin: 4px 0 10px; + padding: 0 16px; } - -/*-------------------------------------------------------------- ->>> TEXT ---------------------------------------------------------------*/ -.satus-text-field +.satus-shortcut__canvas { - font: inherit; + display: flex; box-sizing: border-box; width: 100%; - margin: 0; - padding: 0; - padding: 0 8px; + height: 68px; + padding: 16px; - color: inherit; - border: none; - outline: none; - background: unset; + background: #dedede; + + align-items: center; } - -/*----------------------------------------------------------------------------- ->>> THEMES -------------------------------------------------------------------------------- -1.0 Default ------------------------------------------------------------------------------*/ -html +.satus-section_shortcut { - --satus-theme-primary: #f6b465; - - --satus-theme-dialog: #f7f7f6; - --satus-theme-dialog-text: #777; - - --satus-theme-header: #fff; - --satus-theme-header-text: #777; + width: 100%; + margin: 8px 0 0; - --satus-theme-main: #f7f7f6; - --satus-theme-main-text: #777; + justify-content: flex-end; +} - --satus-theme-section: #fff; +.satus-button_shortcut +{ + font-weight: 500; - --satus-theme-button: transparent; + overflow: hidden; - --satus-theme-scrollbar: rgba(0, 0, 0, .2); - --satus-theme-scrollbar-focus: rgba(0, 0, 0, .4); + height: 28px; + min-height: 28px; + margin-right: 2px; + padding: 4px 8px; - --satus-theme-tooltip: rgba(0, 0, 0, .4); + text-transform: uppercase; - --satus-theme-ripple: rgba(0, 0, 0, .04); -} \ No newline at end of file + color: #f96754; + border-radius: 4px; +} diff --git a/satus.js b/satus.js index 5ccd74c14..959069050 100644 --- a/satus.js +++ b/satus.js @@ -73,114 +73,6 @@ Satus.getAnimationDuration = function(element) { return Number(window.getComputedStyle(element).getPropertyValue('animation-duration').replace(/[^0-9.]/g, '')) * 1000; }; -/*-------------------------------------------------------------- ->>> CHROMIUM STORAGE ----------------------------------------------------------------- -1.0 Get -2.0 Set -3.0 Import -4.0 Clear ---------------------------------------------------------------*/ - -Satus.storage = {}; - -/*-------------------------------------------------------------- -# GET ---------------------------------------------------------------*/ - -Satus.storage.get = function(name) { - var target = Satus.storage; - - name = name.split('/').filter(function(value) { - return value != ''; - }); - - for (var i = 0, l = name.length; i < l; i++) { - if (Satus.isset(target[name[i]])) { - target = target[name[i]]; - } else { - return undefined; - } - } - - return target; -}; - - -/*-------------------------------------------------------------- -# SET ---------------------------------------------------------------*/ - -Satus.storage.set = function(name, value) { - var items = {}, - target = Satus.storage; - - if (!Satus.isset(name)) { - return false; - } - - name = name.split('/').filter(function(value) { - return value != ''; - }); - - for (var i = 0, l = name.length; i < l; i++) { - var item = name[i]; - - if (i < l - 1) { - - if (target[item]) { - target = target[item]; - } else { - target[item] = {}; - - target = target[item]; - } - } else { - target[item] = value; - } - } - - for (var key in Satus.storage) { - if (typeof Satus.storage[key] !== 'function') { - items[key] = Satus.storage[key]; - } - } - - chrome.storage.local.set(items); -}; - - -/*-------------------------------------------------------------- -# IMPORT ---------------------------------------------------------------*/ - -Satus.storage.import = function(callback) { - chrome.storage.local.get(function(items) { - for (var key in items) { - Satus.storage[key] = items[key]; - } - - if (callback) { - callback(); - } - }); -}; - - -/*-------------------------------------------------------------- -# CLEAR ---------------------------------------------------------------*/ - -Satus.storage.clear = function() { - chrome.storage.local.clear(); - - for (var key in Satus.storage) { - if (typeof Satus.storage[key] !== 'function') { - delete Satus.storage[key]; - } - } -}; - /*-------------------------------------------------------------- # LOCALE --------------------------------------------------------------*/ @@ -244,95 +136,6 @@ Satus.locale.import = function(src, callback) { xhr.send(); }; /*-------------------------------------------------------------- ->>> RENDER ---------------------------------------------------------------*/ - -Satus.render = function(element, container, callback) { - function convert(object) { - if (object && object.type) { - var type = Satus.camelize(object.type), - component = Satus.components[type](object), - excluded_properties = ['type', 'label', 'class', 'title', 'storage']; - - function applyProperties(object, target) { - for (var key in object) { - if (Satus.isset(object[key]) && typeof object[key] === 'object' && !object[key].type) { - if (typeof target[key] !== 'object') { - target[key] = {}; - } - - applyProperties(object[key], target[key]); - } else if (excluded_properties.indexOf(key) === -1) { - target[key] = object[key]; - } - } - } - - applyProperties(object, component); - - component.classList.add('satus-' + object.type); - - if (object.class) { - var class_list = object.class.split(' '); - - for (var i = 0, l = class_list.length; i < l; i++) { - component.classList.add(class_list[i]); - } - } - - if (object.before) { - var component_before = document.createElement('span'); - - component_before.innerHTML = object.before; - - for (var i = component_before.children.length - 1; i > -1; i--) { - component.insertBefore(component_before.children[i], component.firstChild); - } - } - - if (object.after) { - var component_after = document.createElement('span'); - - component_after.innerHTML = object.after; - - for (var i = component_after.children.length - 1; i > -1; i--) { - component.appendChild(component_after.children[i]); - } - } - - (container || document.body).appendChild(component); - - if (typeof component.onClickRender === 'object') { - component.addEventListener('click', function() { - Satus.render(component.onClickRender); - }); - } - - if (Satus.isset(Satus.events.render)) { - for (var i = 0, l = Satus.events.render.length; i < l; i++) { - Satus.events.render[i](component, object); - } - } - - if (typeof component.onrender === 'function') { - component.onrender(object); - } - - if (callback) { - callback(); - } - } - } - - if (element.type) { - convert(element); - } else { - for (var key in element) { - convert(element[key]); - } - } -}; -/*-------------------------------------------------------------- # CLONE NODE STYLES --------------------------------------------------------------*/ @@ -343,84 +146,25 @@ Satus.cloneNodeStyles = function(origin, target) { Satus.cloneNodeStyles(origin.children[i], target.children[i]); } }; -/*----------------------------------------------------------------------------- ->>> «SEARCH» MODULE ------------------------------------------------------------------------------*/ - -Satus.search = function(query, object, callback, categories) { - var threads = 0, - folder = '', - results = {}; - - function parse(items) { - threads++; - - for (var key in items) { - var item = items[key]; - - if (categories === true && item.type === 'folder' && folder !== item.label) { - folder = item.label; - } - - if (['switch', 'select', 'slider'].indexOf(item.type) !== -1 && key.indexOf(query) !== -1) { - if (categories === true) { - if (!results[folder]) { - results[folder] = {}; - } - - results[folder][key] = item; - } else { - results[key] = item; - } - } +Satus.on('render', function(component, data) { + if (data.perspective === true) { + component.style.willChange = 'transform'; + component.style.transformStyle = 'preserve-3d'; + component.style.transition = '.4s'; - if (typeof item === 'object') { - parse(item); - } - } + component.addEventListener('mousemove', function(event) { + var bounding = component.getBoundingClientRect(), + dx = event.clientX - bounding.left - bounding.width / 2, + dy = event.clientY - bounding.top - bounding.height / 2; - threads--; + this.style.transform = 'perspective(440px) rotateX(' + dy * -1 + 'deg) rotateY(' + dx + 'deg) translateZ(0)'; + }); - if (threads === 0) { - callback(results); - } + component.addEventListener('mouseout', function(event) { + this.style.transform = 'perspective(440px) rotateX(0deg) rotateY(0deg) translateZ(0)'; + }); } - - parse(object); -}; - -/*-------------------------------------------------------------- ->>> STORAGE KEYS ---------------------------------------------------------------*/ - -Satus.modules.updateStorageKeys = function(object, callback) { - var threads = 0; - - function parse(items) { - threads++; - - for (var key in items) { - var item = items[key]; - - - if (item.type) { - item.storage_key = key; - } - - if (typeof item === 'object') { - parse(item); - } - } - - threads--; - - if (threads === 0) { - callback(); - } - } - - parse(object); -}; +}); /*----------------------------------------------------------------------------- >>> «USER» MODULE ------------------------------------------------------------------------------- @@ -781,374 +525,844 @@ Satus.modules.user = function() { return data; }; -Satus.on('render', function(component, data) { - if (data.perspective === true) { - component.style.willChange = 'transform'; - component.style.transformStyle = 'preserve-3d'; - component.style.transition = '.4s'; - - component.addEventListener('mousemove', function(event) { - var bounding = component.getBoundingClientRect(), - dx = event.clientX - bounding.left - bounding.width / 2, - dy = event.clientY - bounding.top - bounding.height / 2; +/*-------------------------------------------------------------- +>>> CHROMIUM STORAGE +---------------------------------------------------------------- +1.0 Get +2.0 Set +3.0 Import +4.0 Clear +--------------------------------------------------------------*/ - this.style.transform = 'perspective(440px) rotateX(' + dy * -1 + 'deg) rotateY(' + dx + 'deg) translateZ(0)'; - }); +Satus.storage = { + data: {} +}; - component.addEventListener('mouseout', function(event) { - this.style.transform = 'perspective(440px) rotateX(0deg) rotateY(0deg) translateZ(0)'; - }); - } -}); /*-------------------------------------------------------------- ->>> BUTTON +# GET --------------------------------------------------------------*/ -Satus.components.button = function(element) { - var component = document.createElement('button'); +Satus.storage.get = function(name) { + if (satus.isset(name)) { + var target = Satus.storage; - if (Satus.isset(element.icon)) { - var component_icon = document.createElement('span'); + name = name.split('/').filter(function(value) { + return value != ''; + }); - component_icon.className = 'satus-button__icon'; - component_icon.innerHTML = element.icon; + for (var i = 0, l = name.length; i < l; i++) { + if (Satus.isset(target[name[i]])) { + target = target[name[i]]; + } else { + return undefined; + } + } - component.appendChild(component_icon); + return target; } +}; - if (Satus.isset(element.label)) { - var component_label = document.createElement('span'); - - component_label.className = 'satus-button__label'; - component_label.innerText = Satus.locale.getMessage(element.label); - - component.appendChild(component_label); - } - return component; -}; /*-------------------------------------------------------------- ->>> COLOR PICKER +# SET --------------------------------------------------------------*/ -Satus.components.colorPicker = function(element) { - var component = document.createElement('div'), - component_value = document.createElement('div'); - - element.class = 'satus-button'; - component_value.className = 'satus-color-picker__value'; - component_value.style.backgroundColor = Satus.storage.get(element.storage_key) || element.value || ''; - - if (Satus.isset(element.label)) { - var component_label = document.createElement('span'); - - component_label.className = 'satus-button__label'; - component_label.innerText = Satus.locale.getMessage(element.label); - - component.appendChild(component_label); +Satus.storage.set = function(name, value) { + var items = {}, + target = Satus.storage; + + if (!Satus.isset(name)) { + return false; } - component.addEventListener('click', function() { - var component = document.createElement('div'), - component_canvas = document.createElement('canvas'), - close = document.createElement('button'), - ctx = component_canvas.getContext('2d'), - image = new Image(), - dialog = Satus.components.dialog({}); - - close.className = 'satus-button'; - close.innerHTML = ''; - close.onclick = function() { - dialog.querySelector('.satus-dialog__scrim').click(); - }; - - dialog.className = 'satus-dialog satus-dialog--color-picker'; + name = name.split('/').filter(function(value) { + return value != ''; + }); - component_canvas.width = 200; - component_canvas.height = 200; + for (var i = 0, l = name.length; i < l; i++) { + var item = name[i]; - function select(event) { - var coordinates = component_canvas.getBoundingClientRect(), - x = event.clientX - coordinates.left, - y = event.clientY - coordinates.top, - color = ctx.getImageData(x, y, 1, 1).data; + if (i < l - 1) { - component_value.style.backgroundColor = 'rgb(' + color[0] + ',' + color[1] + ',' + color[2] + ')'; + if (target[item]) { + target = target[item]; + } else { + target[item] = {}; - Satus.storage.set(element.storage_key, component_value.style.backgroundColor); + target = target[item]; + } + } else { + target[item] = value; } + } - function mouseup(event) { - component_canvas.removeEventListener('mousemove', select); - window.removeEventListener('mouseup', mouseup); + for (var key in Satus.storage) { + if (typeof Satus.storage[key] !== 'function') { + items[key] = Satus.storage[key]; } + } - component_canvas.addEventListener('mousedown', function() { - select(event); - this.addEventListener('mousemove', select); - window.addEventListener('mouseup', mouseup); - }); - - image.onload = function() { - ctx.drawImage(image, 0, 0); + chrome.storage.local.set(items); +}; - image.remove(); - }; - image.src = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNzAgMjcwIj48ZGVmcz48cmFkaWFsR3JhZGllbnQgaWQ9ImEiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvcmFkaWFsR3JhZGllbnQ+PC9kZWZzPjxnIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMTMzIiBjbGFzcz0iSXJvV2hlZWxIdWUiPjxwYXRoIHN0cm9rZT0iaHNsKDI0MCwgMTAwJSwgNTAlKSIgZD0iTTIwMS40NzcgMTM2Ljc0YTY2LjUgNjYuNSAwIDAwLjAyMy0xLjc0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjQxLCAxMDAlLCA1MCUpIiBkPSJNMjAxLjQzNyAxMzcuOWE2Ni41IDY2LjUgMCAwMC4wNTMtMS43NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDI0MiwgMTAwJSwgNTAlKSIgZD0iTTIwMS4zNzYgMTM5LjA2YTY2LjUgNjYuNSAwIDAwLjA4My0xLjc0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjQzLCAxMDAlLCA1MCUpIiBkPSJNMjAxLjI5NSAxNDAuMjE4YTY2LjUgNjYuNSAwIDAwLjExNC0xLjczOCIvPjxwYXRoIHN0cm9rZT0iaHNsKDI0NCwgMTAwJSwgNTAlKSIgZD0iTTIwMS4xOTQgMTQxLjM3NGE2Ni41IDY2LjUgMCAwMC4xNDQtMS43MzUiLz48cGF0aCBzdHJva2U9ImhzbCgyNDUsIDEwMCUsIDUwJSkiIGQ9Ik0yMDEuMDczIDE0Mi41MjhhNjYuNSA2Ni41IDAgMDAuMTc0LTEuNzMyIi8+PHBhdGggc3Ryb2tlPSJoc2woMjQ2LCAxMDAlLCA1MCUpIiBkPSJNMjAwLjkzMSAxNDMuNjhhNjYuNSA2Ni41IDAgMDAuMjA1LTEuNzI5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjQ3LCAxMDAlLCA1MCUpIiBkPSJNMjAwLjc3IDE0NC44M2E2Ni41IDY2LjUgMCAwMC4yMzQtMS43MjYiLz48cGF0aCBzdHJva2U9ImhzbCgyNDgsIDEwMCUsIDUwJSkiIGQ9Ik0yMDAuNTg4IDE0NS45NzZhNjYuNSA2Ni41IDAgMDAuMjY1LTEuNzIxIi8+PHBhdGggc3Ryb2tlPSJoc2woMjQ5LCAxMDAlLCA1MCUpIiBkPSJNMjAwLjM4NiAxNDcuMTE5YTY2LjUgNjYuNSAwIDAwLjI5NS0xLjcxNiIvPjxwYXRoIHN0cm9rZT0iaHNsKDI1MCwgMTAwJSwgNTAlKSIgZD0iTTIwMC4xNjUgMTQ4LjI1OGE2Ni41IDY2LjUgMCAwMC4zMjUtMS43MSIvPjxwYXRoIHN0cm9rZT0iaHNsKDI1MSwgMTAwJSwgNTAlKSIgZD0iTTE5OS45MjQgMTQ5LjM5M2E2Ni41IDY2LjUgMCAwMC4zNTQtMS43MDQiLz48cGF0aCBzdHJva2U9ImhzbCgyNTIsIDEwMCUsIDUwJSkiIGQ9Ik0xOTkuNjYzIDE1MC41MjRhNjYuNSA2Ni41IDAgMDAuMzg0LTEuNjk4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjUzLCAxMDAlLCA1MCUpIiBkPSJNMTk5LjM4MiAxNTEuNjVhNjYuNSA2Ni41IDAgMDAuNDE0LTEuNjkiLz48cGF0aCBzdHJva2U9ImhzbCgyNTQsIDEwMCUsIDUwJSkiIGQ9Ik0xOTkuMDgxIDE1Mi43NzFhNjYuNSA2Ni41IDAgMDAuNDQ0LTEuNjgzIi8+PHBhdGggc3Ryb2tlPSJoc2woMjU1LCAxMDAlLCA1MCUpIiBkPSJNMTk4Ljc2MiAxNTMuODg3YTY2LjUgNjYuNSAwIDAwLjQ3Mi0xLjY3NiIvPjxwYXRoIHN0cm9rZT0iaHNsKDI1NiwgMTAwJSwgNTAlKSIgZD0iTTE5OC40MjIgMTU0Ljk5N2E2Ni41IDY2LjUgMCAwMC41MDItMS42NjciLz48cGF0aCBzdHJva2U9ImhzbCgyNTcsIDEwMCUsIDUwJSkiIGQ9Ik0xOTguMDY0IDE1Ni4xYTY2LjUgNjYuNSAwIDAwLjUzLTEuNjU3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjU4LCAxMDAlLCA1MCUpIiBkPSJNMTk3LjY4NiAxNTcuMTk4YTY2LjUgNjYuNSAwIDAwLjU2LTEuNjQ4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjU5LCAxMDAlLCA1MCUpIiBkPSJNMTk3LjI4OSAxNTguMjg5YTY2LjUgNjYuNSAwIDAwLjU4OC0xLjYzOSIvPjxwYXRoIHN0cm9rZT0iaHNsKDI2MCwgMTAwJSwgNTAlKSIgZD0iTTE5Ni44NzMgMTU5LjM3MmE2Ni41IDY2LjUgMCAwMC42MTctMS42MjgiLz48cGF0aCBzdHJva2U9ImhzbCgyNjEsIDEwMCUsIDUwJSkiIGQ9Ik0xOTYuNDM4IDE2MC40NDhhNjYuNSA2Ni41IDAgMDAuNjQ1LTEuNjE3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjYyLCAxMDAlLCA1MCUpIiBkPSJNMTk1Ljk4NCAxNjEuNTE3YTY2LjUgNjYuNSAwIDAwLjY3NC0xLjYwNiIvPjxwYXRoIHN0cm9rZT0iaHNsKDI2MywgMTAwJSwgNTAlKSIgZD0iTTE5NS41MTIgMTYyLjU3N2E2Ni41IDY2LjUgMCAwMC43MDItMS41OTMiLz48cGF0aCBzdHJva2U9ImhzbCgyNjQsIDEwMCUsIDUwJSkiIGQ9Ik0xOTUuMDIyIDE2My42MjlhNjYuNSA2Ni41IDAgMDAuNzI5LTEuNTgxIi8+PHBhdGggc3Ryb2tlPSJoc2woMjY1LCAxMDAlLCA1MCUpIiBkPSJNMTk0LjUxMyAxNjQuNjcyYTY2LjUgNjYuNSAwIDAwLjc1Ni0xLjU2OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDI2NiwgMTAwJSwgNTAlKSIgZD0iTTE5My45ODYgMTY1LjcwNmE2Ni41IDY2LjUgMCAwMC43ODQtMS41NTQiLz48cGF0aCBzdHJva2U9ImhzbCgyNjcsIDEwMCUsIDUwJSkiIGQ9Ik0xOTMuNDQxIDE2Ni43MzFhNjYuNSA2Ni41IDAgMDAuODEtMS41NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDI2OCwgMTAwJSwgNTAlKSIgZD0iTTE5Mi44NzkgMTY3Ljc0NmE2Ni41IDY2LjUgMCAwMC44MzctMS41MjYiLz48cGF0aCBzdHJva2U9ImhzbCgyNjksIDEwMCUsIDUwJSkiIGQ9Ik0xOTIuMjk4IDE2OC43NTFhNjYuNSA2Ni41IDAgMDAuODY0LTEuNTExIi8+PHBhdGggc3Ryb2tlPSJoc2woMjcwLCAxMDAlLCA1MCUpIiBkPSJNMTkxLjcgMTY5Ljc0NmE2Ni41IDY2LjUgMCAwMC44OS0xLjQ5NiIvPjxwYXRoIHN0cm9rZT0iaHNsKDI3MSwgMTAwJSwgNTAlKSIgZD0iTTE5MS4wODYgMTcwLjczYTY2LjUgNjYuNSAwIDAwLjkxNi0xLjQ4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjcyLCAxMDAlLCA1MCUpIiBkPSJNMTkwLjQ1MyAxNzEuNzA0YTY2LjUgNjYuNSAwIDAwLjk0Mi0xLjQ2NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDI3MywgMTAwJSwgNTAlKSIgZD0iTTE4OS44MDQgMTcyLjY2NmE2Ni41IDY2LjUgMCAwMC45NjgtMS40NDgiLz48cGF0aCBzdHJva2U9ImhzbCgyNzQsIDEwMCUsIDUwJSkiIGQ9Ik0xODkuMTM5IDE3My42MTdhNjYuNSA2Ni41IDAgMDAuOTkyLTEuNDMiLz48cGF0aCBzdHJva2U9ImhzbCgyNzUsIDEwMCUsIDUwJSkiIGQ9Ik0xODguNDU2IDE3NC41NTZhNjYuNSA2Ni41IDAgMDAxLjAxOC0xLjQxMyIvPjxwYXRoIHN0cm9rZT0iaHNsKDI3NiwgMTAwJSwgNTAlKSIgZD0iTTE4Ny43NTggMTc1LjQ4M2E2Ni41IDY2LjUgMCAwMDEuMDQyLTEuMzk1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjc3LCAxMDAlLCA1MCUpIiBkPSJNMTg3LjA0MyAxNzYuMzk3YTY2LjUgNjYuNSAwIDAwMS4wNjYtMS4zNzYiLz48cGF0aCBzdHJva2U9ImhzbCgyNzgsIDEwMCUsIDUwJSkiIGQ9Ik0xODYuMzEzIDE3Ny4zYTY2LjUgNjYuNSAwIDAwMS4wOS0xLjM1OSIvPjxwYXRoIHN0cm9rZT0iaHNsKDI3OSwgMTAwJSwgNTAlKSIgZD0iTTE4NS41NjcgMTc4LjE4OGE2Ni41IDY2LjUgMCAwMDEuMTEzLTEuMzM4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjgwLCAxMDAlLCA1MCUpIiBkPSJNMTg0LjgwNiAxNzkuMDY0YTY2LjUgNjYuNSAwIDAwMS4xMzYtMS4zMTkiLz48cGF0aCBzdHJva2U9ImhzbCgyODEsIDEwMCUsIDUwJSkiIGQ9Ik0xODQuMDI5IDE3OS45MjdhNjYuNSA2Ni41IDAgMDAxLjE2LTEuMyIvPjxwYXRoIHN0cm9rZT0iaHNsKDI4MiwgMTAwJSwgNTAlKSIgZD0iTTE4My4yMzcgMTgwLjc3NmE2Ni41IDY2LjUgMCAwMDEuMTgyLTEuMjc5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjgzLCAxMDAlLCA1MCUpIiBkPSJNMTgyLjQzMSAxODEuNjFhNjYuNSA2Ni41IDAgMDAxLjIwNC0xLjI1NyIvPjxwYXRoIHN0cm9rZT0iaHNsKDI4NCwgMTAwJSwgNTAlKSIgZD0iTTE4MS42MSAxODIuNDMxYTY2LjUgNjYuNSAwIDAwMS4yMjYtMS4yMzYiLz48cGF0aCBzdHJva2U9ImhzbCgyODUsIDEwMCUsIDUwJSkiIGQ9Ik0xODAuNzc2IDE4My4yMzdhNjYuNSA2Ni41IDAgMDAxLjI0Ny0xLjIxNCIvPjxwYXRoIHN0cm9rZT0iaHNsKDI4NiwgMTAwJSwgNTAlKSIgZD0iTTE3OS45MjcgMTg0LjAyOWE2Ni41IDY2LjUgMCAwMDEuMjY4LTEuMTkzIi8+PHBhdGggc3Ryb2tlPSJoc2woMjg3LCAxMDAlLCA1MCUpIiBkPSJNMTc5LjA2NCAxODQuODA2YTY2LjUgNjYuNSAwIDAwMS4yODktMS4xNzEiLz48cGF0aCBzdHJva2U9ImhzbCgyODgsIDEwMCUsIDUwJSkiIGQ9Ik0xNzguMTg4IDE4NS41NjdhNjYuNSA2Ni41IDAgMDAxLjMxLTEuMTQ4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjg5LCAxMDAlLCA1MCUpIiBkPSJNMTc3LjMgMTg2LjMxM2E2Ni41IDY2LjUgMCAwMDEuMzI4LTEuMTI1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjkwLCAxMDAlLCA1MCUpIiBkPSJNMTc2LjM5NyAxODcuMDQzYTY2LjUgNjYuNSAwIDAwMS4zNDgtMS4xMDEiLz48cGF0aCBzdHJva2U9ImhzbCgyOTEsIDEwMCUsIDUwJSkiIGQ9Ik0xNzUuNDgzIDE4Ny43NThhNjYuNSA2Ni41IDAgMDAxLjM2Ny0xLjA3OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDI5MiwgMTAwJSwgNTAlKSIgZD0iTTE3NC41NTYgMTg4LjQ1NmE2Ni41IDY2LjUgMCAwMDEuMzg1LTEuMDUzIi8+PHBhdGggc3Ryb2tlPSJoc2woMjkzLCAxMDAlLCA1MCUpIiBkPSJNMTczLjYxNyAxODkuMTM5YTY2LjUgNjYuNSAwIDAwMS40MDQtMS4wMyIvPjxwYXRoIHN0cm9rZT0iaHNsKDI5NCwgMTAwJSwgNTAlKSIgZD0iTTE3Mi42NjYgMTg5LjgwNGE2Ni41IDY2LjUgMCAwMDEuNDIyLTEuMDA0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjk1LCAxMDAlLCA1MCUpIiBkPSJNMTcxLjcwNCAxOTAuNDUzYTY2LjUgNjYuNSAwIDAwMS40MzktLjk4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjk2LCAxMDAlLCA1MCUpIiBkPSJNMTcwLjczIDE5MS4wODZhNjYuNSA2Ni41IDAgMDAxLjQ1Ni0uOTU1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjk3LCAxMDAlLCA1MCUpIiBkPSJNMTY5Ljc0NiAxOTEuN2E2Ni41IDY2LjUgMCAwMDEuNDcyLS45MjgiLz48cGF0aCBzdHJva2U9ImhzbCgyOTgsIDEwMCUsIDUwJSkiIGQ9Ik0xNjguNzUxIDE5Mi4yOThhNjYuNSA2Ni41IDAgMDAxLjQ4OS0uOTAzIi8+PHBhdGggc3Ryb2tlPSJoc2woMjk5LCAxMDAlLCA1MCUpIiBkPSJNMTY3Ljc0NiAxOTIuODc5YTY2LjUgNjYuNSAwIDAwMS41MDQtLjg3NyIvPjxwYXRoIHN0cm9rZT0iaHNsKDMwMCwgMTAwJSwgNTAlKSIgZD0iTTE2Ni43MzEgMTkzLjQ0MWE2Ni41IDY2LjUgMCAwMDEuNTE5LS44NSIvPjxwYXRoIHN0cm9rZT0iaHNsKDMwMSwgMTAwJSwgNTAlKSIgZD0iTTE2NS43MDYgMTkzLjk4NmE2Ni41IDY2LjUgMCAwMDEuNTM0LS44MjQiLz48cGF0aCBzdHJva2U9ImhzbCgzMDIsIDEwMCUsIDUwJSkiIGQ9Ik0xNjQuNjcyIDE5NC41MTNhNjYuNSA2Ni41IDAgMDAxLjU0OC0uNzk3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzAzLCAxMDAlLCA1MCUpIiBkPSJNMTYzLjYyOSAxOTUuMDIyYTY2LjUgNjYuNSAwIDAwMS41NjEtLjc3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzA0LCAxMDAlLCA1MCUpIiBkPSJNMTYyLjU3NyAxOTUuNTEyYTY2LjUgNjYuNSAwIDAwMS41NzUtLjc0MiIvPjxwYXRoIHN0cm9rZT0iaHNsKDMwNSwgMTAwJSwgNTAlKSIgZD0iTTE2MS41MTcgMTk1Ljk4NGE2Ni41IDY2LjUgMCAwMDEuNTg3LS43MTUiLz48cGF0aCBzdHJva2U9ImhzbCgzMDYsIDEwMCUsIDUwJSkiIGQ9Ik0xNjAuNDQ4IDE5Ni40MzhhNjYuNSA2Ni41IDAgMDAxLjYtLjY4NyIvPjxwYXRoIHN0cm9rZT0iaHNsKDMwNywgMTAwJSwgNTAlKSIgZD0iTTE1OS4zNzIgMTk2Ljg3M2E2Ni41IDY2LjUgMCAwMDEuNjEyLS42NiIvPjxwYXRoIHN0cm9rZT0iaHNsKDMwOCwgMTAwJSwgNTAlKSIgZD0iTTE1OC4yODkgMTk3LjI4OWE2Ni41IDY2LjUgMCAwMDEuNjIyLS42MzEiLz48cGF0aCBzdHJva2U9ImhzbCgzMDksIDEwMCUsIDUwJSkiIGQ9Ik0xNTcuMTk4IDE5Ny42ODZhNjYuNSA2Ni41IDAgMDAxLjYzMy0uNjAzIi8+PHBhdGggc3Ryb2tlPSJoc2woMzEwLCAxMDAlLCA1MCUpIiBkPSJNMTU2LjEgMTk4LjA2NGE2Ni41IDY2LjUgMCAwMDEuNjQ0LS41NzQiLz48cGF0aCBzdHJva2U9ImhzbCgzMTEsIDEwMCUsIDUwJSkiIGQ9Ik0xNTQuOTk3IDE5OC40MjJhNjYuNSA2Ni41IDAgMDAxLjY1My0uNTQ1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzEyLCAxMDAlLCA1MCUpIiBkPSJNMTUzLjg4NyAxOTguNzYyYTY2LjUgNjYuNSAwIDAwMS42NjMtLjUxNyIvPjxwYXRoIHN0cm9rZT0iaHNsKDMxMywgMTAwJSwgNTAlKSIgZD0iTTE1Mi43NzEgMTk5LjA4MWE2Ni41IDY2LjUgMCAwMDEuNjcyLS40ODciLz48cGF0aCBzdHJva2U9ImhzbCgzMTQsIDEwMCUsIDUwJSkiIGQ9Ik0xNTEuNjUgMTk5LjM4MmE2Ni41IDY2LjUgMCAwMDEuNjgtLjQ1OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDMxNSwgMTAwJSwgNTAlKSIgZD0iTTE1MC41MjQgMTk5LjY2M2E2Ni41IDY2LjUgMCAwMDEuNjg3LS40MjkiLz48cGF0aCBzdHJva2U9ImhzbCgzMTYsIDEwMCUsIDUwJSkiIGQ9Ik0xNDkuMzkzIDE5OS45MjRhNjYuNSA2Ni41IDAgMDAxLjY5NS0uNCIvPjxwYXRoIHN0cm9rZT0iaHNsKDMxNywgMTAwJSwgNTAlKSIgZD0iTTE0OC4yNTggMjAwLjE2NWE2Ni41IDY2LjUgMCAwMDEuNzAxLS4zNyIvPjxwYXRoIHN0cm9rZT0iaHNsKDMxOCwgMTAwJSwgNTAlKSIgZD0iTTE0Ny4xMTkgMjAwLjM4NmE2Ni41IDY2LjUgMCAwMDEuNzA3LS4zNCIvPjxwYXRoIHN0cm9rZT0iaHNsKDMxOSwgMTAwJSwgNTAlKSIgZD0iTTE0NS45NzYgMjAwLjU4OGE2Ni41IDY2LjUgMCAwMDEuNzEzLS4zMSIvPjxwYXRoIHN0cm9rZT0iaHNsKDMyMCwgMTAwJSwgNTAlKSIgZD0iTTE0NC44MyAyMDAuNzdhNjYuNSA2Ni41IDAgMDAxLjcxOC0uMjgiLz48cGF0aCBzdHJva2U9ImhzbCgzMjEsIDEwMCUsIDUwJSkiIGQ9Ik0xNDMuNjggMjAwLjkzMWE2Ni41IDY2LjUgMCAwMDEuNzIzLS4yNSIvPjxwYXRoIHN0cm9rZT0iaHNsKDMyMiwgMTAwJSwgNTAlKSIgZD0iTTE0Mi41MjggMjAxLjA3M2E2Ni41IDY2LjUgMCAwMDEuNzI3LS4yMiIvPjxwYXRoIHN0cm9rZT0iaHNsKDMyMywgMTAwJSwgNTAlKSIgZD0iTTE0MS4zNzQgMjAxLjE5NGE2Ni41IDY2LjUgMCAwMDEuNzMtLjE5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzI0LCAxMDAlLCA1MCUpIiBkPSJNMTQwLjIxOCAyMDEuMjk1YTY2LjUgNjYuNSAwIDAwMS43MzMtLjE2Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzI1LCAxMDAlLCA1MCUpIiBkPSJNMTM5LjA2IDIwMS4zNzZhNjYuNSA2Ni41IDAgMDAxLjczNi0uMTMiLz48cGF0aCBzdHJva2U9ImhzbCgzMjYsIDEwMCUsIDUwJSkiIGQ9Ik0xMzcuOSAyMDEuNDM3YTY2LjUgNjYuNSAwIDAwMS43MzktLjA5OSIvPjxwYXRoIHN0cm9rZT0iaHNsKDMyNywgMTAwJSwgNTAlKSIgZD0iTTEzNi43NCAyMDEuNDc3YTY2LjUgNjYuNSAwIDAwMS43NC0uMDY4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzI4LCAxMDAlLCA1MCUpIiBkPSJNMTM1LjU4IDIwMS40OTdhNjYuNSA2Ni41IDAgMDAxLjc0LS4wMzgiLz48cGF0aCBzdHJva2U9ImhzbCgzMjksIDEwMCUsIDUwJSkiIGQ9Ik0xMzQuNDIgMjAxLjQ5N2E2Ni41IDY2LjUgMCAwMDEuNzQtLjAwNyIvPjxwYXRoIHN0cm9rZT0iaHNsKDMzMCwgMTAwJSwgNTAlKSIgZD0iTTEzMy4yNiAyMDEuNDc3YTY2LjUgNjYuNSAwIDAwMS43NC4wMjMiLz48cGF0aCBzdHJva2U9ImhzbCgzMzEsIDEwMCUsIDUwJSkiIGQ9Ik0xMzIuMSAyMDEuNDM3YTY2LjUgNjYuNSAwIDAwMS43NC4wNTMiLz48cGF0aCBzdHJva2U9ImhzbCgzMzIsIDEwMCUsIDUwJSkiIGQ9Ik0xMzAuOTQgMjAxLjM3NmE2Ni41IDY2LjUgMCAwMDEuNzQuMDgzIi8+PHBhdGggc3Ryb2tlPSJoc2woMzMzLCAxMDAlLCA1MCUpIiBkPSJNMTI5Ljc4MiAyMDEuMjk1YTY2LjUgNjYuNSAwIDAwMS43MzguMTE0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzM0LCAxMDAlLCA1MCUpIiBkPSJNMTI4LjYyNiAyMDEuMTk0YTY2LjUgNjYuNSAwIDAwMS43MzUuMTQ0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzM1LCAxMDAlLCA1MCUpIiBkPSJNMTI3LjQ3MiAyMDEuMDczYTY2LjUgNjYuNSAwIDAwMS43MzIuMTc0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzM2LCAxMDAlLCA1MCUpIiBkPSJNMTI2LjMyIDIwMC45MzFhNjYuNSA2Ni41IDAgMDAxLjcyOS4yMDUiLz48cGF0aCBzdHJva2U9ImhzbCgzMzcsIDEwMCUsIDUwJSkiIGQ9Ik0xMjUuMTcgMjAwLjc3YTY2LjUgNjYuNSAwIDAwMS43MjYuMjM0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzM4LCAxMDAlLCA1MCUpIiBkPSJNMTI0LjAyNCAyMDAuNTg4YTY2LjUgNjYuNSAwIDAwMS43MjEuMjY1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzM5LCAxMDAlLCA1MCUpIiBkPSJNMTIyLjg4MSAyMDAuMzg2YTY2LjUgNjYuNSAwIDAwMS43MTYuMjk1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzQwLCAxMDAlLCA1MCUpIiBkPSJNMTIxLjc0MiAyMDAuMTY1YTY2LjUgNjYuNSAwIDAwMS43MS4zMjUiLz48cGF0aCBzdHJva2U9ImhzbCgzNDEsIDEwMCUsIDUwJSkiIGQ9Ik0xMjAuNjA3IDE5OS45MjRhNjYuNSA2Ni41IDAgMDAxLjcwNC4zNTQiLz48cGF0aCBzdHJva2U9ImhzbCgzNDIsIDEwMCUsIDUwJSkiIGQ9Ik0xMTkuNDc2IDE5OS42NjNhNjYuNSA2Ni41IDAgMDAxLjY5OC4zODQiLz48cGF0aCBzdHJva2U9ImhzbCgzNDMsIDEwMCUsIDUwJSkiIGQ9Ik0xMTguMzUgMTk5LjM4MmE2Ni41IDY2LjUgMCAwMDEuNjkuNDE0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzQ0LCAxMDAlLCA1MCUpIiBkPSJNMTE3LjIyOSAxOTkuMDgxYTY2LjUgNjYuNSAwIDAwMS42ODMuNDQ0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzQ1LCAxMDAlLCA1MCUpIiBkPSJNMTE2LjExMyAxOTguNzYyYTY2LjUgNjYuNSAwIDAwMS42NzYuNDcyIi8+PHBhdGggc3Ryb2tlPSJoc2woMzQ2LCAxMDAlLCA1MCUpIiBkPSJNMTE1LjAwMyAxOTguNDIyYTY2LjUgNjYuNSAwIDAwMS42NjcuNTAyIi8+PHBhdGggc3Ryb2tlPSJoc2woMzQ3LCAxMDAlLCA1MCUpIiBkPSJNMTEzLjkgMTk4LjA2NGE2Ni41IDY2LjUgMCAwMDEuNjU3LjUzIi8+PHBhdGggc3Ryb2tlPSJoc2woMzQ4LCAxMDAlLCA1MCUpIiBkPSJNMTEyLjgwMiAxOTcuNjg2YTY2LjUgNjYuNSAwIDAwMS42NDguNTYiLz48cGF0aCBzdHJva2U9ImhzbCgzNDksIDEwMCUsIDUwJSkiIGQ9Ik0xMTEuNzExIDE5Ny4yODlhNjYuNSA2Ni41IDAgMDAxLjYzOS41ODgiLz48cGF0aCBzdHJva2U9ImhzbCgzNTAsIDEwMCUsIDUwJSkiIGQ9Ik0xMTAuNjI4IDE5Ni44NzNhNjYuNSA2Ni41IDAgMDAxLjYyOC42MTciLz48cGF0aCBzdHJva2U9ImhzbCgzNTEsIDEwMCUsIDUwJSkiIGQ9Ik0xMDkuNTUyIDE5Ni40MzhhNjYuNSA2Ni41IDAgMDAxLjYxNy42NDUiLz48cGF0aCBzdHJva2U9ImhzbCgzNTIsIDEwMCUsIDUwJSkiIGQ9Ik0xMDguNDgzIDE5NS45ODRhNjYuNSA2Ni41IDAgMDAxLjYwNi42NzQiLz48cGF0aCBzdHJva2U9ImhzbCgzNTMsIDEwMCUsIDUwJSkiIGQ9Ik0xMDcuNDIzIDE5NS41MTJhNjYuNSA2Ni41IDAgMDAxLjU5My43MDIiLz48cGF0aCBzdHJva2U9ImhzbCgzNTQsIDEwMCUsIDUwJSkiIGQ9Ik0xMDYuMzcxIDE5NS4wMjJhNjYuNSA2Ni41IDAgMDAxLjU4MS43MjkiLz48cGF0aCBzdHJva2U9ImhzbCgzNTUsIDEwMCUsIDUwJSkiIGQ9Ik0xMDUuMzI4IDE5NC41MTNhNjYuNSA2Ni41IDAgMDAxLjU2OC43NTYiLz48cGF0aCBzdHJva2U9ImhzbCgzNTYsIDEwMCUsIDUwJSkiIGQ9Ik0xMDQuMjk0IDE5My45ODZhNjYuNSA2Ni41IDAgMDAxLjU1NC43ODQiLz48cGF0aCBzdHJva2U9ImhzbCgzNTcsIDEwMCUsIDUwJSkiIGQ9Ik0xMDMuMjY5IDE5My40NDFhNjYuNSA2Ni41IDAgMDAxLjU0LjgxIi8+PHBhdGggc3Ryb2tlPSJoc2woMzU4LCAxMDAlLCA1MCUpIiBkPSJNMTAyLjI1NCAxOTIuODc5YTY2LjUgNjYuNSAwIDAwMS41MjYuODM3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzU5LCAxMDAlLCA1MCUpIiBkPSJNMTAxLjI0OSAxOTIuMjk4YTY2LjUgNjYuNSAwIDAwMS41MTEuODY0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMCwgMTAwJSwgNTAlKSIgZD0iTTEwMC4yNTQgMTkxLjdhNjYuNSA2Ni41IDAgMDAxLjQ5Ni44OSIvPjxwYXRoIHN0cm9rZT0iaHNsKDEsIDEwMCUsIDUwJSkiIGQ9Ik05OS4yNyAxOTEuMDg2YTY2LjUgNjYuNSAwIDAwMS40OC45MTYiLz48cGF0aCBzdHJva2U9ImhzbCgyLCAxMDAlLCA1MCUpIiBkPSJNOTguMjk2IDE5MC40NTNhNjYuNSA2Ni41IDAgMDAxLjQ2NC45NDIiLz48cGF0aCBzdHJva2U9ImhzbCgzLCAxMDAlLCA1MCUpIiBkPSJNOTcuMzM0IDE4OS44MDRhNjYuNSA2Ni41IDAgMDAxLjQ0OC45NjgiLz48cGF0aCBzdHJva2U9ImhzbCg0LCAxMDAlLCA1MCUpIiBkPSJNOTYuMzgzIDE4OS4xMzlhNjYuNSA2Ni41IDAgMDAxLjQzLjk5MiIvPjxwYXRoIHN0cm9rZT0iaHNsKDUsIDEwMCUsIDUwJSkiIGQ9Ik05NS40NDQgMTg4LjQ1NmE2Ni41IDY2LjUgMCAwMDEuNDEzIDEuMDE4Ii8+PHBhdGggc3Ryb2tlPSJoc2woNiwgMTAwJSwgNTAlKSIgZD0iTTk0LjUxNyAxODcuNzU4YTY2LjUgNjYuNSAwIDAwMS4zOTUgMS4wNDIiLz48cGF0aCBzdHJva2U9ImhzbCg3LCAxMDAlLCA1MCUpIiBkPSJNOTMuNjAzIDE4Ny4wNDNhNjYuNSA2Ni41IDAgMDAxLjM3NiAxLjA2NiIvPjxwYXRoIHN0cm9rZT0iaHNsKDgsIDEwMCUsIDUwJSkiIGQ9Ik05Mi43IDE4Ni4zMTNhNjYuNSA2Ni41IDAgMDAxLjM1OSAxLjA5Ii8+PHBhdGggc3Ryb2tlPSJoc2woOSwgMTAwJSwgNTAlKSIgZD0iTTkxLjgxMiAxODUuNTY3YTY2LjUgNjYuNSAwIDAwMS4zMzggMS4xMTMiLz48cGF0aCBzdHJva2U9ImhzbCgxMCwgMTAwJSwgNTAlKSIgZD0iTTkwLjkzNiAxODQuODA2YTY2LjUgNjYuNSAwIDAwMS4zMTkgMS4xMzYiLz48cGF0aCBzdHJva2U9ImhzbCgxMSwgMTAwJSwgNTAlKSIgZD0iTTkwLjA3MyAxODQuMDI5YTY2LjUgNjYuNSAwIDAwMS4zIDEuMTYiLz48cGF0aCBzdHJva2U9ImhzbCgxMiwgMTAwJSwgNTAlKSIgZD0iTTg5LjIyNCAxODMuMjM3YTY2LjUgNjYuNSAwIDAwMS4yNzkgMS4xODIiLz48cGF0aCBzdHJva2U9ImhzbCgxMywgMTAwJSwgNTAlKSIgZD0iTTg4LjM5IDE4Mi40MzFhNjYuNSA2Ni41IDAgMDAxLjI1NyAxLjIwNCIvPjxwYXRoIHN0cm9rZT0iaHNsKDE0LCAxMDAlLCA1MCUpIiBkPSJNODcuNTY5IDE4MS42MWE2Ni41IDY2LjUgMCAwMDEuMjM2IDEuMjI2Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTUsIDEwMCUsIDUwJSkiIGQ9Ik04Ni43NjMgMTgwLjc3NmE2Ni41IDY2LjUgMCAwMDEuMjE0IDEuMjQ3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTYsIDEwMCUsIDUwJSkiIGQ9Ik04NS45NzEgMTc5LjkyN2E2Ni41IDY2LjUgMCAwMDEuMTkzIDEuMjY4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTcsIDEwMCUsIDUwJSkiIGQ9Ik04NS4xOTQgMTc5LjA2NGE2Ni41IDY2LjUgMCAwMDEuMTcxIDEuMjg5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTgsIDEwMCUsIDUwJSkiIGQ9Ik04NC40MzMgMTc4LjE4OGE2Ni41IDY2LjUgMCAwMDEuMTQ4IDEuMzEiLz48cGF0aCBzdHJva2U9ImhzbCgxOSwgMTAwJSwgNTAlKSIgZD0iTTgzLjY4NyAxNzcuM2E2Ni41IDY2LjUgMCAwMDEuMTI1IDEuMzI4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjAsIDEwMCUsIDUwJSkiIGQ9Ik04Mi45NTcgMTc2LjM5N2E2Ni41IDY2LjUgMCAwMDEuMTAxIDEuMzQ4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjEsIDEwMCUsIDUwJSkiIGQ9Ik04Mi4yNDIgMTc1LjQ4M2E2Ni41IDY2LjUgMCAwMDEuMDc4IDEuMzY3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjIsIDEwMCUsIDUwJSkiIGQ9Ik04MS41NDQgMTc0LjU1NmE2Ni41IDY2LjUgMCAwMDEuMDUzIDEuMzg1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjMsIDEwMCUsIDUwJSkiIGQ9Ik04MC44NjEgMTczLjYxN2E2Ni41IDY2LjUgMCAwMDEuMDMgMS40MDQiLz48cGF0aCBzdHJva2U9ImhzbCgyNCwgMTAwJSwgNTAlKSIgZD0iTTgwLjE5NiAxNzIuNjY2YTY2LjUgNjYuNSAwIDAwMS4wMDQgMS40MjIiLz48cGF0aCBzdHJva2U9ImhzbCgyNSwgMTAwJSwgNTAlKSIgZD0iTTc5LjU0NyAxNzEuNzA0YTY2LjUgNjYuNSAwIDAwLjk4IDEuNDM5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjYsIDEwMCUsIDUwJSkiIGQ9Ik03OC45MTQgMTcwLjczYTY2LjUgNjYuNSAwIDAwLjk1NSAxLjQ1NiIvPjxwYXRoIHN0cm9rZT0iaHNsKDI3LCAxMDAlLCA1MCUpIiBkPSJNNzguMyAxNjkuNzQ2YTY2LjUgNjYuNSAwIDAwLjkyOCAxLjQ3MiIvPjxwYXRoIHN0cm9rZT0iaHNsKDI4LCAxMDAlLCA1MCUpIiBkPSJNNzcuNzAyIDE2OC43NTFhNjYuNSA2Ni41IDAgMDAuOTAzIDEuNDg5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjksIDEwMCUsIDUwJSkiIGQ9Ik03Ny4xMjEgMTY3Ljc0NmE2Ni41IDY2LjUgMCAwMC44NzcgMS41MDQiLz48cGF0aCBzdHJva2U9ImhzbCgzMCwgMTAwJSwgNTAlKSIgZD0iTTc2LjU1OSAxNjYuNzMxYTY2LjUgNjYuNSAwIDAwLjg1IDEuNTE5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzEsIDEwMCUsIDUwJSkiIGQ9Ik03Ni4wMTQgMTY1LjcwNmE2Ni41IDY2LjUgMCAwMC44MjQgMS41MzQiLz48cGF0aCBzdHJva2U9ImhzbCgzMiwgMTAwJSwgNTAlKSIgZD0iTTc1LjQ4NyAxNjQuNjcyYTY2LjUgNjYuNSAwIDAwLjc5NyAxLjU0OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDMzLCAxMDAlLCA1MCUpIiBkPSJNNzQuOTc4IDE2My42MjlhNjYuNSA2Ni41IDAgMDAuNzcgMS41NjEiLz48cGF0aCBzdHJva2U9ImhzbCgzNCwgMTAwJSwgNTAlKSIgZD0iTTc0LjQ4OCAxNjIuNTc3YTY2LjUgNjYuNSAwIDAwLjc0MiAxLjU3NSIvPjxwYXRoIHN0cm9rZT0iaHNsKDM1LCAxMDAlLCA1MCUpIiBkPSJNNzQuMDE2IDE2MS41MTdhNjYuNSA2Ni41IDAgMDAuNzE1IDEuNTg3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzYsIDEwMCUsIDUwJSkiIGQ9Ik03My41NjIgMTYwLjQ0OGE2Ni41IDY2LjUgMCAwMC42ODcgMS42Ii8+PHBhdGggc3Ryb2tlPSJoc2woMzcsIDEwMCUsIDUwJSkiIGQ9Ik03My4xMjcgMTU5LjM3MmE2Ni41IDY2LjUgMCAwMC42NiAxLjYxMiIvPjxwYXRoIHN0cm9rZT0iaHNsKDM4LCAxMDAlLCA1MCUpIiBkPSJNNzIuNzExIDE1OC4yODlhNjYuNSA2Ni41IDAgMDAuNjMxIDEuNjIyIi8+PHBhdGggc3Ryb2tlPSJoc2woMzksIDEwMCUsIDUwJSkiIGQ9Ik03Mi4zMTQgMTU3LjE5OGE2Ni41IDY2LjUgMCAwMC42MDMgMS42MzMiLz48cGF0aCBzdHJva2U9ImhzbCg0MCwgMTAwJSwgNTAlKSIgZD0iTTcxLjkzNiAxNTYuMWE2Ni41IDY2LjUgMCAwMC41NzQgMS42NDQiLz48cGF0aCBzdHJva2U9ImhzbCg0MSwgMTAwJSwgNTAlKSIgZD0iTTcxLjU3OCAxNTQuOTk3YTY2LjUgNjYuNSAwIDAwLjU0NSAxLjY1MyIvPjxwYXRoIHN0cm9rZT0iaHNsKDQyLCAxMDAlLCA1MCUpIiBkPSJNNzEuMjM4IDE1My44ODdhNjYuNSA2Ni41IDAgMDAuNTE3IDEuNjYzIi8+PHBhdGggc3Ryb2tlPSJoc2woNDMsIDEwMCUsIDUwJSkiIGQ9Ik03MC45MTkgMTUyLjc3MWE2Ni41IDY2LjUgMCAwMC40ODcgMS42NzIiLz48cGF0aCBzdHJva2U9ImhzbCg0NCwgMTAwJSwgNTAlKSIgZD0iTTcwLjYxOCAxNTEuNjVhNjYuNSA2Ni41IDAgMDAuNDU4IDEuNjgiLz48cGF0aCBzdHJva2U9ImhzbCg0NSwgMTAwJSwgNTAlKSIgZD0iTTcwLjMzNyAxNTAuNTI0YTY2LjUgNjYuNSAwIDAwLjQyOSAxLjY4NyIvPjxwYXRoIHN0cm9rZT0iaHNsKDQ2LCAxMDAlLCA1MCUpIiBkPSJNNzAuMDc2IDE0OS4zOTNhNjYuNSA2Ni41IDAgMDAuNCAxLjY5NSIvPjxwYXRoIHN0cm9rZT0iaHNsKDQ3LCAxMDAlLCA1MCUpIiBkPSJNNjkuODM1IDE0OC4yNThhNjYuNSA2Ni41IDAgMDAuMzcgMS43MDEiLz48cGF0aCBzdHJva2U9ImhzbCg0OCwgMTAwJSwgNTAlKSIgZD0iTTY5LjYxNCAxNDcuMTE5YTY2LjUgNjYuNSAwIDAwLjM0IDEuNzA3Ii8+PHBhdGggc3Ryb2tlPSJoc2woNDksIDEwMCUsIDUwJSkiIGQ9Ik02OS40MTIgMTQ1Ljk3NmE2Ni41IDY2LjUgMCAwMC4zMSAxLjcxMyIvPjxwYXRoIHN0cm9rZT0iaHNsKDUwLCAxMDAlLCA1MCUpIiBkPSJNNjkuMjMgMTQ0LjgzYTY2LjUgNjYuNSAwIDAwLjI4IDEuNzE4Ii8+PHBhdGggc3Ryb2tlPSJoc2woNTEsIDEwMCUsIDUwJSkiIGQ9Ik02OS4wNjkgMTQzLjY4YTY2LjUgNjYuNSAwIDAwLjI1IDEuNzIzIi8+PHBhdGggc3Ryb2tlPSJoc2woNTIsIDEwMCUsIDUwJSkiIGQ9Ik02OC45MjcgMTQyLjUyOGE2Ni41IDY2LjUgMCAwMC4yMiAxLjcyNyIvPjxwYXRoIHN0cm9rZT0iaHNsKDUzLCAxMDAlLCA1MCUpIiBkPSJNNjguODA2IDE0MS4zNzRhNjYuNSA2Ni41IDAgMDAuMTkgMS43MyIvPjxwYXRoIHN0cm9rZT0iaHNsKDU0LCAxMDAlLCA1MCUpIiBkPSJNNjguNzA1IDE0MC4yMThhNjYuNSA2Ni41IDAgMDAuMTYgMS43MzMiLz48cGF0aCBzdHJva2U9ImhzbCg1NSwgMTAwJSwgNTAlKSIgZD0iTTY4LjYyNCAxMzkuMDZhNjYuNSA2Ni41IDAgMDAuMTMgMS43MzYiLz48cGF0aCBzdHJva2U9ImhzbCg1NiwgMTAwJSwgNTAlKSIgZD0iTTY4LjU2MyAxMzcuOWE2Ni41IDY2LjUgMCAwMC4wOTkgMS43MzkiLz48cGF0aCBzdHJva2U9ImhzbCg1NywgMTAwJSwgNTAlKSIgZD0iTTY4LjUyMyAxMzYuNzRhNjYuNSA2Ni41IDAgMDAuMDY4IDEuNzQiLz48cGF0aCBzdHJva2U9ImhzbCg1OCwgMTAwJSwgNTAlKSIgZD0iTTY4LjUwMyAxMzUuNThhNjYuNSA2Ni41IDAgMDAuMDM4IDEuNzQiLz48cGF0aCBzdHJva2U9ImhzbCg1OSwgMTAwJSwgNTAlKSIgZD0iTTY4LjUwMyAxMzQuNDJhNjYuNSA2Ni41IDAgMDAuMDA3IDEuNzQiLz48cGF0aCBzdHJva2U9ImhzbCg2MCwgMTAwJSwgNTAlKSIgZD0iTTY4LjUyMyAxMzMuMjZBNjYuNSA2Ni41IDAgMDA2OC41IDEzNSIvPjxwYXRoIHN0cm9rZT0iaHNsKDYxLCAxMDAlLCA1MCUpIiBkPSJNNjguNTYzIDEzMi4xYTY2LjUgNjYuNSAwIDAwLS4wNTMgMS43NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDYyLCAxMDAlLCA1MCUpIiBkPSJNNjguNjI0IDEzMC45NGE2Ni41IDY2LjUgMCAwMC0uMDgzIDEuNzQiLz48cGF0aCBzdHJva2U9ImhzbCg2MywgMTAwJSwgNTAlKSIgZD0iTTY4LjcwNSAxMjkuNzgyYTY2LjUgNjYuNSAwIDAwLS4xMTQgMS43MzgiLz48cGF0aCBzdHJva2U9ImhzbCg2NCwgMTAwJSwgNTAlKSIgZD0iTTY4LjgwNiAxMjguNjI2YTY2LjUgNjYuNSAwIDAwLS4xNDQgMS43MzUiLz48cGF0aCBzdHJva2U9ImhzbCg2NSwgMTAwJSwgNTAlKSIgZD0iTTY4LjkyNyAxMjcuNDcyYTY2LjUgNjYuNSAwIDAwLS4xNzQgMS43MzIiLz48cGF0aCBzdHJva2U9ImhzbCg2NiwgMTAwJSwgNTAlKSIgZD0iTTY5LjA2OSAxMjYuMzJhNjYuNSA2Ni41IDAgMDAtLjIwNSAxLjcyOSIvPjxwYXRoIHN0cm9rZT0iaHNsKDY3LCAxMDAlLCA1MCUpIiBkPSJNNjkuMjMgMTI1LjE3YTY2LjUgNjYuNSAwIDAwLS4yMzQgMS43MjYiLz48cGF0aCBzdHJva2U9ImhzbCg2OCwgMTAwJSwgNTAlKSIgZD0iTTY5LjQxMiAxMjQuMDI0YTY2LjUgNjYuNSAwIDAwLS4yNjUgMS43MjEiLz48cGF0aCBzdHJva2U9ImhzbCg2OSwgMTAwJSwgNTAlKSIgZD0iTTY5LjYxNCAxMjIuODgxYTY2LjUgNjYuNSAwIDAwLS4yOTUgMS43MTYiLz48cGF0aCBzdHJva2U9ImhzbCg3MCwgMTAwJSwgNTAlKSIgZD0iTTY5LjgzNSAxMjEuNzQyYTY2LjUgNjYuNSAwIDAwLS4zMjUgMS43MSIvPjxwYXRoIHN0cm9rZT0iaHNsKDcxLCAxMDAlLCA1MCUpIiBkPSJNNzAuMDc2IDEyMC42MDdhNjYuNSA2Ni41IDAgMDAtLjM1NCAxLjcwNCIvPjxwYXRoIHN0cm9rZT0iaHNsKDcyLCAxMDAlLCA1MCUpIiBkPSJNNzAuMzM3IDExOS40NzZhNjYuNSA2Ni41IDAgMDAtLjM4NCAxLjY5OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDczLCAxMDAlLCA1MCUpIiBkPSJNNzAuNjE4IDExOC4zNWE2Ni41IDY2LjUgMCAwMC0uNDE0IDEuNjkiLz48cGF0aCBzdHJva2U9ImhzbCg3NCwgMTAwJSwgNTAlKSIgZD0iTTcwLjkxOSAxMTcuMjI5YTY2LjUgNjYuNSAwIDAwLS40NDQgMS42ODMiLz48cGF0aCBzdHJva2U9ImhzbCg3NSwgMTAwJSwgNTAlKSIgZD0iTTcxLjIzOCAxMTYuMTEzYTY2LjUgNjYuNSAwIDAwLS40NzIgMS42NzYiLz48cGF0aCBzdHJva2U9ImhzbCg3NiwgMTAwJSwgNTAlKSIgZD0iTTcxLjU3OCAxMTUuMDAzYTY2LjUgNjYuNSAwIDAwLS41MDIgMS42NjciLz48cGF0aCBzdHJva2U9ImhzbCg3NywgMTAwJSwgNTAlKSIgZD0iTTcxLjkzNiAxMTMuOWE2Ni41IDY2LjUgMCAwMC0uNTMgMS42NTciLz48cGF0aCBzdHJva2U9ImhzbCg3OCwgMTAwJSwgNTAlKSIgZD0iTTcyLjMxNCAxMTIuODAyYTY2LjUgNjYuNSAwIDAwLS41NiAxLjY0OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDc5LCAxMDAlLCA1MCUpIiBkPSJNNzIuNzExIDExMS43MTFhNjYuNSA2Ni41IDAgMDAtLjU4OCAxLjYzOSIvPjxwYXRoIHN0cm9rZT0iaHNsKDgwLCAxMDAlLCA1MCUpIiBkPSJNNzMuMTI3IDExMC42MjhhNjYuNSA2Ni41IDAgMDAtLjYxNyAxLjYyOCIvPjxwYXRoIHN0cm9rZT0iaHNsKDgxLCAxMDAlLCA1MCUpIiBkPSJNNzMuNTYyIDEwOS41NTJhNjYuNSA2Ni41IDAgMDAtLjY0NSAxLjYxNyIvPjxwYXRoIHN0cm9rZT0iaHNsKDgyLCAxMDAlLCA1MCUpIiBkPSJNNzQuMDE2IDEwOC40ODNhNjYuNSA2Ni41IDAgMDAtLjY3NCAxLjYwNiIvPjxwYXRoIHN0cm9rZT0iaHNsKDgzLCAxMDAlLCA1MCUpIiBkPSJNNzQuNDg4IDEwNy40MjNhNjYuNSA2Ni41IDAgMDAtLjcwMiAxLjU5MyIvPjxwYXRoIHN0cm9rZT0iaHNsKDg0LCAxMDAlLCA1MCUpIiBkPSJNNzQuOTc4IDEwNi4zNzFhNjYuNSA2Ni41IDAgMDAtLjcyOSAxLjU4MSIvPjxwYXRoIHN0cm9rZT0iaHNsKDg1LCAxMDAlLCA1MCUpIiBkPSJNNzUuNDg3IDEwNS4zMjhhNjYuNSA2Ni41IDAgMDAtLjc1NiAxLjU2OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDg2LCAxMDAlLCA1MCUpIiBkPSJNNzYuMDE0IDEwNC4yOTRhNjYuNSA2Ni41IDAgMDAtLjc4NCAxLjU1NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDg3LCAxMDAlLCA1MCUpIiBkPSJNNzYuNTU5IDEwMy4yNjlhNjYuNSA2Ni41IDAgMDAtLjgxIDEuNTQiLz48cGF0aCBzdHJva2U9ImhzbCg4OCwgMTAwJSwgNTAlKSIgZD0iTTc3LjEyMSAxMDIuMjU0YTY2LjUgNjYuNSAwIDAwLS44MzcgMS41MjYiLz48cGF0aCBzdHJva2U9ImhzbCg4OSwgMTAwJSwgNTAlKSIgZD0iTTc3LjcwMiAxMDEuMjQ5YTY2LjUgNjYuNSAwIDAwLS44NjQgMS41MTEiLz48cGF0aCBzdHJva2U9ImhzbCg5MCwgMTAwJSwgNTAlKSIgZD0iTTc4LjMgMTAwLjI1NGE2Ni41IDY2LjUgMCAwMC0uODkgMS40OTYiLz48cGF0aCBzdHJva2U9ImhzbCg5MSwgMTAwJSwgNTAlKSIgZD0iTTc4LjkxNCA5OS4yN2E2Ni41IDY2LjUgMCAwMC0uOTE2IDEuNDgiLz48cGF0aCBzdHJva2U9ImhzbCg5MiwgMTAwJSwgNTAlKSIgZD0iTTc5LjU0NyA5OC4yOTZhNjYuNSA2Ni41IDAgMDAtLjk0MiAxLjQ2NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDkzLCAxMDAlLCA1MCUpIiBkPSJNODAuMTk2IDk3LjMzNGE2Ni41IDY2LjUgMCAwMC0uOTY4IDEuNDQ4Ii8+PHBhdGggc3Ryb2tlPSJoc2woOTQsIDEwMCUsIDUwJSkiIGQ9Ik04MC44NjEgOTYuMzgzYTY2LjUgNjYuNSAwIDAwLS45OTIgMS40MyIvPjxwYXRoIHN0cm9rZT0iaHNsKDk1LCAxMDAlLCA1MCUpIiBkPSJNODEuNTQ0IDk1LjQ0NGE2Ni41IDY2LjUgMCAwMC0xLjAxOCAxLjQxMyIvPjxwYXRoIHN0cm9rZT0iaHNsKDk2LCAxMDAlLCA1MCUpIiBkPSJNODIuMjQyIDk0LjUxN2E2Ni41IDY2LjUgMCAwMC0xLjA0MiAxLjM5NSIvPjxwYXRoIHN0cm9rZT0iaHNsKDk3LCAxMDAlLCA1MCUpIiBkPSJNODIuOTU3IDkzLjYwM2E2Ni41IDY2LjUgMCAwMC0xLjA2NiAxLjM3NiIvPjxwYXRoIHN0cm9rZT0iaHNsKDk4LCAxMDAlLCA1MCUpIiBkPSJNODMuNjg3IDkyLjdhNjYuNSA2Ni41IDAgMDAtMS4wOSAxLjM1OSIvPjxwYXRoIHN0cm9rZT0iaHNsKDk5LCAxMDAlLCA1MCUpIiBkPSJNODQuNDMzIDkxLjgxMmE2Ni41IDY2LjUgMCAwMC0xLjExMyAxLjMzOCIvPjxwYXRoIHN0cm9rZT0iaHNsKDEwMCwgMTAwJSwgNTAlKSIgZD0iTTg1LjE5NCA5MC45MzZhNjYuNSA2Ni41IDAgMDAtMS4xMzYgMS4zMTkiLz48cGF0aCBzdHJva2U9ImhzbCgxMDEsIDEwMCUsIDUwJSkiIGQ9Ik04NS45NzEgOTAuMDczYTY2LjUgNjYuNSAwIDAwLTEuMTYgMS4zIi8+PHBhdGggc3Ryb2tlPSJoc2woMTAyLCAxMDAlLCA1MCUpIiBkPSJNODYuNzYzIDg5LjIyNGE2Ni41IDY2LjUgMCAwMC0xLjE4MiAxLjI3OSIvPjxwYXRoIHN0cm9rZT0iaHNsKDEwMywgMTAwJSwgNTAlKSIgZD0iTTg3LjU2OSA4OC4zOWE2Ni41IDY2LjUgMCAwMC0xLjIwNCAxLjI1NyIvPjxwYXRoIHN0cm9rZT0iaHNsKDEwNCwgMTAwJSwgNTAlKSIgZD0iTTg4LjM5IDg3LjU2OWE2Ni41IDY2LjUgMCAwMC0xLjIyNiAxLjIzNiIvPjxwYXRoIHN0cm9rZT0iaHNsKDEwNSwgMTAwJSwgNTAlKSIgZD0iTTg5LjIyNCA4Ni43NjNhNjYuNSA2Ni41IDAgMDAtMS4yNDcgMS4yMTQiLz48cGF0aCBzdHJva2U9ImhzbCgxMDYsIDEwMCUsIDUwJSkiIGQ9Ik05MC4wNzMgODUuOTcxYTY2LjUgNjYuNSAwIDAwLTEuMjY4IDEuMTkzIi8+PHBhdGggc3Ryb2tlPSJoc2woMTA3LCAxMDAlLCA1MCUpIiBkPSJNOTAuOTM2IDg1LjE5NGE2Ni41IDY2LjUgMCAwMC0xLjI4OSAxLjE3MSIvPjxwYXRoIHN0cm9rZT0iaHNsKDEwOCwgMTAwJSwgNTAlKSIgZD0iTTkxLjgxMiA4NC40MzNhNjYuNSA2Ni41IDAgMDAtMS4zMSAxLjE0OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDEwOSwgMTAwJSwgNTAlKSIgZD0iTTkyLjcgODMuNjg3YTY2LjUgNjYuNSAwIDAwLTEuMzI4IDEuMTI1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTEwLCAxMDAlLCA1MCUpIiBkPSJNOTMuNjAzIDgyLjk1N2E2Ni41IDY2LjUgMCAwMC0xLjM0OCAxLjEwMSIvPjxwYXRoIHN0cm9rZT0iaHNsKDExMSwgMTAwJSwgNTAlKSIgZD0iTTk0LjUxNyA4Mi4yNDJhNjYuNSA2Ni41IDAgMDAtMS4zNjcgMS4wNzgiLz48cGF0aCBzdHJva2U9ImhzbCgxMTIsIDEwMCUsIDUwJSkiIGQ9Ik05NS40NDQgODEuNTQ0YTY2LjUgNjYuNSAwIDAwLTEuMzg1IDEuMDUzIi8+PHBhdGggc3Ryb2tlPSJoc2woMTEzLCAxMDAlLCA1MCUpIiBkPSJNOTYuMzgzIDgwLjg2MWE2Ni41IDY2LjUgMCAwMC0xLjQwNCAxLjAzIi8+PHBhdGggc3Ryb2tlPSJoc2woMTE0LCAxMDAlLCA1MCUpIiBkPSJNOTcuMzM0IDgwLjE5NmE2Ni41IDY2LjUgMCAwMC0xLjQyMiAxLjAwNCIvPjxwYXRoIHN0cm9rZT0iaHNsKDExNSwgMTAwJSwgNTAlKSIgZD0iTTk4LjI5NiA3OS41NDdhNjYuNSA2Ni41IDAgMDAtMS40MzkuOTgiLz48cGF0aCBzdHJva2U9ImhzbCgxMTYsIDEwMCUsIDUwJSkiIGQ9Ik05OS4yNyA3OC45MTRhNjYuNSA2Ni41IDAgMDAtMS40NTYuOTU1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTE3LCAxMDAlLCA1MCUpIiBkPSJNMTAwLjI1NCA3OC4zYTY2LjUgNjYuNSAwIDAwLTEuNDcyLjkyOCIvPjxwYXRoIHN0cm9rZT0iaHNsKDExOCwgMTAwJSwgNTAlKSIgZD0iTTEwMS4yNDkgNzcuNzAyYTY2LjUgNjYuNSAwIDAwLTEuNDg5LjkwMyIvPjxwYXRoIHN0cm9rZT0iaHNsKDExOSwgMTAwJSwgNTAlKSIgZD0iTTEwMi4yNTQgNzcuMTIxYTY2LjUgNjYuNSAwIDAwLTEuNTA0Ljg3NyIvPjxwYXRoIHN0cm9rZT0iaHNsKDEyMCwgMTAwJSwgNTAlKSIgZD0iTTEwMy4yNjkgNzYuNTU5YTY2LjUgNjYuNSAwIDAwLTEuNTE5Ljg1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTIxLCAxMDAlLCA1MCUpIiBkPSJNMTA0LjI5NCA3Ni4wMTRhNjYuNSA2Ni41IDAgMDAtMS41MzQuODI0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTIyLCAxMDAlLCA1MCUpIiBkPSJNMTA1LjMyOCA3NS40ODdhNjYuNSA2Ni41IDAgMDAtMS41NDguNzk3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTIzLCAxMDAlLCA1MCUpIiBkPSJNMTA2LjM3MSA3NC45NzhhNjYuNSA2Ni41IDAgMDAtMS41NjEuNzciLz48cGF0aCBzdHJva2U9ImhzbCgxMjQsIDEwMCUsIDUwJSkiIGQ9Ik0xMDcuNDIzIDc0LjQ4OGE2Ni41IDY2LjUgMCAwMC0xLjU3NS43NDIiLz48cGF0aCBzdHJva2U9ImhzbCgxMjUsIDEwMCUsIDUwJSkiIGQ9Ik0xMDguNDgzIDc0LjAxNmE2Ni41IDY2LjUgMCAwMC0xLjU4Ny43MTUiLz48cGF0aCBzdHJva2U9ImhzbCgxMjYsIDEwMCUsIDUwJSkiIGQ9Ik0xMDkuNTUyIDczLjU2MmE2Ni41IDY2LjUgMCAwMC0xLjYuNjg3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTI3LCAxMDAlLCA1MCUpIiBkPSJNMTEwLjYyOCA3My4xMjdhNjYuNSA2Ni41IDAgMDAtMS42MTIuNjYiLz48cGF0aCBzdHJva2U9ImhzbCgxMjgsIDEwMCUsIDUwJSkiIGQ9Ik0xMTEuNzExIDcyLjcxMWE2Ni41IDY2LjUgMCAwMC0xLjYyMi42MzEiLz48cGF0aCBzdHJva2U9ImhzbCgxMjksIDEwMCUsIDUwJSkiIGQ9Ik0xMTIuODAyIDcyLjMxNGE2Ni41IDY2LjUgMCAwMC0xLjYzMy42MDMiLz48cGF0aCBzdHJva2U9ImhzbCgxMzAsIDEwMCUsIDUwJSkiIGQ9Ik0xMTMuOSA3MS45MzZhNjYuNSA2Ni41IDAgMDAtMS42NDQuNTc0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTMxLCAxMDAlLCA1MCUpIiBkPSJNMTE1LjAwMyA3MS41NzhhNjYuNSA2Ni41IDAgMDAtMS42NTMuNTQ1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTMyLCAxMDAlLCA1MCUpIiBkPSJNMTE2LjExMyA3MS4yMzhhNjYuNSA2Ni41IDAgMDAtMS42NjMuNTE3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTMzLCAxMDAlLCA1MCUpIiBkPSJNMTE3LjIyOSA3MC45MTlhNjYuNSA2Ni41IDAgMDAtMS42NzIuNDg3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTM0LCAxMDAlLCA1MCUpIiBkPSJNMTE4LjM1IDcwLjYxOGE2Ni41IDY2LjUgMCAwMC0xLjY4LjQ1OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDEzNSwgMTAwJSwgNTAlKSIgZD0iTTExOS40NzYgNzAuMzM3YTY2LjUgNjYuNSAwIDAwLTEuNjg3LjQyOSIvPjxwYXRoIHN0cm9rZT0iaHNsKDEzNiwgMTAwJSwgNTAlKSIgZD0iTTEyMC42MDcgNzAuMDc2YTY2LjUgNjYuNSAwIDAwLTEuNjk1LjQiLz48cGF0aCBzdHJva2U9ImhzbCgxMzcsIDEwMCUsIDUwJSkiIGQ9Ik0xMjEuNzQyIDY5LjgzNWE2Ni41IDY2LjUgMCAwMC0xLjcwMS4zNyIvPjxwYXRoIHN0cm9rZT0iaHNsKDEzOCwgMTAwJSwgNTAlKSIgZD0iTTEyMi44ODEgNjkuNjE0YTY2LjUgNjYuNSAwIDAwLTEuNzA3LjM0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTM5LCAxMDAlLCA1MCUpIiBkPSJNMTI0LjAyNCA2OS40MTJhNjYuNSA2Ni41IDAgMDAtMS43MTMuMzEiLz48cGF0aCBzdHJva2U9ImhzbCgxNDAsIDEwMCUsIDUwJSkiIGQ9Ik0xMjUuMTcgNjkuMjNhNjYuNSA2Ni41IDAgMDAtMS43MTguMjgiLz48cGF0aCBzdHJva2U9ImhzbCgxNDEsIDEwMCUsIDUwJSkiIGQ9Ik0xMjYuMzIgNjkuMDY5YTY2LjUgNjYuNSAwIDAwLTEuNzIzLjI1Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTQyLCAxMDAlLCA1MCUpIiBkPSJNMTI3LjQ3MiA2OC45MjdhNjYuNSA2Ni41IDAgMDAtMS43MjcuMjIiLz48cGF0aCBzdHJva2U9ImhzbCgxNDMsIDEwMCUsIDUwJSkiIGQ9Ik0xMjguNjI2IDY4LjgwNmE2Ni41IDY2LjUgMCAwMC0xLjczLjE5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTQ0LCAxMDAlLCA1MCUpIiBkPSJNMTI5Ljc4MiA2OC43MDVhNjYuNSA2Ni41IDAgMDAtMS43MzMuMTYiLz48cGF0aCBzdHJva2U9ImhzbCgxNDUsIDEwMCUsIDUwJSkiIGQ9Ik0xMzAuOTQgNjguNjI0YTY2LjUgNjYuNSAwIDAwLTEuNzM2LjEzIi8+PHBhdGggc3Ryb2tlPSJoc2woMTQ2LCAxMDAlLCA1MCUpIiBkPSJNMTMyLjEgNjguNTYzYTY2LjUgNjYuNSAwIDAwLTEuNzM5LjA5OSIvPjxwYXRoIHN0cm9rZT0iaHNsKDE0NywgMTAwJSwgNTAlKSIgZD0iTTEzMy4yNiA2OC41MjNhNjYuNSA2Ni41IDAgMDAtMS43NC4wNjgiLz48cGF0aCBzdHJva2U9ImhzbCgxNDgsIDEwMCUsIDUwJSkiIGQ9Ik0xMzQuNDIgNjguNTAzYTY2LjUgNjYuNSAwIDAwLTEuNzQuMDM4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTQ5LCAxMDAlLCA1MCUpIiBkPSJNMTM1LjU4IDY4LjUwM2E2Ni41IDY2LjUgMCAwMC0xLjc0LjAwNyIvPjxwYXRoIHN0cm9rZT0iaHNsKDE1MCwgMTAwJSwgNTAlKSIgZD0iTTEzNi43NCA2OC41MjNBNjYuNSA2Ni41IDAgMDAxMzUgNjguNSIvPjxwYXRoIHN0cm9rZT0iaHNsKDE1MSwgMTAwJSwgNTAlKSIgZD0iTTEzNy45IDY4LjU2M2E2Ni41IDY2LjUgMCAwMC0xLjc0LS4wNTMiLz48cGF0aCBzdHJva2U9ImhzbCgxNTIsIDEwMCUsIDUwJSkiIGQ9Ik0xMzkuMDYgNjguNjI0YTY2LjUgNjYuNSAwIDAwLTEuNzQtLjA4MyIvPjxwYXRoIHN0cm9rZT0iaHNsKDE1MywgMTAwJSwgNTAlKSIgZD0iTTE0MC4yMTggNjguNzA1YTY2LjUgNjYuNSAwIDAwLTEuNzM4LS4xMTQiLz48cGF0aCBzdHJva2U9ImhzbCgxNTQsIDEwMCUsIDUwJSkiIGQ9Ik0xNDEuMzc0IDY4LjgwNmE2Ni41IDY2LjUgMCAwMC0xLjczNS0uMTQ0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTU1LCAxMDAlLCA1MCUpIiBkPSJNMTQyLjUyOCA2OC45MjdhNjYuNSA2Ni41IDAgMDAtMS43MzItLjE3NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDE1NiwgMTAwJSwgNTAlKSIgZD0iTTE0My42OCA2OS4wNjlhNjYuNSA2Ni41IDAgMDAtMS43MjktLjIwNSIvPjxwYXRoIHN0cm9rZT0iaHNsKDE1NywgMTAwJSwgNTAlKSIgZD0iTTE0NC44MyA2OS4yM2E2Ni41IDY2LjUgMCAwMC0xLjcyNi0uMjM0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTU4LCAxMDAlLCA1MCUpIiBkPSJNMTQ1Ljk3NiA2OS40MTJhNjYuNSA2Ni41IDAgMDAtMS43MjEtLjI2NSIvPjxwYXRoIHN0cm9rZT0iaHNsKDE1OSwgMTAwJSwgNTAlKSIgZD0iTTE0Ny4xMTkgNjkuNjE0YTY2LjUgNjYuNSAwIDAwLTEuNzE2LS4yOTUiLz48cGF0aCBzdHJva2U9ImhzbCgxNjAsIDEwMCUsIDUwJSkiIGQ9Ik0xNDguMjU4IDY5LjgzNWE2Ni41IDY2LjUgMCAwMC0xLjcxLS4zMjUiLz48cGF0aCBzdHJva2U9ImhzbCgxNjEsIDEwMCUsIDUwJSkiIGQ9Ik0xNDkuMzkzIDcwLjA3NmE2Ni41IDY2LjUgMCAwMC0xLjcwNC0uMzU0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTYyLCAxMDAlLCA1MCUpIiBkPSJNMTUwLjUyNCA3MC4zMzdhNjYuNSA2Ni41IDAgMDAtMS42OTgtLjM4NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDE2MywgMTAwJSwgNTAlKSIgZD0iTTE1MS42NSA3MC42MThhNjYuNSA2Ni41IDAgMDAtMS42OS0uNDE0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTY0LCAxMDAlLCA1MCUpIiBkPSJNMTUyLjc3MSA3MC45MTlhNjYuNSA2Ni41IDAgMDAtMS42ODMtLjQ0NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDE2NSwgMTAwJSwgNTAlKSIgZD0iTTE1My44ODcgNzEuMjM4YTY2LjUgNjYuNSAwIDAwLTEuNjc2LS40NzIiLz48cGF0aCBzdHJva2U9ImhzbCgxNjYsIDEwMCUsIDUwJSkiIGQ9Ik0xNTQuOTk3IDcxLjU3OGE2Ni41IDY2LjUgMCAwMC0xLjY2Ny0uNTAyIi8+PHBhdGggc3Ryb2tlPSJoc2woMTY3LCAxMDAlLCA1MCUpIiBkPSJNMTU2LjEgNzEuOTM2YTY2LjUgNjYuNSAwIDAwLTEuNjU3LS41MyIvPjxwYXRoIHN0cm9rZT0iaHNsKDE2OCwgMTAwJSwgNTAlKSIgZD0iTTE1Ny4xOTggNzIuMzE0YTY2LjUgNjYuNSAwIDAwLTEuNjQ4LS41NiIvPjxwYXRoIHN0cm9rZT0iaHNsKDE2OSwgMTAwJSwgNTAlKSIgZD0iTTE1OC4yODkgNzIuNzExYTY2LjUgNjYuNSAwIDAwLTEuNjM5LS41ODgiLz48cGF0aCBzdHJva2U9ImhzbCgxNzAsIDEwMCUsIDUwJSkiIGQ9Ik0xNTkuMzcyIDczLjEyN2E2Ni41IDY2LjUgMCAwMC0xLjYyOC0uNjE3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTcxLCAxMDAlLCA1MCUpIiBkPSJNMTYwLjQ0OCA3My41NjJhNjYuNSA2Ni41IDAgMDAtMS42MTctLjY0NSIvPjxwYXRoIHN0cm9rZT0iaHNsKDE3MiwgMTAwJSwgNTAlKSIgZD0iTTE2MS41MTcgNzQuMDE2YTY2LjUgNjYuNSAwIDAwLTEuNjA2LS42NzQiLz48cGF0aCBzdHJva2U9ImhzbCgxNzMsIDEwMCUsIDUwJSkiIGQ9Ik0xNjIuNTc3IDc0LjQ4OGE2Ni41IDY2LjUgMCAwMC0xLjU5My0uNzAyIi8+PHBhdGggc3Ryb2tlPSJoc2woMTc0LCAxMDAlLCA1MCUpIiBkPSJNMTYzLjYyOSA3NC45NzhhNjYuNSA2Ni41IDAgMDAtMS41ODEtLjcyOSIvPjxwYXRoIHN0cm9rZT0iaHNsKDE3NSwgMTAwJSwgNTAlKSIgZD0iTTE2NC42NzIgNzUuNDg3YTY2LjUgNjYuNSAwIDAwLTEuNTY4LS43NTYiLz48cGF0aCBzdHJva2U9ImhzbCgxNzYsIDEwMCUsIDUwJSkiIGQ9Ik0xNjUuNzA2IDc2LjAxNGE2Ni41IDY2LjUgMCAwMC0xLjU1NC0uNzg0Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTc3LCAxMDAlLCA1MCUpIiBkPSJNMTY2LjczMSA3Ni41NTlhNjYuNSA2Ni41IDAgMDAtMS41NC0uODEiLz48cGF0aCBzdHJva2U9ImhzbCgxNzgsIDEwMCUsIDUwJSkiIGQ9Ik0xNjcuNzQ2IDc3LjEyMWE2Ni41IDY2LjUgMCAwMC0xLjUyNi0uODM3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTc5LCAxMDAlLCA1MCUpIiBkPSJNMTY4Ljc1MSA3Ny43MDJhNjYuNSA2Ni41IDAgMDAtMS41MTEtLjg2NCIvPjxwYXRoIHN0cm9rZT0iaHNsKDE4MCwgMTAwJSwgNTAlKSIgZD0iTTE2OS43NDYgNzguM2E2Ni41IDY2LjUgMCAwMC0xLjQ5Ni0uODkiLz48cGF0aCBzdHJva2U9ImhzbCgxODEsIDEwMCUsIDUwJSkiIGQ9Ik0xNzAuNzMgNzguOTE0YTY2LjUgNjYuNSAwIDAwLTEuNDgtLjkxNiIvPjxwYXRoIHN0cm9rZT0iaHNsKDE4MiwgMTAwJSwgNTAlKSIgZD0iTTE3MS43MDQgNzkuNTQ3YTY2LjUgNjYuNSAwIDAwLTEuNDY0LS45NDIiLz48cGF0aCBzdHJva2U9ImhzbCgxODMsIDEwMCUsIDUwJSkiIGQ9Ik0xNzIuNjY2IDgwLjE5NmE2Ni41IDY2LjUgMCAwMC0xLjQ0OC0uOTY4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTg0LCAxMDAlLCA1MCUpIiBkPSJNMTczLjYxNyA4MC44NjFhNjYuNSA2Ni41IDAgMDAtMS40My0uOTkyIi8+PHBhdGggc3Ryb2tlPSJoc2woMTg1LCAxMDAlLCA1MCUpIiBkPSJNMTc0LjU1NiA4MS41NDRhNjYuNSA2Ni41IDAgMDAtMS40MTMtMS4wMTgiLz48cGF0aCBzdHJva2U9ImhzbCgxODYsIDEwMCUsIDUwJSkiIGQ9Ik0xNzUuNDgzIDgyLjI0MmE2Ni41IDY2LjUgMCAwMC0xLjM5NS0xLjA0MiIvPjxwYXRoIHN0cm9rZT0iaHNsKDE4NywgMTAwJSwgNTAlKSIgZD0iTTE3Ni4zOTcgODIuOTU3YTY2LjUgNjYuNSAwIDAwLTEuMzc2LTEuMDY2Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTg4LCAxMDAlLCA1MCUpIiBkPSJNMTc3LjMgODMuNjg3YTY2LjUgNjYuNSAwIDAwLTEuMzU5LTEuMDkiLz48cGF0aCBzdHJva2U9ImhzbCgxODksIDEwMCUsIDUwJSkiIGQ9Ik0xNzguMTg4IDg0LjQzM2E2Ni41IDY2LjUgMCAwMC0xLjMzOC0xLjExMyIvPjxwYXRoIHN0cm9rZT0iaHNsKDE5MCwgMTAwJSwgNTAlKSIgZD0iTTE3OS4wNjQgODUuMTk0YTY2LjUgNjYuNSAwIDAwLTEuMzE5LTEuMTM2Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTkxLCAxMDAlLCA1MCUpIiBkPSJNMTc5LjkyNyA4NS45NzFhNjYuNSA2Ni41IDAgMDAtMS4zLTEuMTYiLz48cGF0aCBzdHJva2U9ImhzbCgxOTIsIDEwMCUsIDUwJSkiIGQ9Ik0xODAuNzc2IDg2Ljc2M2E2Ni41IDY2LjUgMCAwMC0xLjI3OS0xLjE4MiIvPjxwYXRoIHN0cm9rZT0iaHNsKDE5MywgMTAwJSwgNTAlKSIgZD0iTTE4MS42MSA4Ny41NjlhNjYuNSA2Ni41IDAgMDAtMS4yNTctMS4yMDQiLz48cGF0aCBzdHJva2U9ImhzbCgxOTQsIDEwMCUsIDUwJSkiIGQ9Ik0xODIuNDMxIDg4LjM5YTY2LjUgNjYuNSAwIDAwLTEuMjM2LTEuMjI2Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTk1LCAxMDAlLCA1MCUpIiBkPSJNMTgzLjIzNyA4OS4yMjRhNjYuNSA2Ni41IDAgMDAtMS4yMTQtMS4yNDciLz48cGF0aCBzdHJva2U9ImhzbCgxOTYsIDEwMCUsIDUwJSkiIGQ9Ik0xODQuMDI5IDkwLjA3M2E2Ni41IDY2LjUgMCAwMC0xLjE5My0xLjI2OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDE5NywgMTAwJSwgNTAlKSIgZD0iTTE4NC44MDYgOTAuOTM2YTY2LjUgNjYuNSAwIDAwLTEuMTcxLTEuMjg5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMTk4LCAxMDAlLCA1MCUpIiBkPSJNMTg1LjU2NyA5MS44MTJhNjYuNSA2Ni41IDAgMDAtMS4xNDgtMS4zMSIvPjxwYXRoIHN0cm9rZT0iaHNsKDE5OSwgMTAwJSwgNTAlKSIgZD0iTTE4Ni4zMTMgOTIuN2E2Ni41IDY2LjUgMCAwMC0xLjEyNS0xLjMyOCIvPjxwYXRoIHN0cm9rZT0iaHNsKDIwMCwgMTAwJSwgNTAlKSIgZD0iTTE4Ny4wNDMgOTMuNjAzYTY2LjUgNjYuNSAwIDAwLTEuMTAxLTEuMzQ4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjAxLCAxMDAlLCA1MCUpIiBkPSJNMTg3Ljc1OCA5NC41MTdhNjYuNSA2Ni41IDAgMDAtMS4wNzgtMS4zNjciLz48cGF0aCBzdHJva2U9ImhzbCgyMDIsIDEwMCUsIDUwJSkiIGQ9Ik0xODguNDU2IDk1LjQ0NGE2Ni41IDY2LjUgMCAwMC0xLjA1My0xLjM4NSIvPjxwYXRoIHN0cm9rZT0iaHNsKDIwMywgMTAwJSwgNTAlKSIgZD0iTTE4OS4xMzkgOTYuMzgzYTY2LjUgNjYuNSAwIDAwLTEuMDMtMS40MDQiLz48cGF0aCBzdHJva2U9ImhzbCgyMDQsIDEwMCUsIDUwJSkiIGQ9Ik0xODkuODA0IDk3LjMzNGE2Ni41IDY2LjUgMCAwMC0xLjAwNC0xLjQyMiIvPjxwYXRoIHN0cm9rZT0iaHNsKDIwNSwgMTAwJSwgNTAlKSIgZD0iTTE5MC40NTMgOTguMjk2YTY2LjUgNjYuNSAwIDAwLS45OC0xLjQzOSIvPjxwYXRoIHN0cm9rZT0iaHNsKDIwNiwgMTAwJSwgNTAlKSIgZD0iTTE5MS4wODYgOTkuMjdhNjYuNSA2Ni41IDAgMDAtLjk1NS0xLjQ1NiIvPjxwYXRoIHN0cm9rZT0iaHNsKDIwNywgMTAwJSwgNTAlKSIgZD0iTTE5MS43IDEwMC4yNTRhNjYuNSA2Ni41IDAgMDAtLjkyOC0xLjQ3MiIvPjxwYXRoIHN0cm9rZT0iaHNsKDIwOCwgMTAwJSwgNTAlKSIgZD0iTTE5Mi4yOTggMTAxLjI0OWE2Ni41IDY2LjUgMCAwMC0uOTAzLTEuNDg5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjA5LCAxMDAlLCA1MCUpIiBkPSJNMTkyLjg3OSAxMDIuMjU0YTY2LjUgNjYuNSAwIDAwLS44NzctMS41MDQiLz48cGF0aCBzdHJva2U9ImhzbCgyMTAsIDEwMCUsIDUwJSkiIGQ9Ik0xOTMuNDQxIDEwMy4yNjlhNjYuNSA2Ni41IDAgMDAtLjg1LTEuNTE5Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjExLCAxMDAlLCA1MCUpIiBkPSJNMTkzLjk4NiAxMDQuMjk0YTY2LjUgNjYuNSAwIDAwLS44MjQtMS41MzQiLz48cGF0aCBzdHJva2U9ImhzbCgyMTIsIDEwMCUsIDUwJSkiIGQ9Ik0xOTQuNTEzIDEwNS4zMjhhNjYuNSA2Ni41IDAgMDAtLjc5Ny0xLjU0OCIvPjxwYXRoIHN0cm9rZT0iaHNsKDIxMywgMTAwJSwgNTAlKSIgZD0iTTE5NS4wMjIgMTA2LjM3MWE2Ni41IDY2LjUgMCAwMC0uNzctMS41NjEiLz48cGF0aCBzdHJva2U9ImhzbCgyMTQsIDEwMCUsIDUwJSkiIGQ9Ik0xOTUuNTEyIDEwNy40MjNhNjYuNSA2Ni41IDAgMDAtLjc0Mi0xLjU3NSIvPjxwYXRoIHN0cm9rZT0iaHNsKDIxNSwgMTAwJSwgNTAlKSIgZD0iTTE5NS45ODQgMTA4LjQ4M2E2Ni41IDY2LjUgMCAwMC0uNzE1LTEuNTg3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjE2LCAxMDAlLCA1MCUpIiBkPSJNMTk2LjQzOCAxMDkuNTUyYTY2LjUgNjYuNSAwIDAwLS42ODctMS42Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjE3LCAxMDAlLCA1MCUpIiBkPSJNMTk2Ljg3MyAxMTAuNjI4YTY2LjUgNjYuNSAwIDAwLS42Ni0xLjYxMiIvPjxwYXRoIHN0cm9rZT0iaHNsKDIxOCwgMTAwJSwgNTAlKSIgZD0iTTE5Ny4yODkgMTExLjcxMWE2Ni41IDY2LjUgMCAwMC0uNjMxLTEuNjIyIi8+PHBhdGggc3Ryb2tlPSJoc2woMjE5LCAxMDAlLCA1MCUpIiBkPSJNMTk3LjY4NiAxMTIuODAyYTY2LjUgNjYuNSAwIDAwLS42MDMtMS42MzMiLz48cGF0aCBzdHJva2U9ImhzbCgyMjAsIDEwMCUsIDUwJSkiIGQ9Ik0xOTguMDY0IDExMy45YTY2LjUgNjYuNSAwIDAwLS41NzQtMS42NDQiLz48cGF0aCBzdHJva2U9ImhzbCgyMjEsIDEwMCUsIDUwJSkiIGQ9Ik0xOTguNDIyIDExNS4wMDNhNjYuNSA2Ni41IDAgMDAtLjU0NS0xLjY1MyIvPjxwYXRoIHN0cm9rZT0iaHNsKDIyMiwgMTAwJSwgNTAlKSIgZD0iTTE5OC43NjIgMTE2LjExM2E2Ni41IDY2LjUgMCAwMC0uNTE3LTEuNjYzIi8+PHBhdGggc3Ryb2tlPSJoc2woMjIzLCAxMDAlLCA1MCUpIiBkPSJNMTk5LjA4MSAxMTcuMjI5YTY2LjUgNjYuNSAwIDAwLS40ODctMS42NzIiLz48cGF0aCBzdHJva2U9ImhzbCgyMjQsIDEwMCUsIDUwJSkiIGQ9Ik0xOTkuMzgyIDExOC4zNWE2Ni41IDY2LjUgMCAwMC0uNDU4LTEuNjgiLz48cGF0aCBzdHJva2U9ImhzbCgyMjUsIDEwMCUsIDUwJSkiIGQ9Ik0xOTkuNjYzIDExOS40NzZhNjYuNSA2Ni41IDAgMDAtLjQyOS0xLjY4NyIvPjxwYXRoIHN0cm9rZT0iaHNsKDIyNiwgMTAwJSwgNTAlKSIgZD0iTTE5OS45MjQgMTIwLjYwN2E2Ni41IDY2LjUgMCAwMC0uNC0xLjY5NSIvPjxwYXRoIHN0cm9rZT0iaHNsKDIyNywgMTAwJSwgNTAlKSIgZD0iTTIwMC4xNjUgMTIxLjc0MmE2Ni41IDY2LjUgMCAwMC0uMzctMS43MDEiLz48cGF0aCBzdHJva2U9ImhzbCgyMjgsIDEwMCUsIDUwJSkiIGQ9Ik0yMDAuMzg2IDEyMi44ODFhNjYuNSA2Ni41IDAgMDAtLjM0LTEuNzA3Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjI5LCAxMDAlLCA1MCUpIiBkPSJNMjAwLjU4OCAxMjQuMDI0YTY2LjUgNjYuNSAwIDAwLS4zMS0xLjcxMyIvPjxwYXRoIHN0cm9rZT0iaHNsKDIzMCwgMTAwJSwgNTAlKSIgZD0iTTIwMC43NyAxMjUuMTdhNjYuNSA2Ni41IDAgMDAtLjI4LTEuNzE4Ii8+PHBhdGggc3Ryb2tlPSJoc2woMjMxLCAxMDAlLCA1MCUpIiBkPSJNMjAwLjkzMSAxMjYuMzJhNjYuNSA2Ni41IDAgMDAtLjI1LTEuNzIzIi8+PHBhdGggc3Ryb2tlPSJoc2woMjMyLCAxMDAlLCA1MCUpIiBkPSJNMjAxLjA3MyAxMjcuNDcyYTY2LjUgNjYuNSAwIDAwLS4yMi0xLjcyNyIvPjxwYXRoIHN0cm9rZT0iaHNsKDIzMywgMTAwJSwgNTAlKSIgZD0iTTIwMS4xOTQgMTI4LjYyNmE2Ni41IDY2LjUgMCAwMC0uMTktMS43MyIvPjxwYXRoIHN0cm9rZT0iaHNsKDIzNCwgMTAwJSwgNTAlKSIgZD0iTTIwMS4yOTUgMTI5Ljc4MmE2Ni41IDY2LjUgMCAwMC0uMTYtMS43MzMiLz48cGF0aCBzdHJva2U9ImhzbCgyMzUsIDEwMCUsIDUwJSkiIGQ9Ik0yMDEuMzc2IDEzMC45NGE2Ni41IDY2LjUgMCAwMC0uMTMtMS43MzYiLz48cGF0aCBzdHJva2U9ImhzbCgyMzYsIDEwMCUsIDUwJSkiIGQ9Ik0yMDEuNDM3IDEzMi4xYTY2LjUgNjYuNSAwIDAwLS4wOTktMS43MzkiLz48cGF0aCBzdHJva2U9ImhzbCgyMzcsIDEwMCUsIDUwJSkiIGQ9Ik0yMDEuNDc3IDEzMy4yNmE2Ni41IDY2LjUgMCAwMC0uMDY4LTEuNzQiLz48cGF0aCBzdHJva2U9ImhzbCgyMzgsIDEwMCUsIDUwJSkiIGQ9Ik0yMDEuNDk3IDEzNC40MmE2Ni41IDY2LjUgMCAwMC0uMDM4LTEuNzQiLz48cGF0aCBzdHJva2U9ImhzbCgyMzksIDEwMCUsIDUwJSkiIGQ9Ik0yMDEuNDk3IDEzNS41OGE2Ni41IDY2LjUgMCAwMC0uMDA3LTEuNzQiLz48L2c+PGNpcmNsZSBjeD0iMTM1IiBjeT0iMTM1IiByPSIxMzMiIGZpbGw9InVybCgjYSkiIGNsYXNzPSJJcm9XaGVlbFNhdHVyYXRpb24iLz48Y2lyY2xlIGN4PSIxMzUiIGN5PSIxMzUiIHI9IjEzMyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjIiIGNsYXNzPSJJcm9XaGVlbEJvcmRlciIvPjwvc3ZnPg=='; +/*-------------------------------------------------------------- +# IMPORT +--------------------------------------------------------------*/ - dialog.querySelector('.satus-scrollbar__content').appendChild(close); - dialog.querySelector('.satus-scrollbar__content').appendChild(component_canvas); +Satus.storage.import = function(callback) { + chrome.storage.local.get(function(items) { + for (var key in items) { + Satus.storage[key] = items[key]; + } - document.body.appendChild(dialog); + if (callback) { + callback(); + } }); +}; - component.appendChild(component_value); - return component; -}; /*-------------------------------------------------------------- ->>> DIALOG +# CLEAR --------------------------------------------------------------*/ -Satus.components.dialog = function(element) { - var component = document.createElement('div'), - component_scrim = document.createElement('div'), - component_surface = document.createElement('div'), - component_scrollbar = Satus.components.scrollbar(component_surface), - options = element.options || {}; - - component_scrim.className = 'satus-dialog__scrim'; - component_surface.className = 'satus-dialog__surface'; - - for (var key in element) { - Satus.render(element[key], component_scrollbar); - } - - function close() { - window.removeEventListener('keydown', keydown); - - component.classList.add('satus-dialog--closing'); +Satus.storage.clear = function() { + chrome.storage.local.clear(); - if (typeof element.onclose === 'function') { - element.onclose(); + for (var key in Satus.storage) { + if (typeof Satus.storage[key] !== 'function') { + delete Satus.storage[key]; } - - setTimeout(function() { - component.remove(); - }, Satus.getAnimationDuration(component_surface)); } +}; + +/*----------------------------------------------------------------------------- +>>> «SEARCH» MODULE +-----------------------------------------------------------------------------*/ - function keydown(event) { - if (event.keyCode === 27) { - event.preventDefault(); - close(); - } - - if (event.keyCode === 9) { - var elements = component_surface.querySelectorAll('button, input'), - focused = false; - - event.preventDefault(); +Satus.search = function(query, object, callback, categories) { + var threads = 0, + folder = '', + results = {}; - for (var i = 0, l = elements.length; i < l; i++) { - if (elements[i] === document.activeElement && elements[i + 1]) { - elements[i + 1].focus(); + function parse(items) { + threads++; - focused = true; + for (var key in items) { + var item = items[key]; + + if (categories === true && item.type === 'folder' && folder !== item.label) { + folder = item.label; + } - i = l; + if (['switch', 'select', 'slider'].indexOf(item.type) !== -1 && key.indexOf(query) !== -1) { + if (categories === true) { + if (!results[folder]) { + results[folder] = {}; + } + + results[folder][key] = item; + } else { + results[key] = item; } } - if (focused === false) { - elements[0].focus(); + if (typeof item === 'object') { + parse(item); } } - } - component_scrim.addEventListener('click', close); - window.addEventListener('keydown', keydown); + threads--; - component.appendChild(component_scrim); - component.appendChild(component_surface); + if (threads === 0) { + callback(results); + } + } - // OPTIONS + parse(object); +}; + +/*-------------------------------------------------------------- +>>> RENDER +--------------------------------------------------------------*/ - if (options.left) { - component_surface.style.left = options.left + 'px'; +Satus.render = function(element, container, callback) { + function convert(object) { + if (object && object.type) { + var type = Satus.camelize(object.type), + component = Satus.components[type](object), + excluded_properties = ['type', 'label', 'class', 'title', 'storage']; + + function applyProperties(object, target) { + for (var key in object) { + if (Satus.isset(object[key]) && typeof object[key] === 'object' && !object[key].type) { + if (typeof target[key] !== 'object') { + target[key] = {}; + } + + applyProperties(object[key], target[key]); + } else if (excluded_properties.indexOf(key) === -1) { + target[key] = object[key]; + } + } + } + + applyProperties(object, component); + + component.skelet = object; + + component.classList.add('satus-' + object.type); + + if (object.class) { + var class_list = object.class.split(' '); + + for (var i = 0, l = class_list.length; i < l; i++) { + component.classList.add(class_list[i]); + } + } + + if (object.before) { + var component_before = document.createElement('span'); + + component_before.innerHTML = object.before; + + for (var i = component_before.children.length - 1; i > -1; i--) { + component.insertBefore(component_before.children[i], component.firstChild); + } + } + + if (object.after) { + var component_after = document.createElement('span'); + + component_after.innerHTML = object.after; + + for (var i = component_after.children.length - 1; i > -1; i--) { + component.appendChild(component_after.children[i]); + } + } + + (container || document.body).appendChild(component); + + if (typeof component.onClickRender === 'object') { + component.addEventListener('click', function() { + Satus.render(component.onClickRender); + }); + } + + if (Satus.isset(Satus.events.render)) { + for (var i = 0, l = Satus.events.render.length; i < l; i++) { + Satus.events.render[i](component, object); + } + } + + if (typeof component.onrender === 'function') { + component.onrender(object); + } + + if (callback) { + callback(); + } + } + } + + if (element.type) { + convert(element); + } else { + for (var key in element) { + convert(element[key]); + } + } +}; + +/*-------------------------------------------------------------- +>>> STORAGE KEYS +--------------------------------------------------------------*/ + +Satus.modules.updateStorageKeys = function(object, callback) { + var threads = 0; + + function parse(items) { + threads++; + + for (var key in items) { + var item = items[key]; + + + if (item.type) { + item.storage_key = key; + } + + if (typeof item === 'object') { + parse(item); + } + } + + threads--; + + if (threads === 0) { + callback(); + } } - if (options.top) { - component_surface.style.top = options.top + 'px'; - } + parse(object); +}; +Satus.components.table = function(item) { + var component = document.createElement('div'), + component_head = document.createElement('div'), + component_body = document.createElement('div'), + component_scrollbar = Satus.components.scrollbar(component_body, item.scrollbar), + table = document.createElement('div'); + + table.className = 'satus-table__container'; + component_head.className = 'satus-table__head'; + component_body.className = 'satus-table__body'; + + function update(data) { + var pages = Math.ceil(component.data.length / component.paging), + start = Math.max((component.pagingIndex - 1) * component.paging, 0), + end = component.pagingIndex * component.paging; + + if (end > data.length) { + end = data.length; + } else if (end === 0) { + end = component.paging; + } + + table.innerHTML = ''; + + if (data) { + for (var i = start, l = end; i < l; i++) { + if (data[i]) { + var tr = document.createElement('div'); + + tr.className = 'satus-table__row'; + + for (var j = 0, k = data[i].length; j < k; j++) { + var td = document.createElement('div'); + + + td.className = 'satus-table__cell'; + + if (data[i][j].html) { + td.innerHTML = data[i][j].html; + } else if (data[i][j].text) { + td.innerText = data[i][j].text; + } + + if (item.columns[j].onrender) { + td.onrender = item.columns[j].onrender; + + td.onrender(); + } + + tr.appendChild(td); + } + + table.appendChild(tr); + } + } + } + + component.pagingUpdate(); + } + + function sortArray(array, index, mode) { + if (mode === 'asc') { + if (typeof array[0][index].text === 'number') { + sorted = array.sort(function(a, b) { + return a[index].text - b[index].text; + }); + } else { + sorted = array.sort(function(a, b) { + return a[index].text.localeCompare(b[index].text); + }); + } + } else { + if (typeof array[0][index].text === 'number') { + sorted = array.sort(function(a, b) { + return b[index].text - a[index].text; + }); + } else { + sorted = array.sort(function(a, b) { + return b[index].text.localeCompare(a[index].text); + }); + } + } + + return array; + } + + function sort() { + var mode = this.dataset.sorting, + index = Array.prototype.indexOf.call(this.parentElement.children, this), + sorted; + + if (component.data[0][index] && component.data[0][index].hasOwnProperty('text')) { + if (mode === 'none') { + mode = 'asc'; + } else if (mode === 'asc') { + mode = 'desc'; + } else if (mode === 'desc') { + mode = 'asc'; + } + + if (this.parentNode.querySelector('div[data-sorting=asc], div[data-sorting=desc]')) { + this.parentNode.querySelector('div[data-sorting=asc], div[data-sorting=desc]').dataset.sorting = 'none'; + } + + this.dataset.sorting = mode; + + sorted = sortArray(component.data, index, mode); + + update(sorted); + } else { + this.dataset.sorting = false; + } + } + + function resize() {} + + for (var i = 0, l = item.columns.length; i < l; i++) { + var column = document.createElement('div'); + + column.dataset.sorting = 'none'; + column.addEventListener('click', sort); + column.innerHTML = '' + item.columns[i].title + ''; + + component_head.appendChild(column); + } + + component_scrollbar.appendChild(table); + + component.appendChild(component_head); + component.appendChild(component_body); + + component.data = item.data; + component.paging = item.paging; + component.pagingIndex = 0; + + component.update = function(data, index, mode) { + if (Satus.isset(data)) { + this.data = data; + } + + if (this.querySelector('div[data-sorting=asc], div[data-sorting=desc]')) { + var mode = this.querySelector('div[data-sorting=asc], div[data-sorting=desc]').dataset.sorting, + index = Array.prototype.indexOf.call(this.querySelector('div[data-sorting=asc], div[data-sorting=desc]').parentElement.children, this.querySelector('div[data-sorting=asc], div[data-sorting=desc]')); + + update(sortArray(this.data, index, mode)); + } else { + for (var i = 0, l = item.columns.length; i < l; i++) { + if (item.columns[i].hasOwnProperty('sorting')) { + if (this.data[0][i].hasOwnProperty('text')) { + this.querySelectorAll('.satus-table__head > div')[i].dataset.sorting = item.columns[i].sorting; + } else { + this.querySelectorAll('.satus-table__head > div')[i].dataset.sorting = false; + } + + update(sortArray(this.data, i, item.columns[i].sorting)); + + i = l; + } + } + } + }; + + + // PAGING + + function pagingUpdate() { + if (typeof this.paging === 'number') { + var pages = Math.ceil(this.data.length / this.paging); + + this.querySelector('.satus-table__paging').innerHTML = ''; + + for (var i = 1; i <= pages; i++) { + var button = document.createElement('button'); + + if (i === (this.pagingIndex || 1)) { + button.className = 'active'; + } + + button.innerText = i; + button.parentComponent = this; + button.addEventListener('click', function() { + if (this.parentNode.querySelector('button.active')) { + this.parentNode.querySelector('button.active').classList.remove('active'); + } + + this.classList.add('active'); + + this.parentComponent.pagingIndex = Number(this.innerText); + this.parentComponent.update(this.parentComponent.data); + }); + + this.querySelector('.satus-table__paging').appendChild(button); + } + } + + resize(); + } + + component.pagingUpdate = pagingUpdate; + + component_paging = document.createElement('div'); + + component_paging.className = 'satus-table__paging'; + + component_scrollbar.appendChild(component_paging); - if (options.width) { - component_surface.style.width = options.width + 'px'; + // END PAGING + + if (item.data) { + component.update(item.data); } + + return component; +}; + +/*-------------------------------------------------------------- +>>> HEADER +--------------------------------------------------------------*/ - if (options.height) { - component_surface.style.height = options.height + 'px'; - } +Satus.components.header = function(object) { + var component = document.createElement('header'); - // END OPTIONS + for (var key in object) { + Satus.render(object[key], component); + } return component; }; /*-------------------------------------------------------------- ->>> FOLDER +>>> SELECT --------------------------------------------------------------*/ -Satus.components.folder = function(object) { - var component = document.createElement('button'); - - component.object = object; +Satus.components.select = function(element) { + var component = document.createElement('button'), + component_label = document.createElement('span'), + component_value = document.createElement('span'), + label = Satus.locale.getMessage(element.label); component.classList.add('satus-button'); - component.addEventListener('click', function() { - var parent = document.querySelector(component.object.parent) || document.querySelector('.satus-main'); + component_label.className = 'satus-select__label'; + component_label.innerText = label; - if (!component.object.parent || !parent.classList.contains('satus-main')) { - while (!parent.classList.contains('satus-main')) { - parent = parent.parentNode; + component_value.className = 'satus-select__value'; + + if (element.storage_key) { + var value = Satus.storage.get(element.storage_key); + + component.dataset.storageKey = element.storage_key; + + for (var i = 0, l = element.options.length; i < l; i++) { + if (value === element.options[i].value) { + value = element.options[i].label; } } - parent.open(this.object, object.onopen); - }); + component_value.innerText = Satus.locale.getMessage(value || element.options[0].label); + } - if (Satus.isset(object.label)) { - var component_label = document.createElement('span'); + component.onclick = function() { + var position = this.getBoundingClientRect(), + dialog = { + type: 'dialog', + class: 'satus-dialog--select-component' + }; - component_label.className = 'satus-folder__label'; - component_label.innerText = Satus.locale.getMessage(object.label); + for (var key in element.options) { + dialog[key] = element.options[key]; - component.appendChild(component_label); - } + dialog[key].type = 'button'; + dialog[key].dataset = {}; + dialog[key].dataset.key = element.options[key].label; + dialog[key].dataset.value = element.options[key].value; + dialog[key].onclick = function() { + component_value.innerText = Satus.locale.getMessage(this.dataset.key); - return component; -}; -/*-------------------------------------------------------------- ->>> HEADER ---------------------------------------------------------------*/ + Satus.storage.set(component.dataset.storageKey, this.dataset.value); -Satus.components.header = function(object) { - var component = document.createElement('header'); + var parent = this.parentNode; - for (var key in object) { - Satus.render(object[key], component); - } + while (!parent.classList.contains('satus-dialog')) { + parent = parent.parentNode; + } + + parent.querySelector('.satus-dialog__scrim').click(); + }; + } + + Satus.render(dialog); + }; + + component.appendChild(component_label); + component.appendChild(component_value); return component; }; /*-------------------------------------------------------------- ->>> LIST +>>> SWITCH --------------------------------------------------------------*/ -Satus.components.list = function(object) { - var ul = document.createElement('ul'); +Satus.components.switch = function(element) { + var component = document.createElement('div'), + value; - if (object.compact === true) { - ul.classList.add('satus-list'); - ul.classList.add('satus-list--compact'); + // LABEL + if (Satus.isset(element.label)) { + var component_label = document.createElement('span'); + + component_label.className = 'satus-switch__label'; + component_label.innerText = Satus.locale.getMessage(element.label); + + component.appendChild(component_label); } - for (var key in object) { - if (Satus.isset(object[key].type)) { - var li = document.createElement('li'); - if (object.sortable === true) { - function mousedown(event) { - if (event.button === 0) { - var self = this, - dragging = false, - clone = false, - current_index = Array.from(self.parentNode.children).indexOf(self), - bounding = this.getBoundingClientRect(), - first_x = event.clientX, - first_y = event.clientY, - offset_x = event.clientX - bounding.left, - offset_y = event.clientY - bounding.top; + // INPUT + var component_input = document.createElement('input'); - function mousemove(event) { - if (Math.abs(first_y - event.clientY) <= 5) { - return false; - } - - if (dragging === false) { - clone = self.cloneNode(true); + component_input.type = 'checkbox'; + component_input.className = 'satus-switch__input'; - Satus.cloneNodeStyles(self, clone); - clone.style.position = 'fixed'; - clone.style.pointerEvents = 'none'; - clone.style.backgroundColor = '#fff'; - self.style.visibility = 'hidden'; + if (element.storage_key) { + value = Satus.storage.get(element.storage_key); - document.body.appendChild(clone); + component_input.dataset.storageKey = element.storage_key; + } - dragging = true; - } + if (!Satus.isset(value)) { + value = element.value; + } + + if (value) { + component_input.checked = value; + } + + component_input.addEventListener('change', function() { + Satus.storage.set(this.dataset.storageKey, this.checked); + }); + + component.appendChild(component_input); + + + // TRACK + var component_track = document.createElement('div'); + + component_track.className = 'satus-switch__track'; + + component.appendChild(component_track); + + + // MOUSE MOVE + component_track.addEventListener('mousedown', function(event) { + var prevent = false, + difference = 0; + + function click(event) { + event.preventDefault(); + event.stopPropagation(); + + component.removeEventListener('click', click); + + return false; + } + + function mousemove(event) { + var checkbox = component.querySelector('input'), + movement = event.movementX; + + if (movement * difference < 0) { + difference = 0; + } else { + difference += movement; + + if (prevent === false) { + prevent = true; + component.addEventListener('click', click); + } + } + + if (difference < -5) { + checkbox.checked = false; + } else if (difference > 5) { + checkbox.checked = true; + } + } + + function mouseup(event) { + window.removeEventListener('mousemove', mousemove); + window.removeEventListener('mouseup', mouseup); + } + + window.addEventListener('mousemove', mousemove); + window.addEventListener('mouseup', mouseup); + }); + + + // TOUCH MOVE + component_track.addEventListener('touchstart', function(event) { + var previous_x = 0, + difference = 0; + + function mousemove(event) { + var checkbox = component.querySelector('input'), + movement = event.touches[0].clientX - previous_x; + + previous_x = event.touches[0].clientX; + + if (movement * difference < 0) { + difference = 0; + } else { + difference += movement; + } + + if (difference < -5) { + checkbox.checked = false; + } else if (difference > 5) { + checkbox.checked = true; + } + } + + function mouseup(event) { + window.removeEventListener('touchmove', mousemove); + window.removeEventListener('touchend', mouseup); + } - var x = bounding.left, //event.clientX - offset_x - y = event.clientY - offset_y, - index = Math.floor(y / self.offsetHeight) - 1; + window.addEventListener('touchmove', mousemove); + window.addEventListener('touchend', mouseup); + }); - clone.style.left = x + 'px'; - clone.style.top = y + 'px'; - - //return false; - if (index !== current_index && self.parentNode.children[index]) { - var new_clone = self.cloneNode(true); + return component; +}; +/*-------------------------------------------------------------- +>>> TABS +--------------------------------------------------------------*/ - if (index > 0) { - self.parentNode.insertBefore(new_clone, self.parentNode.children[index].nextSibling); - } else { - self.parentNode.insertBefore(new_clone, self.parentNode.children[index]); - } +Satus.components.tabs = function(object) { + var component = document.createElement('div'), + tabbar = document.createElement('div'), + tabbar_select = document.createElement('div'), + main = document.createElement('div'), + i = 0; + + tabbar.className = 'satus-tabs__bar'; + main.className = 'satus-tabs__main'; + tabbar_select.className = 'satus-tabs__bar--select'; + + tabbar.appendChild(tabbar_select); + + function update() { + var index = Number(this.dataset.key); + + tabbar_select.style.left = this.offsetLeft + 'px'; + + if (this.parentNode.querySelector('.active')) { + var prev_index = Number(this.parentNode.querySelector('.active').dataset.key); + + this.parentNode.querySelector('.active').classList.remove('active'); + } + + this.classList.add('active'); + + var container = document.createElement('div'); + + container.className = 'satus-tabs__tab'; + + satus.render(this.menu, container); + + if (main.children.length >= 1) { + container.classList.add(index > prev_index ? 'satus-animation--fade-in-right' : 'satus-animation--fade-in-left'); + + main.children[0].classList.add('old'); + main.children[0].classList.add(index > prev_index ? 'satus-animation--fade-out-left' : 'satus-animation--fade-out-right'); + + main.appendChild(container); + + setTimeout(function() { + main.children[0].remove(); - self.remove(); + container.classList.remove(index > prev_index ? 'satus-animation--fade-in-right' : 'satus-animation--fade-in-left'); + }, 250); + } else { + main.appendChild(container); + } + } + + for (var key in object) { + if (object[key].type === 'tab') { + var tab = document.createElement('div'); - self = new_clone; + tab.innerText = satus.locale.getMessage(object[key].label); + tab.dataset.key = i; + tab.onclick = update; + tab.menu = Object.assign({}, object[key]); + + delete tab.menu.type; + + tabbar.appendChild(tab); + + i++; + } + } + + tabbar.children[1].click(); - self.addEventListener('mousedown', mousedown); + component.appendChild(tabbar); + component.appendChild(main); - if (typeof object.onchange === 'function') { - object.onchange(current_index, index); - } + return component; +}; + +/*-------------------------------------------------------------- +>>> FOLDER +--------------------------------------------------------------*/ - current_index = index; - } - } +Satus.components.folder = function(object) { + var component = document.createElement('button'); - function mouseup(event) { - if (clone) { - clone.remove(); - self.style.visibility = ''; - } + component.object = object; - window.removeEventListener('mousemove', mousemove); - window.removeEventListener('mouseup', mouseup); - } + component.classList.add('satus-button'); - window.addEventListener('mousemove', mousemove); - window.addEventListener('mouseup', mouseup); - } - } + component.addEventListener('click', function() { + var parent = document.querySelector(component.object.parent) || document.querySelector('.satus-main'); - li.addEventListener('mousedown', mousedown); + if (!component.object.parent || !parent.classList.contains('satus-main')) { + while (!parent.classList.contains('satus-main')) { + parent = parent.parentNode; } + } - Satus.render(object[key], li); + parent.open(this.object, object.onopen); + }); - ul.appendChild(li); - } + if (Satus.isset(object.label)) { + var component_label = document.createElement('span'); + + component_label.className = 'satus-folder__label'; + component_label.innerText = Satus.locale.getMessage(object.label); + + component.appendChild(component_label); } - return ul; -}; - + return component; +}; +/*-------------------------------------------------------------- +>>> TEXT FIELD +--------------------------------------------------------------*/ + +Satus.components.textField = function(element) { + var component = element.rows > 1 ? document.createElement('textarea') : document.createElement('input'); + + component.type = 'text'; + + return component; +}; /*-------------------------------------------------------------- >>> MAIN --------------------------------------------------------------*/ @@ -1165,8 +1379,8 @@ Satus.components.main = function(object) { component_container = document.createElement('div'), component_scrollbar = Satus.components.scrollbar(component_container); - container.classList.add('satus-main__container--fade-out-right'); - component_container.className = 'satus-main__container satus-main__container--fade-in-left'; + container.classList.add('satus-animation--fade-out-right'); + component_container.className = 'satus-main__container satus-animation--fade-in-left'; this.history.pop(); @@ -1185,6 +1399,11 @@ Satus.components.main = function(object) { component_scrollbar.onopen(); } + + var id = this.history[this.history.length - 1].appearanceKey; + + document.body.dataset.appearance = id; + this.dataset.appearance = id; setTimeout(function() { container.remove(); @@ -1197,8 +1416,8 @@ Satus.components.main = function(object) { component_scrollbar = Satus.components.scrollbar(component_container); if (animated !== false) { - container.classList.add('satus-main__container--fade-out-left'); - component_container.className = 'satus-main__container satus-main__container--fade-in-right'; + container.classList.add('satus-animation--fade-out-left'); + component_container.className = 'satus-main__container satus-animation--fade-in-right'; } else { component_container.className = 'satus-main__container'; } @@ -1215,32 +1434,175 @@ Satus.components.main = function(object) { this.historyListener(component_container); } - if (callback) { - component_scrollbar.onopen = callback; + if (callback) { + component_scrollbar.onopen = callback; + + component_scrollbar.onopen(); + } + + var id = this.history[this.history.length - 1].appearanceKey; + + document.body.dataset.appearance = id; + this.dataset.appearance = id; + + setTimeout(function() { + container.remove(); + }, Satus.getAnimationDuration(container)); + }; + + component_container.className = 'satus-main__container'; + + if (object.on && object.on.change) { + component.historyListener = object.on.change; + } + + if (component.historyListener) { + component.historyListener(component_container); + } + + for (var key in object) { + Satus.render(object[key], component_scrollbar); + } + + component.appendChild(component_container); + + return component; +}; + +/*-------------------------------------------------------------- +>>> SLIDER +--------------------------------------------------------------*/ + +Satus.components.slider = function(element) { + var component = document.createElement('div'); + + // LABEL + if (Satus.isset(element.label)) { + var component_label = document.createElement('span'); + + component_label.className = 'satus-slider__label'; + component_label.innerText = Satus.locale.getMessage(element.label); + + component.appendChild(component_label); + } + + + // RANGE + var component_range = document.createElement('input'); + + component_range.type = 'range'; + component_range.className = 'satus-slider__range'; + component_range.min = element.min || 0; + component_range.max = element.max || 10; + component_range.step = element.step || 1; + + component_range.oninput = function() { + var track = this.parentNode.querySelector('.satus-slider__track'), + thumb = this.parentNode.querySelector('.satus-slider__thumb'), + min = Number(this.min) || 0, + max = Number(this.max) || 1, + step = Number(this.step) || 1, + value = Number(this.value) || 0, + offset = (value - min) / (max - min) * 100; + + track.style.width = 'calc(' + offset + '% - ' + Math.floor(offset * 12 / 100) + 'px)'; + + Satus.storage.set(this.dataset.storageKey, Number(this.value)); + + component_thumb.dataset.value = this.value; + + if (component.onchange) { + component.onchange(Number(this.value)); + } + }; + + component.change = function(value) { + component_range.value = value; + + component_thumb.dataset.value = value; + + component_range.oninput(); + }; + + component.addEventListener('mousedown', function() { + function mousemove() { + component.classList.add('satus-slider--dragging'); + } + + function mouseup() { + component.classList.remove('satus-slider--dragging'); + + window.removeEventListener('mousemove', mousemove); + window.removeEventListener('mouseup', mouseup); + } + + window.addEventListener('mousemove', mousemove); + window.addEventListener('mouseup', mouseup); + }); + + if (element.onchange) { + component.onchange = element.onchange; + } + + component.appendChild(component_range); + + + // CONTAINER + var component_container = document.createElement('div'); + + component_container.className = 'satus-slider__container'; + + component.appendChild(component_container); + + + // TRACK + var component_track_container = document.createElement('div'), + component_track = document.createElement('div'); + + component_track_container.className = 'satus-slider__track-container'; + component_track.className = 'satus-slider__track'; + + component_track_container.appendChild(component_track); + component_container.appendChild(component_track_container); + + + // FOCUS RING + var component_ring = document.createElement('div'); + + component_ring.className = 'satus-slider__ring'; + + component_track.appendChild(component_ring); + + + // THUMB + var component_thumb = document.createElement('div'); + + component_thumb.className = 'satus-slider__thumb'; - component_scrollbar.onopen(); - } + component_track.appendChild(component_thumb); - setTimeout(function() { - container.remove(); - }, Satus.getAnimationDuration(container)); - }; + if (element.storage_key) { + var value = Satus.storage.get(element.storage_key) || element.value; - component_container.className = 'satus-main__container'; + component_range.dataset.storageKey = element.storage_key; - if (object.on && object.on.change) { - component.historyListener = object.on.change; - } + if (value) { + component_range.value = value; - if (component.historyListener) { - component.historyListener(component_container); - } + if (!Satus.isset(value)) { + value = element.value; + } - for (var key in object) { - Satus.render(object[key], component_scrollbar); + var offset = (Number(component_range.value) - Number(component_range.min)) / (Number(component_range.max) - Number(component_range.min)) * 100; + + component_track.style.width = 'calc(' + offset + '% - ' + Math.floor(offset * 12 / 100) + 'px)'; + component_thumb.dataset.value = value; + } else { + component_range.value = 0; + component_thumb.dataset.value = 0; + } } - component.appendChild(component_container); return component; }; @@ -1350,813 +1712,624 @@ Satus.components.scrollbar = function(parent, enabled) { return component_content; }; /*-------------------------------------------------------------- ->>> SECTION +>>> DIV --------------------------------------------------------------*/ -Satus.components.section = function(element) { - var component = document.createElement('section'); +Satus.components.div = function(object) { + var component = document.createElement('div'); - for (var key in element) { - Satus.render(element[key], component); + for (var key in object) { + Satus.render(object[key], component); } return component; }; /*-------------------------------------------------------------- ->>> SELECT +>>> LIST --------------------------------------------------------------*/ -Satus.components.select = function(element) { - var component = document.createElement('button'), - component_label = document.createElement('span'), - component_value = document.createElement('span'), - label = Satus.locale.getMessage(element.label); - - component.classList.add('satus-button'); - - component_label.className = 'satus-select__label'; - component_label.innerText = label; - - component_value.className = 'satus-select__value'; - - if (element.storage_key) { - var value = Satus.storage.get(element.storage_key); - - component.dataset.storageKey = element.storage_key; - - for (var i = 0, l = element.options.length; i < l; i++) { - if (value === element.options[i].value) { - value = element.options[i].label; - } - } - - component_value.innerText = Satus.locale.getMessage(value || element.options[0].label); - } - - component.onclick = function() { - var position = this.getBoundingClientRect(), - dialog = { - type: 'dialog', - class: 'satus-dialog--select-component' - }; - - for (var key in element.options) { - dialog[key] = element.options[key]; - - dialog[key].type = 'button'; - dialog[key].dataset = {}; - dialog[key].dataset.key = element.options[key].label; - dialog[key].dataset.value = element.options[key].value; - dialog[key].onclick = function() { - component_value.innerText = Satus.locale.getMessage(this.dataset.key); - - Satus.storage.set(component.dataset.storageKey, this.dataset.value); - - var parent = this.parentNode; - - while (!parent.classList.contains('satus-dialog')) { - parent = parent.parentNode; - } - - parent.querySelector('.satus-dialog__scrim').click(); - }; - } - - Satus.render(dialog); - }; - - component.appendChild(component_label); - component.appendChild(component_value); - - return component; -}; -/*------------------------------------------------------------------------------ ->>> SHORTCUT -------------------------------------------------------------------------------*/ - -Satus.components.shortcut = function(element) { - var self = this, - value = (Satus.storage.get(element.storage_key) ? JSON.parse(Satus.storage.get(element.storage_key)) : false) || element.value || {}, - component = document.createElement('div'), - component_label = document.createElement('span'), - component_value = document.createElement('span'), - mousewheel_timeout = false, - mousewheel_only = false; - - component_label.className = 'satus-shortcut__label'; - component_value.className = 'satus-shortcut__value'; - - function update(canvas) { - let text_value = [], - keys_value = []; - - if (value.altKey === true) { - text_value.push('Alt'); - keys_value.push('