├── README.md ├── UPDATED-todo.md ├── background.js ├── dupl.png ├── fontawesome.css ├── fontawesome.js ├── foreground.js ├── icon.png ├── ideas.md ├── index.html ├── jquery.min.js ├── manifest.json ├── marked.min.js ├── messages-plan.md ├── notification.mp3 ├── options.html ├── popup.html ├── repldm-page.css ├── sanitize-html.js └── socket.io.js /README.md: -------------------------------------------------------------------------------- 1 | [repldm](https://chrome.google.com/webstore/detail/repldm/keafnbglbpeinfldadjibfibkaklhceg) - bringing direct messaging to replit 2 | ============================================ 3 | 4 | ***This project was made by the @dupl team - @rafrafraf and @MarcusWeinberger (me)*** 5 | 6 | [![webstore](https://storage.googleapis.com/chrome-gcs-uploader.appspot.com/image/WlD8wC6g8khYWPJUsQceQkhXSlv1/UV4C4ybeBTsZt43U4xis.png)](https://chrome.google.com/webstore/detail/repldm/keafnbglbpeinfldadjibfibkaklhceg) 7 | 8 | ## What is repldm? 9 | 10 | ReplDM is a chrome extension that injects javascript into replit in order to add direct messaging capabilities. Message any user on replit! 11 | 12 | [![demo](https://i.imgur.com/2JTpahS.gif)](https://i.imgur.com/2JTpahS.gif) 13 | 14 | # ***Need help getting set up? [Follow the tutorial here](https://notes.marcusj.tech/link/repldm)*** - and sorry about the bugs 15 | 16 | To install unpublished updates and stay cutting edge, [**follow this guide to install the developer release**](https://www.cnet.com/how-to/how-to-install-chrome-extensions-manually/) - you'll need to download the zip file [from here (source)](https://github.com/AgeOfMarcus/repl-dm-chrome/archive/master.zip). 17 | 18 | ## [GitHub repo](https://github.com/AgeOfMarcus/repl-dm-chrome) - For issues and more 19 | 20 | Additional thanks goes to @firefish, @19wintersp, and @ch1ck3n for contributing to the project! 21 | 22 | --- 23 | 24 | # Coming soon 25 | 26 | * privacy features 27 | - block users 28 | - mute conversations 29 | - toggle markdown rendering 30 | 31 | -------------------------------------------------------------------------------- /UPDATED-todo.md: -------------------------------------------------------------------------------- 1 | # TODO: 2 | 3 | * fix messages order bug when opening chat 4 | 5 | * make the scroll to top to load earlier messages actually work 6 | 7 | * (optional) show user online status 8 | 9 | * improve loading speed any way possible (for chats and messages) 10 | 11 | 12 | ***once all of the above is completed, we can release repldm V1.*** -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | // execute script as soon as extension is installed or refreshed 2 | 3 | chrome.tabs.onActivated.addListener(tab => { 4 | addScripts(tab); 5 | }) 6 | 7 | function addScripts(tab) { 8 | chrome.tabs.get(tab.tabId, currentTabInfo => { 9 | if (/^https:\/\/repl\.it/.test(currentTabInfo.url)) { 10 | chrome.tabs.insertCSS(null, {file: './repldm-page.css'}); 11 | chrome.tabs.executeScript(null, {file: './jquery.min.js'}, () => { 12 | chrome.tabs.executeScript(null, {file: './sanitize-html.js'}, () => { 13 | chrome.tabs.executeScript(null, {file: './marked.min.js'}, () => { 14 | chrome.tabs.executeScript(null, {file: './foreground.js'}, () => { console.log('i injected') }) 15 | }) 16 | }) 17 | }) 18 | } 19 | }) 20 | } 21 | 22 | chrome.runtime.onMessage.addListener( 23 | () => { 24 | document.getElementById('notif-sound').play(); 25 | } 26 | ); -------------------------------------------------------------------------------- /dupl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgeOfMarcus/repl-dm-chrome/4c01ff70e328125f0772b1b327ee739da15fa8c3/dupl.png -------------------------------------------------------------------------------- /fontawesome.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | .fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hive:before{content:"\e07f"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-innosoft:before{content:"\e080"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-perbyte:before{content:"\e083"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-uncharted:before{content:"\e084"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-watchman-monitoring:before{content:"\e087"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} -------------------------------------------------------------------------------- /foreground.js: -------------------------------------------------------------------------------- 1 | var _first_load = true; 2 | 3 | const socket = io("https://repldm.dupl.repl.co"); 4 | 5 | var version = chrome.runtime.getManifest().version; 6 | 7 | // READ ME or ur gay lol 8 | 9 | // to set notification badge all u gotta do is $('repldmBtn').attr('notifications', "[insert number here]") 10 | // if the notifications attribute doesnt exist, or has no value or the value of 0, the badge auto hides so dw about hiding it, and the attribute value auto sets the badge value too so its super easy. 11 | // also, i think the number it shows should be the number of unread chats, not the number of unread messages. so if you and some other guy sent me a few msgs, it would show 2 for 2 unread chats. 12 | 13 | // showing users online: just add class "online" to the node lol 14 | 15 | 16 | // new messages icons: to set status, give the .mid (child of .node) the attr called status - values are sent, received, read & opened 17 | 18 | socket.on('new message', (res) => { 19 | let msg = res.message; 20 | socket.emit('recv', {auth: authToken, token: res.token}); 21 | 22 | if (msg.from in _msg_cache) { 23 | _msg_cache[msg.from].push(msg); 24 | _msg_cache[msg.from] = _msg_cache[msg.from].slice().sort((a, b) => { (a.time < b.time) ? 1 : -1 }); 25 | } else { 26 | _msg_cache[msg.from] = [msg]; 27 | } 28 | 29 | if ($('.chat .top span').text() == msg.from) { 30 | if (document.getElementById(`msg-${msg.id}`)) { 31 | return; 32 | } 33 | 34 | $('.chat .box').append($(` 35 |
36 | ${renderText(msg.body)} 37 | 38 |
39 | `)) 40 | 41 | var box = $('.chat .box'); // scroll to bottom of chat 42 | box.scrollTop(box.prop('scrollHeight')); 43 | } else { 44 | if (_notify_perm && _settings.notifications) { 45 | getProfilePicture(msg.from, (src) => { 46 | var notif = new Notification(`${msg.from} sent you a message`, { 47 | body: msg.body, 48 | icon: src, 49 | silent: true 50 | }); 51 | 52 | if (_settings.sound) { 53 | // sound effect 54 | chrome.runtime.sendMessage( 55 | "play sound" 56 | ); 57 | } 58 | }) 59 | } 60 | } 61 | }) 62 | 63 | socket.on('show mark read', (res) => { 64 | let msg = res.message; 65 | socket.emit('recv', {auth: authToken, token: res.token}); 66 | $('.read').removeClass('read'); 67 | $(`#msg-${msg.id}`).addClass('read'); 68 | 69 | var box = $('.chat .box'); // scroll to bottom of chat 70 | box.scrollTop(box.prop('scrollHeight')); 71 | }) 72 | 73 | var _msg_node_increment = 0; 74 | var _msg_cache = {}; 75 | 76 | function getMessages(user, callback, older_than=null, newer_than=null, limit=null) { 77 | // returns a list of messages 78 | data = { 79 | auth: authToken, 80 | user: user 81 | } 82 | if (older_than) data['older_than'] = older_than; 83 | if (limit) data['limit'] = limit; 84 | if (newer_than) data['newer_than'] = newer_than; 85 | 86 | socket.emit('get messages', data, (r) => { callback(r.result) }) 87 | } 88 | 89 | function sendMessage(to, body, callback) { 90 | /* 91 | socket returns a message object, which by default is passed to the 92 | parseMessage function and added to the html 93 | */ 94 | socket.emit('send message', { 95 | auth: authToken, // global object set on auth 96 | to: to, 97 | body: body 98 | }, (r) => { callback(r.result) }) 99 | } 100 | 101 | function getProfilePicture(user, callback) { 102 | // returns URL or default pfp if user not found 103 | socket.emit('pfp', { 104 | auth: authToken, 105 | username: user 106 | }, (r) => { callback(r.result) }) 107 | } 108 | 109 | function listUnread(callback) { 110 | // returns dict {username: unreadMessages[int]} 111 | socket.emit('get unread', { 112 | auth: authToken 113 | }, (r) => { callback(r.result) }) 114 | } 115 | 116 | function markRead(ids, callback, read=true) { 117 | // returns list of ids which the operation was successful 118 | socket.emit('mark read', { 119 | auth: authToken, 120 | ids: ids, 121 | read: read 122 | }, (r) => { callback(r.result) }) 123 | } 124 | 125 | function getConvos(callback) { 126 | socket.emit('get conversations', {auth: authToken}, (r) => { callback(r.result) }) 127 | } 128 | 129 | 130 | // sorts chat into order 131 | function sort_dict(dict) { 132 | // Create items array 133 | var items = Object.keys(dict).map(function(key) { 134 | return [key, dict[key]]; 135 | }); 136 | 137 | // Sort the array based on the second element 138 | items.sort(function(first, second) { 139 | return second[1].time - first[1].time; 140 | }); 141 | return items; 142 | } 143 | 144 | // loads img src for pfps after theyve been put in 145 | function load_pfps() { 146 | console.log('loading pfps') 147 | for (i=0; i<$('.node').length; i++) { 148 | const ele = $(`.node[for="msg-${i}"]`); 149 | const user = ele.find('.name').text(); 150 | const img = ele.find('.pfp').find('img'); 151 | getProfilePicture(user, (pfp) => { 152 | img.attr('src', pfp); 153 | }) 154 | } 155 | } 156 | 157 | // adds functionality to open chats 158 | function addMsgEventListeners() { 159 | $('.node-radio').each( () => { 160 | $(this).bind('change', (event) => { 161 | document.querySelector('.right .no-msg').style.display = 'none'; 162 | var ele = $(`label[for=${event.target.id}]`); 163 | loadConvo(ele.find('div .name').text()); // loadConvo(username) 164 | }) 165 | }) 166 | } 167 | 168 | function init() { 169 | listUnread((unread) => { 170 | $('repldmBtn').attr('notifications', `${Object.keys(unread).length}`); 171 | getConvos((users) => { 172 | var html = ''; 173 | const sorted_users = sort_dict(users); // ------- my new method which makes messages sorted ;) 174 | if (sorted_users.length == 0) { 175 | $('.loading-msgs').hide(); 176 | } 177 | for (var i=0; i 199 | 213 | `; 214 | 215 | if (i == 0) { 216 | $('.loading-msgs').hide(); 217 | } 218 | else if (i >= sorted_users.length-1) { // last iteration 219 | $('.left-msgs').html(html); 220 | addMsgEventListeners(); 221 | load_pfps(); 222 | } 223 | } 224 | 225 | 226 | 227 | 228 | 229 | /* 230 | for (const [user, recent] of Object.entries(users)) { 231 | getProfilePicture(user, (pfp) => { 232 | msgsDiv = $('.left-msgs'); 233 | if (recent.from == authToken.username) { // from me 234 | if (recent.read) { // they opened it 235 | status = "read" 236 | } else { // sent successfully to them 237 | status = "sent" 238 | } 239 | } else { // to me 240 | if (recent.read) { // i've read it 241 | status = "opened" 242 | } else { // i havent - aka unread 243 | status = "received" 244 | } 245 | } 246 | 247 | // because css is stupid as hell we need to have the read class on the last message that has been read ONLY so cant just add read to every message thats been read smh... ive already added the code to remove the class read when you get pinged for a new msg being read 248 | 249 | msgsDiv.append($(` 250 | 251 | 265 | `)); 266 | 267 | $('.node-radio').bind('click', (event) => { 268 | document.querySelector('.right .no-msg').style.display = 'none'; 269 | $(`label[for=${event.target.id}]`).addClass('seen'); 270 | loadConvo($(`label[for=${event.target.id}`).find('div .name').text()); // loadConvo(username) 271 | }) 272 | 273 | if (first) { 274 | $('.loading-msgs').hide(); 275 | first = false; 276 | } 277 | 278 | _msg_node_increment++; 279 | }) 280 | }*/ 281 | }) 282 | }) 283 | } 284 | 285 | function renderText(text) { // ------------------------ i need ur help here marcus, i need to make all img tags be inside a label and a checkbox before the label 286 | const userRe = /(?$&')), { 288 | allowedTags: sanitizeHtml.defaults.allowedTags.concat([ 'img' ]) 289 | }); 290 | } 291 | 292 | function displaySentMessage(message) { 293 | if (message.to in _msg_cache) { 294 | _msg_cache[message.to].push(message) 295 | } else { 296 | _msg_cache[message.to] = [message]; 297 | } 298 | 299 | _msg_cache[message.to] = _msg_cache[message.to].slice().sort((a, b) => { (a.time < b.time) ? 1 : -1 }); 300 | 301 | if ($('.chat .top span').text() == message.to) { 302 | if (document.getElementById(`msg-${message.id}`)) { 303 | return; 304 | } 305 | 306 | $('.chat .box').append($(` 307 |
308 | ${renderText(message.body)} 309 | 310 |
311 | `)) 312 | } 313 | 314 | var box = $('.chat .box'); // scroll to bottom of chat 315 | box.scrollTop(box.prop('scrollHeight')); 316 | } 317 | 318 | function checkReadStatus(user) { 319 | var ids = []; 320 | var elms = Array.from(document.getElementsByClassName('msg-node')); 321 | elms.forEach((el) => { 322 | //TODO: check if element is in viewport 323 | try { 324 | var msg = JSON.parse(atob(el.getElementsByClassName('hidden-input')[0].value)); 325 | if (!(msg.read) && !(msg.from == authToken.username)) { 326 | ids.push(msg.id); 327 | } 328 | } catch(err) { 329 | console.log('error checking read status. err:', err, 'elm:', el); 330 | } 331 | }) 332 | if (ids.length > 0) { 333 | markRead(ids, (res) => { 334 | console.log("Marked as read:", res, 'from:', ids); 335 | }) 336 | } 337 | 338 | /*recent = elms[elms.length - 1] 339 | if (recent.from == authToken.username) { // from me 340 | if (recent.read) { // they opened it 341 | status = "read" 342 | } else { // sent successfully to them 343 | status = "sent" 344 | } 345 | } else { // to me 346 | if (recent.read) { // i've read it 347 | status = "opened" 348 | } else { // i havent - aka unread 349 | status = "received" 350 | } 351 | } 352 | 353 | $(`#status-${user}`).attr('status', status); 354 | */ // --------------------------------- this was always setting status to "received" 355 | 356 | if ($(`#status-${user}`).attr('status') == "received") { // my solution 357 | $(`#status-${user}`).attr('status', 'opened'); 358 | } 359 | } 360 | 361 | function loadPrevious() { // dis no work ------------------------------------------------------------------ 362 | $('.load-old-msgs').animate({ // loading msgs anim 363 | marginTop: "5px" 364 | }, 200); 365 | 366 | user = $('.chat .top span').text(); 367 | var html = ''; 368 | if (user in _msg_cache) { 369 | getMessages(user, (messages) => { 370 | _msg_cache[user].unshift(...messages) // *messages 371 | _msg_cache[user] = _msg_cache[user].slice().sort((a, b) => { (a.time < b.time) ? 1 : -1 }); 372 | //$('.chat .box').clear(); 373 | 374 | _msg_cache[user].forEach((item, index) => { 375 | if ((item.from == authToken.username) && (item.read)) { 376 | msgClass = 'sent read' 377 | } else if (item.from == authToken.username) { 378 | msgClass = 'sent'; 379 | } else { 380 | msgClass = 'received' 381 | } 382 | 383 | if (document.getElementById(`msg-${item.id}`)) { 384 | return; 385 | } 386 | var html = html + ` 387 |
388 | ${renderText(item.body)} 389 | 390 |
391 | `; 392 | 393 | /* 394 | $('.chat .box').append($(` 395 |
396 | ${renderText(item.body)} 397 | 398 |
399 | `)) //TODO: markdown and filter xss, add time to message 400 | 401 | var box = $('.chat .box'); 402 | box.scrollTop(box.prop('scrollHeight')); 403 | */ 404 | }) 405 | $('.chat .box').html(html + $('.chat .box').html()); 406 | console.log(html) 407 | }, older_than=_msg_cache[user][0].time) 408 | } 409 | } 410 | 411 | function loadConvo(user) { 412 | $('.chat .box').empty() // we gotta clear g 413 | 414 | $('.load-old-msgs').animate({ // loading msgs anim 415 | marginTop: "5px" 416 | }, 200); 417 | 418 | if ($('.chat .top span').text() == user) { 419 | return; 420 | } 421 | 422 | $('.chat .top span').text(user); 423 | $('.chat .top span').off('click'); 424 | $('.chat .top span').click(() => { 425 | window.open(`/@${user}`, '_blank'); 426 | }) 427 | getProfilePicture(user, (src) => { 428 | $('.chat .top .chat-img').attr('src', src); 429 | }); 430 | 431 | // showdupl badge 432 | if (['rafrafraf', 'MarcusWeinberger'].includes(user)) { 433 | $('.chat .top .badge').show(); 434 | } 435 | else { 436 | $('.chat .top .badge').hide(); 437 | } 438 | 439 | if (user in _msg_cache) { 440 | _msg_cache[user] = _msg_cache[user].slice().sort((a, b) => { (a.time < b.time) ? 1 : -1 }); 441 | _msg_cache[user].forEach((item, index) => { 442 | if ((item.from == authToken.username) && (item.read)) { 443 | msgClass = 'sent read' 444 | } else if (item.from == authToken.username) { 445 | msgClass = 'sent'; 446 | } else { 447 | msgClass = 'received' 448 | } 449 | 450 | if (document.getElementById(`msg-${item.id}`)) { 451 | return; 452 | } 453 | 454 | $('.chat .box').append($(` 455 |
456 | ${renderText(item.body)} 457 | 458 |
459 | `)) //TODO: markdown and filter xss, add time to message 460 | 461 | var box = $('.chat .box'); // scroll to bottom of chat 462 | box.scrollTop(box.prop('scrollHeight')); 463 | }) 464 | 465 | getMessages(user, (messages) => { 466 | _msg_cache[user].push(...messages) // *messages 467 | 468 | _msg_cache[user] = _msg_cache[user].slice().sort((a, b) => ((a.time < b.time) ? 1 : -1)); 469 | 470 | if ($('.chat .top span').text() != user) return; 471 | $('.chat .box').empty(); 472 | _msg_cache[user].forEach((item, index) => { 473 | if ((item.from == authToken.username) && (item.read)) { 474 | msgClass = 'sent read' 475 | } else if (item.from == authToken.username) { 476 | msgClass = 'sent'; 477 | } else { 478 | msgClass = 'received' 479 | } 480 | 481 | if (document.getElementById(`msg-${item.id}`)) { 482 | return; 483 | } 484 | 485 | $('.chat .box').append($(` 486 |
487 | ${renderText(item.body)} 488 | 489 |
490 | `)) //TODO: markdown and filter xss, add time to message 491 | 492 | $('.load-old-msgs').animate({ // loading msgs anim 493 | marginTop: "-30px" 494 | }, 200); 495 | 496 | var box = $('.chat .box'); // scroll to bottom of chat 497 | box.scrollTop(box.prop('scrollHeight')); 498 | }) 499 | }, newer_than=_msg_cache[user][_msg_cache[user].length - 1].time) 500 | } else { // fuck you rafi this is the better way of formatting if/else 501 | getMessages(user, (messages) => { 502 | _msg_cache[user] = messages.sort((a, b) => { (a.time < b.time) ? 1 : -1 }); 503 | if ($('.chat .top span').text() != user) return; 504 | $('.chat .box').empty(); 505 | _msg_cache[user].forEach((item, index) => { 506 | if ((item.from == authToken.username) && (item.read)) { 507 | msgClass = 'sent read' 508 | } else if (item.from == authToken.username) { 509 | msgClass = 'sent'; 510 | } else { 511 | msgClass = 'received' 512 | } 513 | 514 | if (document.getElementById(`msg-${item.id}`)) { 515 | return; 516 | } 517 | 518 | $('.chat .box').append($(` 519 |
520 | ${renderText(item.body)} 521 | 522 |
523 | `)) //TODO: markdown and filter xss, add time to message 524 | 525 | $('.load-old-msgs').animate({ // loading msgs anim 526 | marginTop: "-30px" 527 | }, 200); 528 | 529 | var box = $('.chat .box'); // scroll to bottom of chat 530 | box.scrollTop(box.prop('scrollHeight')); 531 | }) 532 | }) 533 | } 534 | setTimeout(() => { checkReadStatus(user) }, 1500); 535 | } 536 | 537 | // https://stackoverflow.com/a/12475270/8291579 538 | function time_ago(time) { 539 | 540 | switch (typeof time) { 541 | case 'number': 542 | break; 543 | case 'string': 544 | time = +new Date(time); 545 | break; 546 | case 'object': 547 | if (time.constructor === Date) time = time.getTime(); 548 | break; 549 | default: 550 | time = +new Date(); 551 | } 552 | var time_formats = [ 553 | [60, 'seconds', 1], // 60 554 | [120, '1 minute ago', '1 minute from now'], // 60*2 555 | [3600, 'minutes', 60], // 60*60, 60 556 | [7200, '1 hour ago', '1 hour from now'], // 60*60*2 557 | [86400, 'hours', 3600], // 60*60*24, 60*60 558 | [172800, 'Yesterday', 'Tomorrow'], // 60*60*24*2 559 | [604800, 'days', 86400], // 60*60*24*7, 60*60*24 560 | [1209600, 'Last week', 'Next week'], // 60*60*24*7*4*2 561 | [2419200, 'weeks', 604800], // 60*60*24*7*4, 60*60*24*7 562 | [4838400, 'Last month', 'Next month'], // 60*60*24*7*4*2 563 | [29030400, 'months', 2419200], // 60*60*24*7*4*12, 60*60*24*7*4 564 | [58060800, 'Last year', 'Next year'], // 60*60*24*7*4*12*2 565 | [2903040000, 'years', 29030400], // 60*60*24*7*4*12*100, 60*60*24*7*4*12 566 | [5806080000, 'Last century', 'Next century'], // 60*60*24*7*4*12*100*2 567 | [58060800000, 'centuries', 2903040000] // 60*60*24*7*4*12*100*20, 60*60*24*7*4*12*100 568 | ]; 569 | var seconds = (+new Date() - time) / 1000, 570 | token = 'ago', 571 | list_choice = 1; 572 | 573 | if (seconds == 0) { 574 | return 'Just now' 575 | } 576 | if (seconds < 0) { 577 | seconds = Math.abs(seconds); 578 | token = 'from now'; 579 | list_choice = 2; 580 | } 581 | var i = 0, 582 | format; 583 | while (format = time_formats[i++]) 584 | if (seconds < format[0]) { 585 | if (typeof format[2] == 'string') 586 | return format[list_choice]; 587 | else 588 | return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token; 589 | } 590 | return time; 591 | } 592 | //test 593 | function authed() { 594 | /* content scripts cant run this - must be done in bg 595 | chrome.runtime.requestUpdateCheck((status, details) => { 596 | console.log(`[checkUpdate] status: ${status}, details: ${details}`); 597 | if (status == 'update_available') { 598 | if (_notify_perm && _settings.notifications) { 599 | var notif = new Notification(`An update is available`, { 600 | body: `Click to update`, 601 | silent: true 602 | }); 603 | 604 | notif.onclick = () => { 605 | chrome.runtime.reload(); 606 | }; 607 | 608 | if (_settings.sound) { 609 | // sound effect 610 | chrome.runtime.sendMessage( 611 | "play sound" 612 | ); 613 | } 614 | } 615 | } 616 | }) 617 | */ 618 | console.log('authed') 619 | 620 | var path = window.location.pathname; 621 | $('html').on('DOMSubtreeModified', 'body', () => { 622 | if (window.location.pathname !== path) { 623 | $('.cont').hide(); 624 | setTimeout(() => { 625 | setup(); 626 | path = window.location.pathname; 627 | }, 100) 628 | } 629 | $('.user-hover-card .user-info-card-header span.jsx-1369737386:not(.user-info-card-full-name)').after().click(() => { 630 | var username = $('.user-hover-card-anchor span.jsx-801033477').text().split(" ")[0].replace('@',''); 631 | newMessageTo(username); 632 | }) 633 | }); 634 | 635 | function setup() { 636 | // add message button to profile page 637 | setTimeout(() => { 638 | const profilePageUser = document.querySelector(".profile-username-label").childNodes[2].data; //get username 639 | 640 | if (authToken.username != profilePageUser && $('.profile-username-label').length !== 0 && $('.message-btn').length == 0) { 641 | $('
message
').insertAfter('.profile-username-label'); 642 | 643 | document.querySelector('.message-btn').addEventListener('click', (event) => { 644 | newMessageTo(event.target.previousElementSibling.innerText.split(" ")[0]); 645 | }) 646 | } 647 | }, 200) 648 | 649 | // add repldm button 650 | if ($('.repldmBtn').length == 0) { 651 | // dark theme check 652 | var dark; 653 | if ($('header').css('background-color') == "rgb(29, 35, 51)") { 654 | dark = 'darktheme'; 655 | } 656 | else { 657 | dark = ''; 658 | } 659 | var html = ` 660 |
661 | 662 | 663 |
repl DM
664 |
`; 665 | $(html).insertAfter('.scroll-container .new-repl-cta'); 666 | 667 | $('.repldmBtn').click(() => { 668 | if (_first_load) { 669 | init(); 670 | globalThis._first_load = false; 671 | } 672 | var open = $('.cont').is(':visible'); 673 | $('.repldmBtn .fa-paper-plane').toggle(); 674 | $('.repldmBtn').toggleClass('open'); 675 | if (!open) { // open 676 | $('body').css('overflow', 'hidden'); // stops page scrolling 677 | $('.cont').show(); 678 | $('.dmWrapper').css({ 679 | marginTop: '-400px', 680 | opacity: '0.2' 681 | }); 682 | $('.dmWrapper').animate({ 683 | marginTop: '0', 684 | opacity: '1' 685 | }, 100); 686 | } 687 | else { // close 688 | $('body').css('overflow', 'scroll'); 689 | $('.new-msg-cont').hide(); 690 | $('.dmWrapper').animate({ 691 | marginTop: '-400px', 692 | opacity: '0.1' 693 | }, 100, () => { 694 | $('.cont').hide(); 695 | }); 696 | } 697 | }) 698 | } 699 | 700 | // add repldm page 701 | if ($('.cont').length == 0) { 702 | var pageHtml = ` 802 | 803 | `; 814 | 815 | $('body').append($(pageHtml)); 816 | 817 | // image drop script ---------------------- 818 | var counter = 0; 819 | $('.dmWrapper').bind({ 820 | dragenter: function(ev) { 821 | ev.preventDefault(); // needed for IE 822 | counter++; 823 | $('.image-drop').addClass('active'); 824 | }, 825 | 826 | dragleave: function() { 827 | counter--; 828 | if (counter === 0) { 829 | $('.image-drop').removeClass('active'); 830 | } 831 | }, 832 | 833 | dragover: (e) => { 834 | e = e || event; 835 | e.preventDefault(); 836 | }, 837 | 838 | drop: (ev) => { // file dropped 839 | e = ev || event; 840 | e.preventDefault(); 841 | e.stopPropagation(); 842 | 843 | ev.dataTransfer = ev.originalEvent.dataTransfer; 844 | if (ev.dataTransfer.items) { 845 | // Use DataTransferItemList interface to access the file(s) 846 | for (var i = 0; i < ev.dataTransfer.items.length; i++) { 847 | // If dropped items aren't files, reject them 848 | if (ev.dataTransfer.items[i].kind === 'file') { 849 | var file = ev.dataTransfer.items[i].getAsFile(); 850 | console.log('... file[' + i + '].name = ' + file.name); 851 | } 852 | } 853 | } else { 854 | // Use DataTransfer interface to access the file(s) 855 | for (var i = 0; i < ev.dataTransfer.files.length; i++) { 856 | var file = ev.dataTransfer.files[i]; 857 | console.log('... file[' + i + '].name = ' + file.name); 858 | } 859 | } 860 | 861 | $('.image-drop').removeClass('active'); 862 | counter = 0; 863 | } 864 | }); 865 | // /image drop script ---------------------- 866 | 867 | // scroll script 868 | $('.chat .box').on('scroll', () => { 869 | var scrollTop = $('.chat .box').scrollTop(); 870 | if (scrollTop <= 0) { 871 | loadPrevious(); 872 | console.log('loading old messages') 873 | } 874 | }); 875 | 876 | // resizer script 877 | var up = false; 878 | var leftW = 300; 879 | $('.dmWrapper .resizer').bind('mousedown', (ev) => { 880 | up = true; 881 | var startPos = ev.pageX; 882 | $('body').css({ 883 | cursor: 'grabbing', 884 | userSelect: 'none' 885 | }); 886 | var rightW = $('.dmWrapper .right').width(); 887 | $('body').mousemove((e) => { 888 | var tmp = (e.pageX - ev.pageX); 889 | var newW = leftW + tmp; 890 | if ((newW >= 150) && (rightW - tmp) >= 360) { 891 | $('.dmWrapper .left').width(newW); 892 | } 893 | }) 894 | }) 895 | $('body').bind('mouseup', () => { 896 | if (up) { 897 | up = false; 898 | $('body').off('mousemove'); 899 | leftW = $('.dmWrapper .left').width(); 900 | $('body').css({ 901 | cursor: '', 902 | userSelect: '' 903 | }); 904 | } 905 | }) 906 | 907 | window.addEventListener('paste', (event) => { 908 | var items = (event.clipboardData || event.originalEvent.clipboardData).items; 909 | for (index in items) { 910 | var item = items[index]; 911 | if (item.kind === 'file') { 912 | var file = item.getAsFile(); 913 | var filename = file.name; 914 | /*Get File Extension*/ 915 | var ext = filename.split('.').reverse()[0].toLowerCase(); 916 | /*Check Image File Extensions*/ 917 | if (jQuery.inArray(ext, ['jpg', 'png', 'gif', 'jpeg']) > -1) { 918 | /*Create FormData Instance*/ 919 | var data = new FormData(); 920 | data.append('image', file); 921 | /*Request Ajax With File*/ 922 | $.ajax({ 923 | url: 'https://i.marcusj.tech/api/upload', 924 | data: data, 925 | type: 'POST', 926 | processData: false, 927 | contentType: false, 928 | success: function (response) { 929 | var body = $('input.msg').val() + `![img](${response.url})`; 930 | $('input.msg').val(body); 931 | } 932 | }) 933 | } 934 | } 935 | } 936 | }) 937 | 938 | // font size 939 | chrome.storage.local.get(['fontsize'], (res) => { 940 | if (typeof res.fontsize === 'undefined') { 941 | chrome.storage.local.set({'fontsize': '16px'}); 942 | } 943 | else { 944 | $('.dmWrapper .right .box').removeClass('small'); 945 | $('.dmWrapper .right .box').removeClass('large'); 946 | 947 | if (res.fontsize == '12px') { // small 948 | $('.dmWrapper .right .box').addClass('small'); 949 | } 950 | else if (res.fontsize == '20px'){ // large 951 | $('.dmWrapper .right .box').addClass('large'); 952 | } 953 | } 954 | }) 955 | 956 | // background color 957 | chrome.storage.local.get(['background'], (res) => { 958 | if (typeof res.background === 'undefined') { 959 | chrome.storage.local.set({'background': 'white'}); 960 | } 961 | else { 962 | $('.dmWrapper .right').css('background-color', res.background); 963 | 964 | if (res.background == 'white') { 965 | document.querySelector('.dmWrapper .right').classList.add('white-bg'); 966 | $('.dmWrapper').attr('theme', 'white'); // white 967 | } 968 | else { 969 | document.querySelector('.dmWrapper .right').classList.remove('white-bg'); 970 | if (res.background == 'rgb(34, 85, 221)') { // blue 971 | $('.dmWrapper').attr('theme', 'blue'); 972 | } 973 | else if (res.background == 'rgb(37, 211, 102)') { // green 974 | $('.dmWrapper').attr('theme', 'green'); 975 | } 976 | else if (res.background == 'rgb(222, 96, 82)') { // red 977 | $('.dmWrapper').attr('theme', 'red'); 978 | } 979 | else if (res.background == 'rgb(242, 236, 58)') { // yellow 980 | $('.dmWrapper').attr('theme', 'yellow'); 981 | } 982 | } 983 | } 984 | }) 985 | chrome.storage.local.get(['settings'], (res) => { 986 | if (res.settings) { 987 | // notifications 988 | if (res.settings.notifications) { 989 | document.getElementsByClassName('change-notifications')[0].checked = true; 990 | } 991 | // notifications sound 992 | if (res.settings.sound) { 993 | document.getElementsByClassName('change-sound')[0].checked = true; 994 | } 995 | } 996 | else { 997 | document.getElementsByClassName('change-notifications')[0].checked = true; 998 | document.getElementsByClassName('change-sound')[0].checked = true; 999 | } 1000 | }) 1001 | } 1002 | } 1003 | 1004 | window.onload = setup(); 1005 | 1006 | // toggle settings 1007 | var els = document.getElementsByClassName('settings-btn'); 1008 | for (i=0; i { 1010 | var ele = document.querySelector('.dmWrapper .settings'); 1011 | if (ele.classList.contains('open')) { 1012 | ele.classList.remove('open'); 1013 | } 1014 | else { 1015 | ele.classList.add('open'); 1016 | } 1017 | }) 1018 | } 1019 | 1020 | // change font size 1021 | var els = document.getElementsByClassName('change-size'); 1022 | for (i=0; i { 1024 | $('.dmWrapper .right .box').removeClass('small'); 1025 | $('.dmWrapper .right .box').removeClass('large'); 1026 | 1027 | if (event.target.style.fontSize == '12px') { // small 1028 | $('.dmWrapper .right .box').addClass('small'); 1029 | } 1030 | else if (event.target.style.fontSize == '20px'){ // large 1031 | $('.dmWrapper .right .box').addClass('large'); 1032 | } 1033 | // font size 1034 | chrome.storage.local.set({'fontsize': event.target.style.fontSize}); 1035 | 1036 | }) 1037 | } 1038 | 1039 | // change bg color 1040 | var els = document.getElementsByClassName('change-color'); 1041 | for (i=0; i { 1043 | document.querySelector('.dmWrapper .right').style.backgroundColor = event.target.style.backgroundColor; 1044 | if (event.target.style.backgroundColor == 'white') { 1045 | document.querySelector('.dmWrapper .right').classList.add('white-bg'); 1046 | $('.dmWrapper').attr('theme', 'white'); 1047 | } 1048 | else { 1049 | document.querySelector('.dmWrapper .right').classList.remove('white-bg'); 1050 | } 1051 | 1052 | if (event.target.style.backgroundColor == 'rgb(34, 85, 221)') { // blue 1053 | $('.dmWrapper').attr('theme', 'blue'); 1054 | } 1055 | else if (event.target.style.backgroundColor == 'rgb(37, 211, 102)') { // green 1056 | $('.dmWrapper').attr('theme', 'green'); 1057 | } 1058 | else if (event.target.style.backgroundColor == 'rgb(222, 96, 82)') { // red 1059 | $('.dmWrapper').attr('theme', 'red'); 1060 | } 1061 | else if (event.target.style.backgroundColor == 'rgb(242, 236, 58)') { // yellow 1062 | $('.dmWrapper').attr('theme', 'yellow'); 1063 | } 1064 | // background color 1065 | chrome.storage.local.set({'background': event.target.style.backgroundColor}); 1066 | }) 1067 | } 1068 | 1069 | // change notifications 1070 | var chn = document.getElementsByClassName('change-notifications')[0]; 1071 | chn.addEventListener('change', () => { 1072 | if ($(chn).is(':checked')) { 1073 | _settings.notifications = true; 1074 | } 1075 | else { 1076 | _settings.notifications = false; 1077 | } 1078 | chrome.storage.local.set({'settings': _settings}); 1079 | }) 1080 | 1081 | // change notif sound 1082 | var chs = document.getElementsByClassName('change-sound')[0]; 1083 | chs.addEventListener('change', () => { 1084 | if ($(chs).is(':checked')) { 1085 | _settings.sound = true; 1086 | } 1087 | else { 1088 | _settings.sound = false; 1089 | } 1090 | chrome.storage.local.set({'settings': _settings}); 1091 | }) 1092 | 1093 | // close new message 1094 | document.querySelector('.close-new-msg').addEventListener('click', () => { 1095 | document.querySelector('.new-msg-cont').style.display = 'none'; 1096 | }) 1097 | 1098 | // open new message 1099 | document.querySelector('.write-msg-btn').addEventListener('click', () => { 1100 | document.querySelector('.new-msg-cont').style.display = ''; 1101 | }) 1102 | 1103 | // send msg to user 1104 | document.querySelector('.send-new-msg').addEventListener('click', () => { 1105 | document.querySelector('.new-msg-cont').style.display = ''; 1106 | loadConvo($('.new-msg .to input').val()); 1107 | sendMessage($('.new-msg .to input').val(), $('.new-msg .message textarea').val(), (msg) => { 1108 | displaySentMessage(msg); 1109 | }) 1110 | $('.new-msg .to input').val(''); 1111 | $('.new-msg .message textarea').val(''); 1112 | document.querySelector('.new-msg-cont').style.display = 'none'; 1113 | msgsDiv = $('.left-msgs').empty(); 1114 | init(); 1115 | }) 1116 | 1117 | document.querySelector('.msg').addEventListener('keyup', (event) => { 1118 | if (event.key == 'Enter') { 1119 | sendMessage($('.chat .top span').text(), $(event.target).val(), displaySentMessage) 1120 | $(event.target).val(''); 1121 | } 1122 | }) 1123 | 1124 | function newMessageTo(name) { 1125 | $('.repldmBtn .fa-paper-plane').toggle(); 1126 | $('.repldmBtn').toggleClass('open'); 1127 | $('.cont').show(); 1128 | 1129 | $('.dmWrapper').animate({ 1130 | marginTop: '0', 1131 | opacity: '1' 1132 | }, 100, () => { 1133 | $('.new-msg-cont').show(); 1134 | $('.new-msg-cont .to input').val(name); 1135 | $('.new-msg-cont .message input').focus(); 1136 | }); 1137 | 1138 | $('.repldmBtn .fa-paper-plane').toggle(); 1139 | 1140 | // delete the profile prompt thingy 1141 | if ($('.user-hover-card-anchor').length !== 0) { 1142 | $('.user-hover-card-anchor').hide(); 1143 | } 1144 | } 1145 | 1146 | } 1147 | 1148 | function getAuth() { 1149 | $('.auth-wrapper').hide(); 1150 | var auth = $('#authTkn').val().split(':'); 1151 | var authObj = { 1152 | username: auth[0], 1153 | token: auth[1] 1154 | } 1155 | chrome.storage.sync.set({'auth': authObj}, (r) => { console.log("auth object stored") }) 1156 | chrome.storage.sync.set({'settings': { 1157 | 'notifications': true, 1158 | 'sound': true, 1159 | 'color': 'white', 1160 | 'font-size': '16px' 1161 | }}, (r) => { console.log("default settings stored") }) 1162 | socket.emit('hello', {auth: authObj}, (r) => { 1163 | $('repldmBtn').attr('notifications', `${Object.keys(r).length}`); 1164 | }) 1165 | authed(); 1166 | init(); 1167 | } 1168 | 1169 | chrome.storage.sync.get(['auth'], (res) => { 1170 | console.log(res) 1171 | if (Object.keys(res).length === 0) { // no auth object 1172 | var authHtml = ``; 1180 | 1181 | $('body').append($(authHtml)); 1182 | 1183 | document.querySelector('.auth-btn').addEventListener('click', () => { 1184 | window.open("https://repldm.dupl.repl.co/auth", "_blank"); 1185 | 1186 | document.getElementById('auth-form').innerHTML = ``; 1187 | 1188 | document.getElementById('get-auth-btn').addEventListener('click', getAuth); 1189 | }) 1190 | 1191 | $('.auth-wrapper').fadeIn(); 1192 | 1193 | $('.close-auth').click(() => { 1194 | $('.auth-wrapper').hide(); 1195 | }) 1196 | } 1197 | else { 1198 | globalThis.authToken = res.auth; 1199 | socket.emit('hello', {auth: res.auth}, (r) => { console.log(r) }) 1200 | chrome.storage.local.get(['settings'], (res) => { 1201 | if (res.settings) { 1202 | globalThis._settings = res.settings; 1203 | } else { 1204 | globalThis._settings = { 1205 | 'notifications': true, 1206 | 'sound': true, 1207 | 'color': 'white', 1208 | 'font-size': '16px' 1209 | } 1210 | chrome.storage.local.set({'settings': _settings}, (r) => { console.log("applied default settings") }) 1211 | } 1212 | }) 1213 | authed(); 1214 | } 1215 | }) 1216 | 1217 | Notification.requestPermission().then((res) => { 1218 | globalThis._notify_perm = res; 1219 | }) 1220 | 1221 | const _NOTIF_AUDIO = "data:audio/mpeg;base64,SUQzAwAAAAAPdlRJVDIAAABfAAAB//5zAG4AYQBwAGMAaABhAHQAIABuAG8AdABpAGYAaQBjAGEAdABpAG8AbgAgAHQAbwBuAGUAIAA1ADAANQA0ADkAMwA2ADYANAAwADgAMgA0ADYANAA5ADkAMAA5AENPTU0AAACKAAABWFhY//4AAP/+WAAyAEMAbwBuAHYAZQByAHQALgBjAG8AbQAsACAAQgBlAHMAdAAgAGMAbwBuAHYAZQByAHQAZQByACAAZgBvAHIAIABhAGwAbAAgAGYAaQBsAGUAIAB0AHkAcABlADoAIABBAHUAZABpAG8ALAAgAFYAaQBkAGUAbwAuAC4ALgBUU1NFAAAAHwAAAf/+ZgByAGUAOgBhAGMAIAB2ADEALgAxAC4AMgBiAENUT0MAAAALAAB0b2MAAwFjaHAwAENIQVAAAAAVAABjaHAwAAAAAAAAAAQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+5BkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYaW5nAAAADwAAACoAABdiERERERERERERWVlZWVlZWVldXV1dXV1dXWFhYWFhYWFhYWZmZmZmZmZmampqampqampvb29vb29vb29zc3Nzc3Nzc3h4eHh4eHh4g4ODg4ODg4ODi4uLi4uLi4uSkpKSkpKSkgAAADJMQU1FMy4xMDAEqgAAAAAAAAAANSAkAsBNAAHCAAAXYqXKIfEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+6BkAA/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk8w/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAJAIAFA4AoA+pkg4JRKJ8IADj4zhUL3L2aYkeaIJHxTwWC//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEwCJJpA4QMIfTsV01QXMvBlqR84NnBy+BQIwUAbd7n4WIZCCigM+bAmXQ+79/AHCjjF/GaNldqffWfjE5AkrMAAErJCD/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAATgRvIalL+1X97b5n3CLoKNVZPQsPwq2blXX////sncN18FB4XYlXK1rVbP/////9OuNNMcBUkIa5FKeVWrtbOz+PP////7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABP///95I/I6SJy+G2Huu/797pcMeax5a/L//////////2X2t25Rt3LPWuSzcU+1lTZ1rVXXccaoph5YwABRbtt9+EwZx//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEiLis4ammk3OlYdDSpguCNbmUCYdlGg9JCGDziTFJFLXJuUJIGm2tkkDm22mHZdd164vvKBpZ2SCowkUAqVHgKyVwKVv/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAASQRlrNQ928sWBpeuu0a8y5kAAbS7/8AEwVIwhwG2N8XBQsRUHGYQiBjN8SagzYHtr3rUvy9e83btt9viY1LNahjHvtRf/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABJ3xqA30VdXvVTYf7n89F3zr+69aeKdEABMp/+AAGIhQ1zvKFGI8mBCqLzS4XsfA5a9qHX2CAGaiRnJNuZxtmqlFpnTW//sQZP+P8AAAaQAAAAgAAA0gAAABAAAB/gAAACAAADSAAAAEYiRRxc54KwNNQq+v+ILlEMoAAEROfAMArFUuWK2dL55lFIS1+lbKsEcHoFQzFXInBrFA2XNtVDOXe6c5cnqZxus6bNr/+2Bk/4AAAAB/hQAACAAADSCgAAEcWZNh+b2kCAAANIMAAAB8IuVZ+HygdfZEQDwOZlaoJQ6BQOBFTCISDsAOBFEo1gIdCGSSgIYcYgYUGgDGU4kHMqsNIeMkWMefMmeWOZYYj4coUWzZa3d7C6AOhsUMMQCpAdD01y/XBwNCN1IfQIF3kZV1W8dc0HC6Vl9qlU2ZbInGdX///9dbqb1Vh9t3Oexx4u/n////22SVIpAlqHH/p4YidDMSv/////+7b+c7yx/IjHq8plVmltWP///////9YW//v565GZE/F6Rxikl8olU3/S9N4OJeEGhUsGzRt3hlYQACbun24iKwq6aJ2mf/+0Bk/oDy7SNX/2kACAAAD/DgAAEJQE1T5+mKKAAAP8AAAARTzAWI14JZbYkjvT0fP+gDFWrFaa138bPg0OPAqHayobBVwqCo8NESobJYKrDWWKy0Sy2JQVO+o91VgqoOcRVgqCoSDqqamXEAABs/oAAcyalvTSmbRAUqfIk0qQy2FCtIV4hPRN8iILOkFAQxjIZUCAmYIepKv4PFqqqczhswP5RJ+6uamXEAABs/oAAcyalvTf/7QGTzgfH3GFH5+TIqAAAP8AAAAQeYazv1pYAoAAA/woAABCmbRAUqfIk0qQy2FCtIV4hPRN8iILOkFAQxjIZUCAmYIepKv4PFqqr+cOMF/ok/dHs7PDkACVvwkpJt0GiWvw6Ldn+Z04TBjAKT+JYGWLOWQg5GGJ/masa1SdLmRropjFEanck2v/IBNvwkpL7oNFLAjos+hprzpK6MEMzki15lBZyyEHIcET/IasahVJ0uZGro//twZP6ABkRP1+5rSQAAAA/wwAAACpQ5Y/2cACAAAD/DgAAEpiSiD6ldB1WS6FAA2/RAAQoMC8ViJ6LsXcl54kGS1mt4JML4AXD/PxPqBacWZ62sD9wFEEZG8ZpfC6F7LyPUN0mRvl4NsOohIrxGxuELKQdQmItomBOFAZgxA8HIoEgdxYBoQR6K5gWy0TSUVS4Zmg/E1ahNuPurmUJh+KN20LDmrAwToaq1jkyyVDVqjmTKCBo5KwWORkzVDI1lcjWVHImsch1KVetTfXVVH0ysU22qAL1s+EgKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7YET6ARH4IdD5+hsYPqQ6Hz9DYwZ0bz3jaGco043ndG2M5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7UGT3A/VHVUzp7B6qAAAP8AAAAQDAASSgAAAgAAA/wAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk9Y/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sQZP+P8AAAaQAAAAgAAA0gAAABAAABpAAAACAAADSAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+xBk/4/wAABpAAAACAAADSAAAAEAAAGkAAAAIAAANIAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7EGT/j/AAAGkAAAAIAAANIAAAAQAAAaQAAAAgAAA0gAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 1222 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgeOfMarcus/repl-dm-chrome/4c01ff70e328125f0772b1b327ee739da15fa8c3/icon.png -------------------------------------------------------------------------------- /ideas.md: -------------------------------------------------------------------------------- 1 | ## ideas: 2 | * custom right click menu: 3 | 1. delete message 4 | 2. copy to clipboard 5 | 6 | 7 | * maybe make chats have the same icons as snapchat to show the paper plane or chat and fill if unseen (hmmm i like this idea) 8 | 9 | * have something to show if a person has repl dm or not ---------------- dis a good idea i like dis 10 | 11 | * make scroll to top of chat load more messages 12 | 13 | * make it when u @ someone it becomes hoverable an blue n stuff thatd be c00l 14 | 15 | * **make a user not found for when you send a message to a user that doesnt exist** 16 | 17 | * **make a user does not have repldm yet** 18 | 19 | * **make loading chats faster by making profile pics lazy load perhaps?** 20 | 21 | * **make a site that lets ppl that cant use chrome extensions use it** 22 | --- 23 | 24 | ## todo: 25 | * make notification go to chat onclick 26 | 27 | * perhaps firefox support 28 | 29 | * make the css for different screen sizes 30 | 31 | * notification badge number 32 | 33 | * order the chats by most recent to oldest 34 | 35 | * notification onclick 36 | 37 | --- 38 | 39 | ## bugs: 40 | * overflow hidden bug when u go to a new page while on repldm smh 41 | 42 | * clicking back on a notification just makes the notifcation come back smh 43 | 44 | * fix the chat not showing up as read when i open it (for marcus' chat) 45 | 46 | * notifications come up too many times for each msg and clicking back makes it come back idk why 47 | 48 | * fix all the bugs with read lmao 49 | 50 | * duplicate messages 51 | 52 | * notification sound plays even if youre on chat 53 | 54 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | background 7 | 8 | 9 | click me! 10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ReplDM", 3 | "description": "Adds direct messaging functionality to replit.com", 4 | "version": "0.7.4", 5 | "manifest_version": 2, 6 | "icons": { 7 | "128": "icon.png" 8 | }, 9 | "content_scripts": [ 10 | { 11 | "matches": ["*://repl.it/*", "*://replit.com/*"], 12 | "js": ["./fontawesome.js", "./socket.io.js", "./jquery.min.js", "marked.min.js", "./sanitize-html.js", "./foreground.js"], 13 | "css": ["./fontawesome.css", "./repldm-page.css"] 14 | } 15 | ], 16 | "options_page": "./options.html", 17 | "browser_action": { 18 | "default_popup": "popup.html" 19 | }, 20 | "permissions": [ 21 | "storage", 22 | "tabs", 23 | "*://repl.it/*", 24 | "*://replit.com/*" 25 | ], 26 | "background": { 27 | "page": "index.html" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /marked.min.js: -------------------------------------------------------------------------------- 1 | !function(e,u){"object"==typeof exports&&"undefined"!=typeof module?module.exports=u():"function"==typeof define&&define.amd?define(u):(e="undefined"!=typeof globalThis?globalThis:e||self).marked=u()}(this,function(){"use strict";function r(e,u){for(var t=0;te.length)&&(u=e.length);for(var t=0,n=new Array(u);t=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function t(e){return D[e]}var e,u=(function(u){function e(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}u.exports={defaults:e(),getDefaults:e,changeDefaults:function(e){u.exports.defaults=e}}}(e={exports:{}}),e.exports),n=/[&<>"']/,s=/[&<>"']/g,l=/[<>"']|&(?!#?\w+;)/,a=/[<>"']|&(?!#?\w+;)/g,D={"&":"&","<":"<",">":">",'"':""","'":"'"};var c=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function h(e){return e.replace(c,function(e,u){return"colon"===(u=u.toLowerCase())?":":"#"===u.charAt(0)?"x"===u.charAt(1)?String.fromCharCode(parseInt(u.substring(2),16)):String.fromCharCode(+u.substring(1)):""})}var p=/(^|[^\[])\^/g;var g=/[^\w:]/g,f=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;var F={},A=/^[^:]+:\/*[^/]*$/,C=/^([^:]+:)[\s\S]*$/,d=/^([^:]+:\/*[^/]*)[\s\S]*$/;function E(e,u){F[" "+e]||(A.test(e)?F[" "+e]=e+"/":F[" "+e]=k(e,"/",!0));var t=-1===(e=F[" "+e]).indexOf(":");return"//"===u.substring(0,2)?t?u:e.replace(C,"$1")+u:"/"===u.charAt(0)?t?u:e.replace(d,"$1")+u:e+u}function k(e,u,t){var n=e.length;if(0===n)return"";for(var r=0;ru)t.splice(u);else for(;t.length>=1,e+=e;return t+e},S=u.defaults,T=k,I=y,R=m,Z=_;function q(e,u,t){var n=u.href,r=u.title?R(u.title):null,u=e[1].replace(/\\([\[\]])/g,"$1");return"!"!==e[0].charAt(0)?{type:"link",raw:t,href:n,title:r,text:u}:{type:"image",raw:t,href:n,title:r,text:R(u)}}var O=function(){function e(e){this.options=e||S}var u=e.prototype;return u.space=function(e){e=this.rules.block.newline.exec(e);if(e)return 1=t.length?e.slice(t.length):e}).join("\n")}(t,u[3]||"");return{type:"code",raw:t,lang:u[2]&&u[2].trim(),text:e}}},u.heading=function(e){var u=this.rules.block.heading.exec(e);if(u){var t=u[2].trim();return/#$/.test(t)&&(e=T(t,"#"),!this.options.pedantic&&e&&!/ $/.test(e)||(t=e.trim())),{type:"heading",raw:u[0],depth:u[1].length,text:t}}},u.nptable=function(e){e=this.rules.block.nptable.exec(e);if(e){var u={type:"table",header:I(e[1].replace(/^ *| *\| *$/g,"")),align:e[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:e[3]?e[3].replace(/\n$/,"").split("\n"):[],raw:e[0]};if(u.header.length===u.align.length){for(var t=u.align.length,n=0;n ?/gm,"");return{type:"blockquote",raw:u[0],text:e}}},u.list=function(e){e=this.rules.block.list.exec(e);if(e){for(var u,t,n,r,i,s,l=e[0],a=e[2],D=1g[1].length:n[1].length>=g[0].length||3/i.test(e[0])&&(u=!1),!t&&/^<(pre|code|kbd|script)(\s|>)/i.test(e[0])?t=!0:t&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0])&&(t=!1),{type:this.options.sanitize?"text":"html",raw:e[0],inLink:u,inRawBlock:t,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):R(e[0]):e[0]}},u.link=function(e){var u=this.rules.inline.link.exec(e);if(u){var t=u[2].trim();if(!this.options.pedantic&&/^$/.test(t))return;e=T(t.slice(0,-1),"\\");if((t.length-e.length)%2==0)return}else{var n=Z(u[2],"()");-1$/.test(t)?n.slice(1):n.slice(1,-1)),q(u,{href:n&&n.replace(this.rules.inline._escapes,"$1"),title:i&&i.replace(this.rules.inline._escapes,"$1")},u[0])}},u.reflink=function(e,u){if((t=this.rules.inline.reflink.exec(e))||(t=this.rules.inline.nolink.exec(e))){e=(t[2]||t[1]).replace(/\s+/g," ");if((e=u[e.toLowerCase()])&&e.href)return q(t,e,t[0]);var t=t[0].charAt(0);return{type:"text",raw:t,text:t}}},u.emStrong=function(e,u,t){void 0===t&&(t="");var n=this.rules.inline.emStrong.lDelim.exec(e);if(n&&(!n[3]||!t.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08C7\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\u9FFC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7CA\uA7F5-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDD\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/))){var r=n[1]||n[2]||"";if(!r||r&&(""===t||this.rules.inline.punctuation.exec(t))){var i,s=n[0].length-1,l=s,a=0,D="*"===n[0][0]?this.rules.inline.emStrong.rDelimAst:this.rules.inline.emStrong.rDelimUnd;for(D.lastIndex=0,u=u.slice(-1*e.length+s);null!=(n=D.exec(u));)if(i=n[1]||n[2]||n[3]||n[4]||n[5]||n[6])if(i=i.length,n[3]||n[4])l+=i;else if(!((n[5]||n[6])&&s%3)||(s+i)%3){if(!(0<(l-=i))){if(l+a-i<=0&&!u.slice(D.lastIndex).match(D)&&(i=Math.min(i,i+l+a)),Math.min(s,i)%2)return{type:"em",raw:e.slice(0,s+n.index+i+1),text:e.slice(1,s+n.index+i)};if(Math.min(s,i)%2==0)return{type:"strong",raw:e.slice(0,s+n.index+i+1),text:e.slice(2,s+n.index+i-1)}}}else a+=i}}},u.codespan=function(e){var u=this.rules.inline.code.exec(e);if(u){var t=u[2].replace(/\n/g," "),n=/[^ ]/.test(t),e=/^ /.test(t)&&/ $/.test(t);return n&&e&&(t=t.substring(1,t.length-1)),t=R(t,!0),{type:"codespan",raw:u[0],text:t}}},u.br=function(e){e=this.rules.inline.br.exec(e);if(e)return{type:"br",raw:e[0]}},u.del=function(e){e=this.rules.inline.del.exec(e);if(e)return{type:"del",raw:e[0],text:e[2]}},u.autolink=function(e,u){e=this.rules.inline.autolink.exec(e);if(e){var t,u="@"===e[2]?"mailto:"+(t=R(this.options.mangle?u(e[1]):e[1])):t=R(e[1]);return{type:"link",raw:e[0],text:t,href:u,tokens:[{type:"text",raw:t,text:t}]}}},u.url=function(e,u){var t,n,r,i;if(t=this.rules.inline.url.exec(e)){if("@"===t[2])r="mailto:"+(n=R(this.options.mangle?u(t[0]):t[0]));else{for(;i=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])[0],i!==t[0];);n=R(t[0]),r="www."===t[1]?"http://"+n:n}return{type:"link",raw:t[0],text:n,href:r,tokens:[{type:"text",raw:n,text:n}]}}},u.inlineText=function(e,u,t){e=this.rules.inline.text.exec(e);if(e){t=u?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):R(e[0]):e[0]:R(this.options.smartypants?t(e[0]):e[0]);return{type:"text",raw:e[0],text:t}}},e}(),y=w,_=x,w=v,x={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?! {0,3}bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,nptable:y,table:y,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};x.def=_(x.def).replace("label",x._label).replace("title",x._title).getRegex(),x.bullet=/(?:[*+-]|\d{1,9}[.)])/,x.item=/^( *)(bull) ?[^\n]*(?:\n(?! *bull ?)[^\n]*)*/,x.item=_(x.item,"gm").replace(/bull/g,x.bullet).getRegex(),x.listItemStart=_(/^( *)(bull) */).replace("bull",x.bullet).getRegex(),x.list=_(x.list).replace(/bull/g,x.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+x.def.source+")").getRegex(),x._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",x._comment=/|$)/,x.html=_(x.html,"i").replace("comment",x._comment).replace("tag",x._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),x.paragraph=_(x._paragraph).replace("hr",x.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|!--)").replace("tag",x._tag).getRegex(),x.blockquote=_(x.blockquote).replace("paragraph",x.paragraph).getRegex(),x.normal=w({},x),x.gfm=w({},x.normal,{nptable:"^ *([^|\\n ].*\\|.*)\\n {0,3}([-:]+ *\\|[-| :]*)(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)",table:"^ *\\|(.+)\\n {0,3}\\|?( *[-:]+[-| :]*)(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),x.gfm.nptable=_(x.gfm.nptable).replace("hr",x.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|!--)").replace("tag",x._tag).getRegex(),x.gfm.table=_(x.gfm.table).replace("hr",x.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|!--)").replace("tag",x._tag).getRegex(),x.pedantic=w({},x.normal,{html:_("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",x._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:y,paragraph:_(x.normal._paragraph).replace("hr",x.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",x.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});y={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:y,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",emStrong:{lDelim:/^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,rDelimAst:/\_\_[^_]*?\*[^_]*?\_\_|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,rDelimUnd:/\*\*[^*]*?\_[^*]*?\*\*|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:y,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~"};y.punctuation=_(y.punctuation).replace(/punctuation/g,y._punctuation).getRegex(),y.blockSkip=/\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g,y.escapedEmSt=/\\\*|\\_/g,y._comment=_(x._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),y.emStrong.lDelim=_(y.emStrong.lDelim).replace(/punct/g,y._punctuation).getRegex(),y.emStrong.rDelimAst=_(y.emStrong.rDelimAst,"g").replace(/punct/g,y._punctuation).getRegex(),y.emStrong.rDelimUnd=_(y.emStrong.rDelimUnd,"g").replace(/punct/g,y._punctuation).getRegex(),y._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,y._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,y._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,y.autolink=_(y.autolink).replace("scheme",y._scheme).replace("email",y._email).getRegex(),y._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,y.tag=_(y.tag).replace("comment",y._comment).replace("attribute",y._attribute).getRegex(),y._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,y._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,y._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,y.link=_(y.link).replace("label",y._label).replace("href",y._href).replace("title",y._title).getRegex(),y.reflink=_(y.reflink).replace("label",y._label).getRegex(),y.reflinkSearch=_(y.reflinkSearch,"g").replace("reflink",y.reflink).replace("nolink",y.nolink).getRegex(),y.normal=w({},y),y.pedantic=w({},y.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:_(/^!?\[(label)\]\((.*?)\)/).replace("label",y._label).getRegex(),reflink:_(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",y._label).getRegex()}),y.gfm=w({},y.normal,{escape:_(y.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\'+(t?e:H(e,!0))+"\n":"
"+(t?e:H(e,!0))+"
\n"},u.blockquote=function(e){return"
\n"+e+"
\n"},u.html=function(e){return e},u.heading=function(e,u,t,n){return this.options.headerIds?"'+e+"\n":""+e+"\n"},u.hr=function(){return this.options.xhtml?"
\n":"
\n"},u.list=function(e,u,t){var n=u?"ol":"ul";return"<"+n+(u&&1!==t?' start="'+t+'"':"")+">\n"+e+"\n"},u.listitem=function(e){return"
  • "+e+"
  • \n"},u.checkbox=function(e){return" "},u.paragraph=function(e){return"

    "+e+"

    \n"},u.table=function(e,u){return"\n\n"+e+"\n"+(u=u&&""+u+"")+"
    \n"},u.tablerow=function(e){return"\n"+e+"\n"},u.tablecell=function(e,u){var t=u.header?"th":"td";return(u.align?"<"+t+' align="'+u.align+'">':"<"+t+">")+e+"\n"},u.strong=function(e){return""+e+""},u.em=function(e){return""+e+""},u.codespan=function(e){return""+e+""},u.br=function(){return this.options.xhtml?"
    ":"
    "},u.del=function(e){return""+e+""},u.link=function(e,u,t){if(null===(e=V(this.options.sanitize,this.options.baseUrl,e)))return t;e='"},u.image=function(e,u,t){if(null===(e=V(this.options.sanitize,this.options.baseUrl,e)))return t;t=''+t+'":">"},u.text=function(e){return e},e}(),K=function(){function e(){}var u=e.prototype;return u.strong=function(e){return e},u.em=function(e){return e},u.codespan=function(e){return e},u.del=function(e){return e},u.html=function(e){return e},u.text=function(e){return e},u.link=function(e,u,t){return""+t},u.image=function(e,u,t){return""+t},u.br=function(){return""},e}(),Q=function(){function e(){this.seen={}}var u=e.prototype;return u.serialize=function(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")},u.getNextSafeSlug=function(e,u){var t=e,n=0;if(this.seen.hasOwnProperty(t))for(n=this.seen[e];t=e+"-"+ ++n,this.seen.hasOwnProperty(t););return u||(this.seen[e]=n,this.seen[t]=0),t},u.slug=function(e,u){void 0===u&&(u={});var t=this.serialize(e);return this.getNextSafeSlug(t,u.dryrun)},e}(),W=u.defaults,Y=b,ee=function(){function t(e){this.options=e||W,this.options.renderer=this.options.renderer||new J,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new K,this.slugger=new Q}t.parse=function(e,u){return new t(u).parse(e)},t.parseInline=function(e,u){return new t(u).parseInline(e)};var e=t.prototype;return e.parse=function(e,u){void 0===u&&(u=!0);for(var t,n,r,i,s,l,a,D,o,c,h,p,g,f,F,A="",C=e.length,d=0;dAn error occurred:

    "+ne(e.message+"",!0)+"
    ";throw e}}return ie.options=ie.setOptions=function(e){return ue(ie.defaults,e),re(ie.defaults),ie},ie.getDefaults=m,ie.defaults=u,ie.use=function(l){var u,t=ue({},l);l.renderer&&function(){var e,s=ie.defaults.renderer||new J;for(e in l.renderer)!function(r){var i=s[r];s[r]=function(){for(var e=arguments.length,u=new Array(e),t=0;tAn error occurred:

    "+ne(e.message+"",!0)+"
    ";throw e}},ie.Parser=ee,ie.parser=ee.parse,ie.Renderer=J,ie.TextRenderer=K,ie.Lexer=X,ie.lexer=X.lex,ie.Tokenizer=O,ie.Slugger=Q,ie.parse=ie}); -------------------------------------------------------------------------------- /messages-plan.md: -------------------------------------------------------------------------------- 1 | # **READ ME**. plan for handling messages: 2 | 3 | ## firstly, message caching 4 | client requests messages first time and stores them all in local storage 5 | 6 | new message recieved while client is offline, next time online: 7 | requests server for the number of unread chats. (to display the number on the red notif icon thingy mabob) 8 | 9 | when opening a chat: 10 | 1. first check if any chats are stored with this user whos chat client opened. 11 | 2. if so: if the username matches one of the ones that have an unread message with (which we requested from the server already), 12 | then first display all messages stored in local storage, add a loading icon while requesting all the unread messages from this user. 13 | 3. when recieved, hide the loading anim, store the new messages in local storage. 14 | 15 | 16 | **what we need**: 17 | 1. a server call that gets all the usernames from unread chats. (so if bob and sally sent me a few messages each, the server would just send the usernames "bob" and "sally"). this is important for the notification number and for my way of handling message caching 18 | 19 | ## next, handling message reads 20 | each message stored in server should have a bool attribute "read". 21 | 22 | if thats already in place then noice. 23 | 24 | when requesting messages, add class read to all messages that have the attribute read (ez) 25 | 26 | heres the tough part... 27 | okay so when ur in chat with someone and you send a message... 28 | 29 | my idea to solve this: 30 | 1. when client opens a chat and requests messages, the server should set the "read" attribute to True to all the messages requested. 31 | 2. the server checks if the username that sent the message is online (with session id's), if so send a socket thingy with the username of who they sent the message to saying read. lets call this socket emit "update_read" for now 32 | 3. when the client recieves the "update_read" socket emit, if he is in the chat with the user whos username was recieved, then add the class "read" to all messages in chat. **either way** update the local storage with all the messages sent attributes "read" to true. 33 | 34 | that being said, its easier said than done but this shouldnt be too hard to implement 35 | -------------------------------------------------------------------------------- /notification.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgeOfMarcus/repl-dm-chrome/4c01ff70e328125f0772b1b327ee739da15fa8c3/notification.mp3 -------------------------------------------------------------------------------- /options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | options 7 | 8 | 9 | 10 | 11 |

    im the options

    12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | popup 7 | 8 | 9 | 10 | 11 |

    Popup uner construction.

    12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /repldm-page.css: -------------------------------------------------------------------------------- 1 | 2 | .user-hover-card .user-info-card-header span.jsx-1369737386:not(.user-info-card-full-name)::after { 3 | content: 'message'; 4 | margin-left: 5px; 5 | background-color: #21953e; 6 | border: 1px solid transparent; 7 | color: white; 8 | padding: 2px; 9 | transition: color 0.5s; 10 | cursor: default; 11 | border-radius: 3px; 12 | font-size: 14px; 13 | transition: all 0.3s; 14 | } 15 | .user-hover-card .user-info-card-header span.jsx-1369737386:not(.user-info-card-full-name):hover::after { 16 | background-color: #228037; 17 | } 18 | 19 | 20 | .repldmBtn { 21 | flex-shrink: 0; 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | border-radius: 4px; 26 | cursor: pointer; 27 | position: relative; 28 | border-right: 3px solid transparent; 29 | padding: 8px; 30 | margin-bottom: 4px; 31 | } 32 | .repldmBtn.open { 33 | border-right: 3px solid #3485e4; 34 | background-color: rgba(52,133,228,0.12); 35 | } 36 | .repldmBtn:hover { 37 | background-color: #f3f3f3; 38 | } 39 | .repldmBtn.open:hover { 40 | background-color: rgba(52,133,228,0.12); 41 | } 42 | .repldmBtn[notifications]:not([notifications=""]):not([notifications="0"])::after { 43 | content: attr(notifications); 44 | background-color: #ff491c; 45 | width: 14px; 46 | height: 14px; 47 | color: white; 48 | display: flex; 49 | align-items: center; 50 | justify-content: center; 51 | border-radius: 50%; 52 | padding: 3px; 53 | font-size: 12px; 54 | } 55 | 56 | .repldmBtn .fa-paper-plane { 57 | height: 16px; 58 | width: auto; 59 | margin-right: 8px; 60 | } 61 | .repldmBtn .label { 62 | margin-right: auto; 63 | } 64 | .repldmBtn .label, .repldmBtn .fa-paper-plane { 65 | color: #363636; 66 | user-select: none; 67 | } 68 | 69 | 70 | .darktheme.repldmBtn .label, .darktheme.repldmBtn .fa-paper-plane { 71 | color: #e1e2e4; 72 | } 73 | .darktheme.repldmBtn:hover { 74 | background-color: #262b3b; 75 | } 76 | .darktheme.repldmBtn.open { 77 | border-right: 3px solid transparent; 78 | } 79 | 80 | .message-btn { 81 | width: fit-content; 82 | margin: auto; 83 | padding: 3px 9px; 84 | font-size: 16px; 85 | background-color: #21953e; 86 | color: white; 87 | border-radius: 3px; 88 | cursor: pointer; 89 | } 90 | 91 | .message-btn:hover { 92 | background-color: #228037; 93 | } 94 | 95 | 96 | 97 | /* repldm page css */ 98 | .cont { 99 | width: 100%; 100 | height: calc(100% - 60px); 101 | position: fixed; 102 | bottom: 0; 103 | right: 0; 104 | padding-left: 240px; 105 | background-color: #f6f6f6; 106 | display: flex; 107 | justify-content: center; 108 | align-items: center; 109 | color: black; 110 | font-family: 'IBM Plex Sans',sans-serif; 111 | z-index: 1000; 112 | } 113 | 114 | .dmWrapper { 115 | width: 85%; 116 | height: 90%; 117 | border-radius: 6px; 118 | border: 1px solid rgb(219,219,219); 119 | background-color: white; 120 | display: flex; 121 | overflow: hidden; 122 | z-index: 1000; 123 | } 124 | 125 | /* left */ 126 | .dmWrapper .left { 127 | border-right: 1px solid rgb(219,219,219); 128 | width: 300px; 129 | height: 100%; 130 | display: flex; 131 | flex-direction: column; 132 | position: relative; 133 | user-select: none; 134 | } 135 | 136 | .dmWrapper .left .left-top { 137 | width: 100%; 138 | height: 60px; 139 | display: flex; 140 | justify-content: center; 141 | align-items: center; 142 | border-bottom: 1px solid rgb(219,219,219); 143 | font-weight: 600; 144 | color: #19191a; 145 | flex-shrink: 0; 146 | } 147 | .dmWrapper .left .left-top .title { 148 | display: flex; 149 | justify-content: center; 150 | align-items: center; 151 | } 152 | .left-top .settings-btn { 153 | width: 16px; 154 | height: 16px; 155 | color: #19191a; 156 | display: flex; 157 | justify-content: center; 158 | align-items: center; 159 | cursor: pointer; 160 | position: absolute; 161 | left: 10px; 162 | } 163 | .left-top .write-msg-btn { 164 | width: 16px; 165 | height: 16px; 166 | color: #19191a; 167 | display: flex; 168 | justify-content: center; 169 | align-items: center; 170 | cursor: pointer; 171 | position: absolute; 172 | right: 10px; 173 | } 174 | 175 | .left-msgs { 176 | display: flex; 177 | width: 100%; 178 | height: 100%; 179 | position: relative; 180 | flex-direction: column; 181 | padding-top: 8px; 182 | overflow-x: hidden; 183 | overflow-y: scroll; 184 | padding-bottom: 150px; 185 | } 186 | 187 | .left-msgs .node { 188 | padding: 2px 12px; 189 | display: flex; 190 | align-items: center; 191 | justify-content: flex-start; 192 | height: 90px; 193 | cursor: pointer; 194 | flex-shrink: 0; 195 | border-right: 3px solid transparent; 196 | position: relative; 197 | } 198 | .left-msgs .node:hover { 199 | background-color: rgba(200,200,200,0.1); 200 | } 201 | 202 | .left-msgs .node .pfp { 203 | width: 60px; 204 | height: 60px; 205 | min-width: 60px; 206 | min-height: 60px; 207 | border-radius: 50%; 208 | overflow: hidden; 209 | position: relative; 210 | } 211 | .left-msgs .node .pfp img { 212 | min-width: 60px; 213 | width: auto; 214 | min-height: 60px; 215 | height: auto; 216 | max-width: 70px; 217 | max-height: 70px; 218 | position: absolute; 219 | top: 50%; 220 | left: 50%; 221 | transform: translate(-50%, -50%); 222 | } 223 | 224 | 225 | .node-radio { 226 | display: none; 227 | } 228 | .node-radio:checked + .node { 229 | border-right: 3px solid #3485e4; 230 | background-color: rgba(52, 133, 228, 0.12) !important; 231 | } 232 | 233 | 234 | .left-msgs .mid { 235 | margin-left: 12px; 236 | flex-grow: 1; 237 | display: flex; 238 | } 239 | .left-msgs .name { 240 | color: #262626; 241 | font-weight: 600; 242 | position: absolute; 243 | transform: translateY(-100%); 244 | display: flex; 245 | } 246 | .left-msgs .name::before { 247 | content: '@'; 248 | } 249 | .left-msgs .description { 250 | color: #262626; 251 | font-weight: 400; 252 | } 253 | .left * { 254 | user-select: none; 255 | } 256 | 257 | 258 | 259 | 260 | /* right */ 261 | .dmWrapper .right { 262 | flex-grow: 1; 263 | height: 100%; 264 | position: relative; 265 | background-color: white; 266 | z-index: 2; 267 | } 268 | 269 | .dmWrapper .right .no-msg { 270 | width: 100%; 271 | height: 100%; 272 | display: flex; 273 | flex-direction: column; 274 | align-items: center; 275 | justify-content: center; 276 | } 277 | 278 | 279 | 280 | 281 | 282 | /* settings */ 283 | .settings { 284 | position: absolute; 285 | width: 100%; 286 | height: 50px; 287 | top: 0; 288 | left: 0; 289 | background-color: white; 290 | transition: height 0.125s; 291 | opacity: 0; 292 | pointer-events: none; 293 | display: flex; 294 | flex-direction: column; 295 | z-index: 2; 296 | } 297 | .settings.open { 298 | width: 100%; 299 | height: 100%; 300 | opacity: 1; 301 | pointer-events: all; 302 | } 303 | 304 | .settings-body { 305 | flex-shrink: 0; 306 | display: flex; 307 | flex-direction: column; 308 | margin-top: 8px; 309 | } 310 | 311 | .settings-body .option { 312 | display: flex; 313 | padding: 3px 12px; 314 | align-items: center; 315 | white-space: nowrap; 316 | } 317 | .settings-body .option .change-color { 318 | width: 30px; 319 | height: 20px; 320 | margin-left: 8px; 321 | cursor: pointer; 322 | flex-shrink: 0; 323 | } 324 | .settings-body .option input { 325 | margin-left: 8px; 326 | } 327 | 328 | 329 | /* new msg */ 330 | .new-msg-cont { 331 | position: fixed; 332 | top: 0; 333 | left: 0; 334 | z-index: 2000; 335 | width: 100%; 336 | height: 100%; 337 | background-color: rgba(0,0,0,0.5); 338 | font-family: 'IBM Plex Sans',sans-serif; 339 | } 340 | .new-msg { 341 | position: absolute; 342 | width: 400px; 343 | height: 350px; 344 | top: 50%; 345 | left: 50%; 346 | transform: translate(-50%, -50%); 347 | background-color: white; 348 | border-radius: 9px; 349 | border: 1px solid rgba(200,200,200,0.5); 350 | display: flex; 351 | flex-direction: column; 352 | } 353 | .new-msg .top { 354 | width: 100%; 355 | height: 40px; 356 | border-bottom: 1px solid rgba(200,200,200,0.35); 357 | display: flex; 358 | flex-shrink: 0; 359 | justify-content: center; 360 | align-items: center; 361 | } 362 | .new-msg .top .close-new-msg { 363 | position: absolute; 364 | left: 10px; 365 | cursor: pointer; 366 | } 367 | .new-msg .top .close-new-msg svg { 368 | min-width: 11px; 369 | flex-shrink: 0; 370 | } 371 | .new-msg .to, .new-msg .message { 372 | flex-shrink: 0; 373 | display: flex; 374 | padding: 6px 8px; 375 | align-items: center; 376 | justify-content: center; 377 | font-size: 18px; 378 | } 379 | .new-msg .to input, .new-msg .message input { 380 | border: 0!important; 381 | box-shadow: 0!important; 382 | outline: 0 !important; 383 | flex-grow: 1; 384 | padding: 6px; 385 | padding-bottom: 0; 386 | font-size: 16px; 387 | } 388 | .new-msg .to input, .new-msg .message textarea { 389 | resize: none; 390 | flex-grow: 1; 391 | } 392 | .new-msg .to input, .new-msg .message textarea:hover, .new-msg .message textarea:focus, .new-msg .message textarea:active { 393 | outline: 0; 394 | } 395 | .new-msg .to { 396 | border-bottom: 1px solid rgba(200,200,200,0.5); 397 | padding: 12px 8px; 398 | } 399 | .new-msg .to input { 400 | padding-left: 30px; 401 | } 402 | 403 | .new-msg .top .send-new-msg { 404 | color: rgb(0, 149, 246); 405 | position: absolute; 406 | right: 15px; 407 | font-weight: 600; 408 | cursor: pointer; 409 | } 410 | 411 | 412 | /* chat */ 413 | .white-bg .no-msg img { 414 | -webkit-filter: drop-shadow(1px 1px 0 black) 415 | drop-shadow(-1px -1px 0 rgb(219,219,219)); 416 | filter: drop-shadow(1px 1px 0 black) 417 | drop-shadow(-1px -1px 0 rgb(219,219,219)); 418 | } 419 | .white-bg .no-msg span { 420 | color: #19191a !important; 421 | } 422 | 423 | .right .chat { 424 | width: 100%; 425 | height: 100%; 426 | display: flex; 427 | flex-direction: column; 428 | } 429 | .right .chat .top { 430 | width: 100%; 431 | height: 60px; 432 | border-bottom: 1px solid rgb(219,219,219); 433 | background-color: white; 434 | display: flex; 435 | align-items: center; 436 | color: #19191a; 437 | font-weight: 600; 438 | position: relative; 439 | z-index: 2; 440 | } 441 | .chat .top span { 442 | cursor: pointer; 443 | } 444 | .chat .top span::before { 445 | content: '@'; 446 | } 447 | .right .chat .top .chat-img { 448 | width: 30px; 449 | height: 30px; 450 | min-width: 30px; 451 | min-height: 30px; 452 | border-radius: 50%; 453 | overflow: hidden; 454 | position: relative; 455 | margin-right: 8px; 456 | margin-left: 30px; 457 | } 458 | .right .chat .wrapper { 459 | width: 100%; 460 | height: calc(100% - 60px); 461 | display: flex; 462 | flex-direction: column; 463 | } 464 | .right .chat .wrapper .box { 465 | width: 100%; 466 | flex-grow: 1; 467 | display: flex; 468 | flex-direction: column; 469 | overflow-y: scroll; 470 | padding-top: 50px; 471 | font-size: 16px; 472 | padding-bottom: 30px; 473 | } 474 | .small { 475 | font-size: 12px !important; 476 | } 477 | .large { 478 | font-size: 20px !important; 479 | } 480 | 481 | .right .chat .wrapper .box .msg-node { 482 | border-radius: 12px; 483 | padding: 10px; 484 | width: fit-content; 485 | max-width: 280px; 486 | flex-grow: 0; 487 | border: 1px solid rgb(219,219,219); 488 | margin-top: 5px; 489 | position: relative; 490 | min-width: 75px; 491 | } 492 | .right .chat .wrapper .box .msg-node.sent { 493 | margin-left: auto; 494 | margin-right: 8px; 495 | background-color: #0095f6; 496 | color: white; 497 | border-color: #0095f6; 498 | } 499 | .right .chat .wrapper .box .msg-node.received { 500 | margin-left: 8px; 501 | background-color: white; 502 | } 503 | .right .msg-node img { 504 | height: auto; 505 | border: 1px solid rgb(219, 219, 219); 506 | border-radius: 8px; 507 | } 508 | .right .msg-node * { 509 | width: 100%; 510 | word-wrap: break-word; 511 | } 512 | 513 | /* themes */ 514 | 515 | .dmWrapper[theme="green"] .msg-node.sent { 516 | background-color: #44eb7d !important; 517 | border-color: #44eb7d !important; 518 | } 519 | 520 | 521 | .msg-node a { 522 | color: #82cbff; 523 | } 524 | .dmWrapper[theme="green"] .msg-node a { 525 | color: #1a7fc7; 526 | } 527 | 528 | /* /themes */ 529 | 530 | 531 | 532 | .right .chat .wrapper .msg-wrapper { 533 | padding: 10px; 534 | width: calc(100% - 20px); 535 | } 536 | .right .chat .wrapper .msg-wrapper .msg { 537 | border-radius: 15px; 538 | border: 1px solid rgb(219,219,219); 539 | width: calc(100% - 20px); 540 | padding: 6px 10px; 541 | } 542 | .right .chat .wrapper .msg-wrapper .msg:focus { 543 | outline: 0; 544 | } 545 | 546 | 547 | 548 | 549 | /* auth */ 550 | .auth-wrapper { 551 | position: fixed; 552 | top: 0; 553 | left: 0; 554 | z-index: 10000; 555 | width: 100%; 556 | height: 100%; 557 | background-color: rgba(0,0,0,0.25); 558 | display: flex; 559 | align-items: center; 560 | justify-content: center; 561 | } 562 | 563 | .auth-cont { 564 | background-color: white; 565 | padding: 30px 10px; 566 | border-radius: 6px; 567 | display: flex; 568 | align-items: center; 569 | justify-content: center; 570 | position: relative; 571 | flex-direction: column; 572 | max-width: 260px; 573 | user-select: none; 574 | } 575 | 576 | .auth-btn { 577 | cursor: pointer; 578 | background-color: #262b3b; 579 | color: #20ab46; 580 | border-radius: 4px; 581 | padding: 5px 6px; 582 | margin-top: 10px; 583 | user-select: none; 584 | } 585 | .close-auth { 586 | position: absolute; 587 | top: 5px; 588 | left: 5px; 589 | cursor: pointer; 590 | user-select: none; 591 | } 592 | 593 | 594 | /* dupl badge */ 595 | .badge { 596 | height: 30px; 597 | width: fit-content; 598 | position: relative; 599 | flex-shrink: 0; 600 | } 601 | .badge img { 602 | height: 100%; 603 | width: auto; 604 | -webkit-filter: drop-shadow(1px 1px 0 black) 605 | drop-shadow(0px 0px 0 black); 606 | filter: drop-shadow(1px 1px 0 black) 607 | drop-shadow(0px 0px 0 black); 608 | } 609 | 610 | /* loading msgs anim */ 611 | .loading-msgs { 612 | width: 45px; 613 | height: 45px; 614 | position: absolute; 615 | top: 50%; 616 | left: 50%; 617 | transform: translate(-50%, -50%); 618 | } 619 | .loading-msgs img { 620 | height: 100%; 621 | width: auto; 622 | animation: spin 1s infinite linear; 623 | } 624 | @keyframes spin { 625 | 0% { 626 | transform: rotate(0deg); 627 | } 628 | 100% { 629 | transform: rotate(360deg); 630 | } 631 | } 632 | 633 | 634 | /* message read styles */ 635 | .read::before { 636 | content: 'read'; 637 | position: absolute; 638 | color: gray; 639 | bottom: -100%; 640 | font-size: 14px; 641 | bottom: -21px; 642 | text-align: right; 643 | right: 8px; 644 | } 645 | .sent:not(.read)::before { 646 | content: 'delivered'; 647 | position: absolute; 648 | color: gray; 649 | bottom: -100%; 650 | font-size: 14px; 651 | bottom: -21px; 652 | text-align: right; 653 | right: 8px; 654 | } 655 | .right:not(.white-bg) .msg-node::before { 656 | color: white !important; 657 | } 658 | 659 | .box::-webkit-scrollbar { 660 | background: transparent; 661 | } 662 | .box::-webkit-scrollbar-track { 663 | display: none; 664 | } 665 | .box::-webkit-scrollbar-thumb { 666 | background-color: rgba(250,250,250,0.7); 667 | } 668 | .box::-webkit-scrollbar-thumb:hover { 669 | background-color: rgba(250,250,250,0.85); 670 | } 671 | .white-bg .box::-webkit-scrollbar-thumb { 672 | background: #b0b4b8bb; 673 | } 674 | .white-bg .box::-webkit-scrollbar-thumb:hover { 675 | background: #b0b4b8; 676 | } 677 | 678 | .sent + .received { 679 | margin-top: 20px !important; 680 | } 681 | .received + .sent { 682 | margin-top: 20px !important; 683 | } 684 | .read + .sent:not(.read) { 685 | margin-top: 20px !important; 686 | } 687 | 688 | 689 | /* online */ 690 | .node.online::after { 691 | content: ''; 692 | background-color: #0de03e; 693 | width: 13px; 694 | height: 13px; 695 | position: absolute; 696 | border-radius: 50%; 697 | bottom: 15px; 698 | left: 55px; 699 | border: 3px solid white; 700 | } 701 | .node:hover::after { 702 | border: 3px solid white; 703 | } 704 | 705 | 706 | 707 | /* new message icons */ 708 | .node .icons { 709 | display: flex; 710 | position: relative; 711 | align-items: center; 712 | margin-right: 16px; 713 | white-space: nowrap; 714 | font-size: smaller; 715 | } 716 | .node .icons * { 717 | color: #3485e4; 718 | margin-right: 6px; 719 | width: 15px; 720 | max-width: 15px; 721 | min-width: 15px; 722 | } 723 | 724 | .mid[status]::after { 725 | content: attr(status); 726 | color: black; 727 | text-transform: capitalize; 728 | width: fit-content; 729 | font-size: smaller; 730 | } 731 | .node .fa-paper-plane { 732 | transform: rotate(55deg) skewY(10deg); 733 | } 734 | 735 | .node .icons[date]::after { 736 | content: attr(date); 737 | color: black; 738 | text-transform: capitalize; 739 | width: fit-content; 740 | } 741 | .node .icons::before { 742 | content: ''; 743 | background-color: rgba(0,0,0,0.7); 744 | width: 4px; 745 | height: 4px; 746 | border-radius: 50%; 747 | position: absolute; 748 | right: -10px; 749 | } 750 | 751 | .mid:not([status='received']) .received-icon { /* received */ 752 | display: none; 753 | } 754 | .mid:not([status='opened']) .opened-icon { /* received & opened */ 755 | display: none; 756 | } 757 | .mid:not([status='sent']) .sent-icon { /* sent */ 758 | display: none; 759 | } 760 | .mid:not([status='read']) .read-icon { /* sent and read */ 761 | display: none; 762 | } 763 | 764 | 765 | 766 | 767 | /* resizer */ 768 | .resizer { 769 | width: 15px; 770 | background-color: #f6f6f6; 771 | display: flex; 772 | justify-content: center; 773 | align-items: center; 774 | cursor: grab; 775 | z-index: 2; 776 | } 777 | .resizer:active { 778 | cursor: grabbing; 779 | } 780 | .resizer::before { 781 | content: ''; 782 | width: 4px; 783 | height: 50px; 784 | border: 1px solid rgb(209, 208, 208); 785 | border-radius: 4px; 786 | background-color: #dad5d5; 787 | transition: background-color 0.2s; 788 | } 789 | .resizer:hover::before { 790 | background-color: #d4cdcd; 791 | border: 1px solid rgb(209, 202, 202); 792 | } 793 | 794 | 795 | 796 | /* change font size option */ 797 | .change-size { 798 | border: 1px solid black; 799 | width: 30px; 800 | height: 30px; 801 | display: flex; 802 | align-items: center; 803 | justify-content: center; 804 | margin-left: 8px; 805 | cursor: pointer; 806 | flex-shrink: 0; 807 | } 808 | 809 | 810 | 811 | /* now with style */ 812 | .now-with { 813 | position: absolute; 814 | text-align: center; 815 | margin-top: -200px; 816 | animation: grow-shrink 1.5s ease-in-out infinite; 817 | z-index: 10; 818 | margin-left: 150px; 819 | font-weight: 600; 820 | color: black !important; 821 | } 822 | @keyframes grow-shrink { 823 | 0% { 824 | transform: rotate(-10deg) scale(1); 825 | } 826 | 50% { 827 | transform: rotate(-10deg) scale(1.2); 828 | } 829 | 100% { 830 | transform: rotate(-10deg) scale(1); 831 | } 832 | } 833 | 834 | 835 | 836 | /* image drop */ 837 | .chat .wrapper { 838 | position: relative; 839 | } 840 | 841 | .image-drop { 842 | width: 100%; 843 | height: 100%; 844 | background-color: white; 845 | transition: margin-top 0.2s ease-in-out; 846 | z-index: 100; 847 | position: absolute; 848 | display: flex; 849 | justify-content: center; 850 | align-items: center; 851 | } 852 | .image-drop-preview { 853 | width: 80%; 854 | height: 80%; 855 | border: 8px dashed rgb(219,219,219); 856 | display: flex; 857 | align-items: center; 858 | justify-content: center; 859 | color: rgb(201, 201, 201); 860 | font-size: 24px; 861 | } 862 | 863 | .image-drop.active { 864 | margin-top: 0 !important; 865 | } 866 | 867 | 868 | 869 | /* load old msgs */ 870 | .load-old-msgs { 871 | width: 100%; 872 | display: flex; 873 | justify-content: center; 874 | align-items: center; 875 | position: absolute; 876 | margin-top: -30px; 877 | animation: spin linear 1s infinite; 878 | user-select: none; 879 | } 880 | .load-old-msgs * { 881 | width: 16px; 882 | height: 16px; 883 | } 884 | @keyframes spin { 885 | 0% { 886 | transform: rotate(0deg); 887 | } 888 | 100% { 889 | transform: rotate(360deg); 890 | } 891 | } 892 | 893 | 894 | 895 | /* open image full screen */ 896 | .msg-node img { 897 | cursor: pointer; 898 | } 899 | .msg-node .image-check { 900 | display: none; 901 | } 902 | .msg-node label { 903 | transition: all 0.5s; 904 | } 905 | .msg-node .image-check:checked + label { 906 | position: fixed; 907 | top: 0; 908 | left: 0; 909 | display: flex; 910 | height: 100%; 911 | width: 100%; 912 | align-items: center; 913 | justify-content: center; 914 | background-color: rgba(0,0,0,0.4); 915 | z-index: 2000; 916 | } 917 | .msg-node .image-check:checked + label img { 918 | height: 75%; 919 | width: auto; 920 | cursor: default; 921 | } 922 | 923 | 924 | 925 | /* smaller screen widths */ 926 | @media only screen and (max-width: 1000px) { 927 | .dmWrapper { 928 | width: 90%; 929 | } 930 | } 931 | @media only screen and (max-width: 900px) { 932 | .dmWrapper { 933 | width: 95%; 934 | } 935 | } 936 | 937 | 938 | 939 | 940 | --------------------------------------------------------------------------------