├── LICENSE ├── README.md ├── dokumente ├── Ablaufplan.doc ├── Auswertung.xlsx ├── Finalrunde Antwort-Maske.xlsx ├── Fragen.doc ├── Moderationskarten.doc ├── Schilder.doc └── beispiel-fragen.txt ├── server ├── Familien-Duell.url ├── StartServer.bat ├── fragen.txt ├── node.exe ├── node_modules │ ├── .bin │ │ ├── wscat │ │ └── wscat.cmd │ └── ws │ │ ├── .npmignore │ │ ├── .travis.yml │ │ ├── History.md │ │ ├── Makefile │ │ ├── README.md │ │ ├── bench │ │ ├── parser.benchmark.js │ │ ├── sender.benchmark.js │ │ ├── speed.js │ │ └── util.js │ │ ├── binding.gyp │ │ ├── builderror.log │ │ ├── doc │ │ └── ws.md │ │ ├── index.js │ │ ├── lib │ │ ├── BufferPool.js │ │ ├── BufferUtil.fallback.js │ │ ├── BufferUtil.js │ │ ├── ErrorCodes.js │ │ ├── Receiver.hixie.js │ │ ├── Receiver.js │ │ ├── Sender.hixie.js │ │ ├── Sender.js │ │ ├── Validation.fallback.js │ │ ├── Validation.js │ │ ├── WebSocket.js │ │ ├── WebSocketServer.js │ │ └── browser.js │ │ ├── node_modules │ │ ├── commander │ │ │ ├── .npmignore │ │ │ ├── .travis.yml │ │ │ ├── History.md │ │ │ ├── Makefile │ │ │ ├── Readme.md │ │ │ ├── index.js │ │ │ ├── lib │ │ │ │ └── commander.js │ │ │ └── package.json │ │ ├── options │ │ │ ├── .npmignore │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── lib │ │ │ │ └── options.js │ │ │ ├── package.json │ │ │ └── test │ │ │ │ ├── fixtures │ │ │ │ └── test.conf │ │ │ │ └── options.test.js │ │ └── tinycolor │ │ │ ├── .npmignore │ │ │ ├── README.md │ │ │ ├── example.js │ │ │ ├── package.json │ │ │ └── tinycolor.js │ │ ├── package.json │ │ └── src │ │ ├── bufferutil.cc │ │ └── validation.cc ├── server.js └── server.py └── web ├── css ├── bootstrap.min.css ├── font-awesome.min.css ├── jquery.dataTables.css └── main.css ├── fonts ├── FontAwesome.otf ├── fontawesome-webfont.eot ├── fontawesome-webfont.svg ├── fontawesome-webfont.ttf ├── fontawesome-webfont.woff ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf └── glyphicons-halflings-regular.woff ├── img ├── background.jpg ├── logo.png ├── noSound.png ├── notConnected.png ├── schweinchen1.png ├── schweinchen2.png ├── schweinchen3.png └── soundOn.png ├── index.html ├── js ├── components.js ├── jquery-ui-1.10.4.min.js ├── jquery.min.js ├── jquery.min.map ├── main.js ├── typed.js └── websocket.js └── sounds ├── fail.ogg ├── failOrginal.ogg ├── failOriginal.ogg ├── failfinal.ogg ├── intro.ogg ├── schweinchen.ogg ├── textRichtig.ogg └── zahlRichtig.ogg /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cracker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Familienduell 2 | 3 | ![logo](./web/img/logo.png) 4 | 5 | Familienduell Client / Server (NodeJs Javascript) 6 | 7 | ### -A- START DES SERVERS! 8 | 9 | ___Windows___ 10 | 1. Im Ordner "server" die Datei StartServer.bat doppelklicken. 11 | * Im Fenster das jetzt erscheint sollte: "SERVER IS UP AND RUNNING" stehen. 12 | * Falls die Firewall fragt, solltest du die Anfrage zulassen da sonst der Client nicht verbinden kann. 13 | 14 | ___Mac___ 15 | 16 | 1. Installiere NodeJs und npm (https://nodejs.org/en/download/) 17 | 18 | 2. starte die (mac) konsole und wechsle in den Serverordner 19 | 20 | 3. installiere das Websocketmodul (ws) 21 | `npm install ws` 22 | 23 | 4. Starte den Server 24 | `node server.js` 25 | 26 | 5. In der Console erscheint: "SERVER IS UP AND RUNNING" 27 | 28 | ### -B- START DES CONTROLLERS! 29 | 30 | 1. Browser öffnen und zur Adresse: http://127.0.0.1:8080 surfen 31 | 32 | 2. Auf den Controller Button klicken. 33 | 34 | ### -C- Start des Displays 35 | 36 | 1. In einem neuen Browserfenster/tab verbinden und auf "Display" klicken. 37 | 38 | 39 | --------------------------- 40 | 41 | ### FAQs: 42 | Q: Warum ist das Display zu Beginn schwarz, und wie kann ich das ändern? 43 | A: Das Bild ist schwarz damit man die Intromusik starten kann und die Leute (Zuschauer) nicht schon vorher wissen was auf sie zukommt. 44 | Dies kann (Im Controller) über die Checkbox "Blackscreen", im Bereich "Intro" kontrolliert werden. 45 | 46 | Q: Warum bekomm ich die Fehlermeldung "node.exe wurde falsch geschrieben oder konnte nicht gefunden werden"?
47 | A: Die heruntergeladene zip Datei muss zunächst entpack werden. Rechtsklick auf die Datei -> Alles etpacken. 48 | 49 | Q: Wie funktioniert das mit 2 oder mehr Geräten? 50 | A: Alle Geräte müssen im gleichen Netzwerk sein. Dann verwende einfach eine Externe IP des Servers (aus dem Serverfenster) zum verbinden von einem anderen Gerät aus. 51 | 52 | Q: Läuft der Server mit nodeJs auch unter Linux / Läuft der Python Server auch unter Windows? 53 | A: Ja, dafür müssen jedoch zunächst die etsprechenden Abhänigkeiten installiert werden. 54 | 55 | Q: Gibt es eine Funktion um Leuten über einen Link direkt das Zuschauen zu ermöglichen? 56 | A: Ja. Der Link lautet: http://SERVERURL/PFAD/index.html?viewonly=true (SERVERURL und PFAD anpassen!) 57 | 58 | Q: Ich erhalten im Serverfenster den Fehler: Error: listen EADDRINUSE 59 | A: Eine andere Anwendung blockiert bereits den Port. Beende diese und starte den Server erneut 60 | 61 | Q: Ich habe sonstige Fehler bei (Anzeige, Verbindungsaufbau, Anwendungsverhalten) 62 | A: Falls du einen anderen Browser als Google Chrome verwendest, installiere Chrome. 63 | 64 | Sonstige Fragen, Fehlermeldungen, Beschwerden oder auch Spenden (Paypal) per Mail an: raphael.fritsch@gmx.de 65 | 66 | --------------------------- 67 | 68 | Programmierung: cracker 69 | Unterstützt durch: DiggerTigger, Anni & Naseile 70 | 71 | Danke auch an: 72 | * [flbe](https://github.com/flbe) für den Python Server 73 | * [susgo](https://github.com/susgo) für den Finalmodus 74 | * [ConvalAtGit](https://github.com/ConvalAtGit) für viele Verbesserungen, Redesign und zusätzliche Word und Excel Dokumente 75 | * [fruitcoder](https://github.com/fruitcoder/) Design verbesserungen 76 | -------------------------------------------------------------------------------- /dokumente/Ablaufplan.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/dokumente/Ablaufplan.doc -------------------------------------------------------------------------------- /dokumente/Auswertung.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/dokumente/Auswertung.xlsx -------------------------------------------------------------------------------- /dokumente/Finalrunde Antwort-Maske.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/dokumente/Finalrunde Antwort-Maske.xlsx -------------------------------------------------------------------------------- /dokumente/Fragen.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/dokumente/Fragen.doc -------------------------------------------------------------------------------- /dokumente/Moderationskarten.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/dokumente/Moderationskarten.doc -------------------------------------------------------------------------------- /dokumente/Schilder.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/dokumente/Schilder.doc -------------------------------------------------------------------------------- /dokumente/beispiel-fragen.txt: -------------------------------------------------------------------------------- 1 | JTVCJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBlaW4lMjBNJUMzJUE0cmNoZW4lMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyTSVDMyVBNHJjaGVuJTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMlNjaG5lZXdpdHRjaGVuJTIyJTJDJTIyYW56JTIyJTNBJTIyMzklMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIySCVDMyVBNG5zZWwlMjB1bmQlMjBHcmV0ZWwlMjIlMkMlMjJhbnolMjIlM0ElMjIyNyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJSb3RrJUMzJUE0cHBjaGVuJTIyJTJDJTIyYW56JTIyJTNBJTIyMTIlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyUmFwdW56ZWwlMjIlMkMlMjJhbnolMjIlM0ElMjIxMCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJEb3JuciVDMyVCNnNjaGVuJTIyJTJDJTIyYW56JTIyJTNBJTIyNyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjIlMjIlMkMlMjJhbnolMjIlM0ElMjIlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lbiUyMFNpZSUyMGVpbiUyMHN0cm9tYmV0cmllYmVuZXMlMjBLJUMzJUJDY2hlbmdlciVDMyVBNHQlMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyU3Ryb21rJUMzJUJDY2hlbmdlciVDMyVBNHQlMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyTWl4ZXIlMjIlMkMlMjJhbnolMjIlM0ElMjIzOCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJLYWZmZWVtYXNjaGluZSUyMiUyQyUyMmFueiUyMiUzQSUyMjIyJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkslQzMlQkNobHNjaHJhbmslMjIlMkMlMjJhbnolMjIlM0ElMjIxOCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJNaWtyb3dlbGxlJTIyJTJDJTIyYW56JTIyJTNBJTIyOSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJUb2FzdGVyJTIyJTJDJTIyYW56JTIyJTNBJTIyOCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJXYWZmZWxlaXNlbiUyMiUyQyUyMmFueiUyMiUzQSUyMjUlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lbiUyMFNpZSUyMGVpbiUyMFRpZXIlMkMlMjBkYXMlMjBtaXQlMjBBJTIwYmVnaW5udCUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJUaWVyJTIwbWl0JTIwQSUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJBZmZlJTIyJTJDJTIyYW56JTIyJTNBJTIyNDMlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQW1laXNlJTIyJTJDJTIyYW56JTIyJTNBJTIyMjUlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQWFsJTIyJTJDJTIyYW56JTIyJTNBJTIyMTYlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQW5ha29uZGElMjIlMkMlMjJhbnolMjIlM0ElMjIxMCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJBbXNlbCUyMiUyQyUyMmFueiUyMiUzQSUyMjQlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQWRsZXIlMjIlMkMlMjJhbnolMjIlM0ElMjIyJTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBlaW4lMjBBbGtvaG9sZnJlaWVzJTIwR2V0ciVDMyVBNG5rJTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMkFsa29ob2xmcmVpZXMlMjBHZXRyJUMzJUE0bmslMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQ29sYSUyMiUyQyUyMmFueiUyMiUzQSUyMjM5JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMldhc3NlciUyMiUyQyUyMmFueiUyMiUzQSUyMjI1JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlNhZnQlMjIlMkMlMjJhbnolMjIlM0ElMjIxNiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjIoRWlzLSlUZWUlMjIlMkMlMjJhbnolMjIlM0ElMjIxMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJLYWZmZSUyMiUyQyUyMmFueiUyMiUzQSUyMjUlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyTGltb25hZGUlMjIlMkMlMjJhbnolMjIlM0ElMjIzJTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBlaW5lbiUyMHBlcmZla3RlbiUyME9ydCUyMGYlQzMlQkNyJTIwZWluJTIwcm9tYW50aXNjaGVzJTIwRXNzZW4uJTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMnJvbWFudGlzY2hlcyUyMEVzc2VuJTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMlJlc3RhdXJhbnQlMjIlMkMlMjJhbnolMjIlM0ElMjIzNiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJXYXNzZXIlMjAoU2VlJTJDJTIwTWVlciUyQyUyMFN0cmFuZCklMjIlMkMlMjJhbnolMjIlM0ElMjIzMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJadWhhdXNlJTIwJTJGJTIwS2FtaW4lMjIlMkMlMjJhbnolMjIlM0ElMjIxNSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJCYWxrb24lMjAlMkYlMjBUZXJhc3NlJTIyJTJDJTIyYW56JTIyJTNBJTIyOCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJHYXJ0ZW4lMjIlMkMlMjJhbnolMjIlM0ElMjI1JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlBhcmlzJTIyJTJDJTIyYW56JTIyJTNBJTIyNCUyMiU3RCU1RCU3RCUyQyU3QiUyMmZyYWdlJTIyJTNBJTIyTmVubmVuJTIwU2llJTIwZXR3YXMlMkMlMjBkYXMlMjBtYW4lMjBpbW1lciUyMGJlaSUyMHNpY2glMjB0ciVDMyVBNGd0JTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMmJlaSUyMHNpY2glMjB0ciVDMyVBNGd0JTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMkhhbmR5JTIwJTJGJTIwU21hcnRwaG9uZSUyMiUyQyUyMmFueiUyMiUzQSUyMjI4JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlBvcnRtb25lZSUyMiUyQyUyMmFueiUyMiUzQSUyMjIyJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMihBcm1iYW5kLSlVaHIlMjIlMkMlMjJhbnolMjIlM0ElMjIxNiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTY2hsJUMzJUJDc3NlbCUyMiUyQyUyMmFueiUyMiUzQSUyMjE0JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMktsZWlkdW5nJTIyJTJDJTIyYW56JTIyJTNBJTIyMTIlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyU2NobXVjayUyMiUyQyUyMmFueiUyMiUzQSUyMjglMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lbiUyMFNpZSUyMGVpbiUyMExpZWQlMkMlMjBkYXMlMjBqZWRlciUyMEtlbm50JTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMkxpZWQlMjBqZWRlciUyMGtlbm50JTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMkFsbGUlMjBtZWluZSUyMEVudGNoZW4lMjIlMkMlMjJhbnolMjIlM0ElMjI0MyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJIYXBweSUyMEJpcnRoZGF5JTIyJTJDJTIyYW56JTIyJTNBJTIyMjElMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyTmF0aW9uYWxoeW1uZSUyMiUyQyUyMmFueiUyMiUzQSUyMjE1JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkglQzMlQTRuc2NoZW4lMjBrbGVpbiUyMiUyQyUyMmFueiUyMiUzQSUyMjExJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMk8lMjBUYW5uZW5iYXVtJTIyJTJDJTIyYW56JTIyJTNBJTIyNyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJCcnVkZXIlMjBKYWtvYiUyMiUyQyUyMmFueiUyMiUzQSUyMjMlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lbiUyMFNpZSUyMGVpbiUyMGdlZiVDMyVBNGhybGljaGVzJTIwVGllciUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJnZWYlQzMlQTRocmxpY2hlcyUyMFRpZXIlMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyTCVDMyVCNndlJTIyJTJDJTIyYW56JTIyJTNBJTIyMzglMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyVGlnZXIlMjIlMkMlMjJhbnolMjIlM0ElMjIyNSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJLcm9rb2RpbCUyMiUyQyUyMmFueiUyMiUzQSUyMjE3JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkhhaWZpc2NoJTIyJTJDJTIyYW56JTIyJTNBJTIyOSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTY2hsYW5nZSUyMiUyQyUyMmFueiUyMiUzQSUyMjYlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQiVDMyVBNHIlMjIlMkMlMjJhbnolMjIlM0ElMjI1JTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBlaW5lbiUyMEtpbmRlcnRyYXVtYmVydWYlMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyS2luZGVydHJhdW1iZXJ1ZiUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJGZXVlcndlaHJtYW5uJTIyJTJDJTIyYW56JTIyJTNBJTIyMzQlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyVGllcmFyenQlMjIlMkMlMjJhbnolMjIlM0ElMjIyNSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJQaWxvdCUyMiUyQyUyMmFueiUyMiUzQSUyMjE2JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlMlQzMlQTRuZ2VyJTJGU3RhciUyMiUyQyUyMmFueiUyMiUzQSUyMjExJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkxva2YlQzMlQkNocmVyJTIyJTJDJTIyYW56JTIyJTNBJTIyOSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJBc3Ryb25hdXQlMjIlMkMlMjJhbnolMjIlM0ElMjI1JTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBlaW5lJTIwRnJlaXplaXRha3Rpdml0JUMzJUE0dCUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJGcmVpemVpdGFrdGl2aXQlQzMlQTR0JTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMlNwb3J0JTIyJTJDJTIyYW56JTIyJTNBJTIyMzUlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyTGVzZW4lMjIlMkMlMjJhbnolMjIlM0ElMjIzMSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJNdXNpayUyMiUyQyUyMmFueiUyMiUzQSUyMjE2JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlNwaWVsZW4lMjAlMkYlMjBab2NrZW4lMjIlMkMlMjJhbnolMjIlM0ElMjI4JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMktpbm8lMjAlMkYlMjBUViUyMCUyRiUyMEZpbG0lMjIlMkMlMjJhbnolMjIlM0ElMjI3JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMldhbmRlcm4lMjAlMkYlMjBTcGF6aWVyZW4lMjIlMkMlMjJhbnolMjIlM0ElMjIzJTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBlaW5lbiUyMHdlaSVDMyU5RmVuJTIwVm9nZWwlMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyd2VpJUMzJTlGZXIlMjBWb2dlbCUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJUYXViZSUyMiUyQyUyMmFueiUyMiUzQSUyMjMyJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMk0lQzMlQjZ3ZSUyMiUyQyUyMmFueiUyMiUzQSUyMjI2JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlNjaHdhbiUyMiUyQyUyMmFueiUyMiUzQSUyMjIyJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMktha2FkdSUyMiUyQyUyMmFueiUyMiUzQSUyMjEwJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkdhbnMlMjIlMkMlMjJhbnolMjIlM0ElMjI2JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlBlbGlrYW4lMjIlMkMlMjJhbnolMjIlM0ElMjI0JTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZSUyMGVpbmVuJTIwYW1lcmlrYW5pc2NoZW4lMjBCdW5kZXNzdGFhdCUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJCdW5kZXNzdGFhdCUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJUZXhhcyUyMiUyQyUyMmFueiUyMiUzQSUyMjMzJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkZsb3JpZGElMjIlMkMlMjJhbnolMjIlM0ElMjIyMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJOZXclMjBZb3JrJTIyJTJDJTIyYW56JTIyJTNBJTIyMTYlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyS2FsaWZvcm5pZW4lMjIlMkMlMjJhbnolMjIlM0ElMjIxMyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJPaGlvJTIyJTJDJTIyYW56JTIyJTNBJTIyMTAlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyV2FzaGluZ3RvbiUyMiUyQyUyMmFueiUyMiUzQSUyMjYlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lbiUyMFNpZSUyMGV0d2FzJTJDJTIwZGFzcyUyMG1hbiUyMGFuJTIwZWluZW4lMjBGZXJuc2VoZXIlMjBhbnNjaGxpZSVDMyU5RnQlMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyRmVybnNlaGVyJTIwYW5zY2hsaWUlQzMlOUZ0JTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMkRWRC1QbGF5ZXIlMjIlMkMlMjJhbnolMjIlM0ElMjIzOCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTcGllbGVrb25zb2xlJTIyJTJDJTIyYW56JTIyJTNBJTIyMjElMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyUmVjZWl2ZXIlMjIlMkMlMjJhbnolMjIlM0ElMjIxNSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJMYXB0b3AlMjIlMkMlMjJhbnolMjIlM0ElMjIxMSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJVU0ItU3RpY2slMjIlMkMlMjJhbnolMjIlM0ElMjI4JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkthbWVyYSUyMiUyQyUyMmFueiUyMiUzQSUyMjclMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lbiUyMFNpZSUyMGVpbmVuJTIwRGlzbmV5ZmlsbSUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJEaXNuZXlmaWxtJTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMkRlciUyMEslQzMlQjZuaWclMjBkZXIlMjBMJUMzJUI2d2VuJTIyJTJDJTIyYW56JTIyJTNBJTIyMzYlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQmFtYmklMjIlMkMlMjJhbnolMjIlM0ElMjIyMSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJEYXMlMjBEc2NodW5nZWxidWNoJTIyJTJDJTIyYW56JTIyJTNBJTIyMTglMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQXJpZWxsZSUyMiUyQyUyMmFueiUyMiUzQSUyMjE0JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkFsYWRkaW4lMjIlMkMlMjJhbnolMjIlM0ElMjI3JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkRpZSUyMFNjaCVDMyVCNm5lJTIwdW5kJTIwZGFzJTIwQmllc3QlMjIlMkMlMjJhbnolMjIlM0ElMjI0JTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBlaW4lMjBUaWVyJTJDJTIwZGFzJTIwYXVmJTIwZGVtJTIwQmF1ZXJuaG9mJTIwbGVidCUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJUaWVyJTIwYXVmJTIwQmF1ZXJuaG9mJTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMkt1aCUyMiUyQyUyMmFueiUyMiUzQSUyMjU4JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlNjaHdlaW4lMjIlMkMlMjJhbnolMjIlM0ElMjIxOSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJIYWhuJTJGSHVobiUyMiUyQyUyMmFueiUyMiUzQSUyMjE0JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlBmZXJkJTIyJTJDJTIyYW56JTIyJTNBJTIyNCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJIdW5kJTIyJTJDJTIyYW56JTIyJTNBJTIyMyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJLYXR6ZSUyMiUyQyUyMmFueiUyMiUzQSUyMjIlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lJTIwZXR3YXMlMkMlMjB3b21pdCUyMG1hbiUyMHNjaHJlaWJlbiUyMGthbm4lMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyU2NocmVpYmVuJTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMkt1Z2Vsc2NocmVpYmVyJTIyJTJDJTIyYW56JTIyJTNBJTIyMzklMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyRiVDMyVCQ2xsZmVkZXIlMjIlMkMlMjJhbnolMjIlM0ElMjIyMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJCbGVpc3RpZnQlMjIlMkMlMjJhbnolMjIlM0ElMjIxNCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJDb21wdXRlciUyMiUyQyUyMmFueiUyMiUzQSUyMjE0JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlNjaHJlaWJtYXNjaGluZSUyMiUyQyUyMmFueiUyMiUzQSUyMjYlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyS3JlaWRlJTIyJTJDJTIyYW56JTIyJTNBJTIyNSUyMiU3RCU1RCU3RCUyQyU3QiUyMmZyYWdlJTIyJTNBJTIyTmVubmVuJTIwU2llJTIwZWluZSUyMGJlbGllYnRlJTIwRWlzc29ydGUlMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyRWlzc29ydGUlMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyVmFuaWxsZSUyMiUyQyUyMmFueiUyMiUzQSUyMjQwJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlNjaG9ja29sYWRlJTIyJTJDJTIyYW56JTIyJTNBJTIyMzElMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyRXJkYmVlcmUlMjIlMkMlMjJhbnolMjIlM0ElMjIxMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTdHJhY2NpYXRlbGxhJTIyJTJDJTIyYW56JTIyJTNBJTIyNyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJaaXRyb25lJTIyJTJDJTIyYW56JTIyJTNBJTIyNiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJQaXN0YXppZSUyMiUyQyUyMmFueiUyMiUzQSUyMjQlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lJTIwZXR3YXMlMkMlMjBkYXMlMjBtYW4lMjBuaWNodCUyMHZlcmxpZXJlbiUyMHNvbGx0ZSUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJuaWNodCUyMHZlcmxpZXJlbiUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJTY2hsJUMzJUJDc3NlbCUyMiUyQyUyMmFueiUyMiUzQSUyMjMzJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkdlbGQlMjIlMkMlMjJhbnolMjIlM0ElMjIyNSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJBdXN3ZWlzJTIwJTJGJTIwUGFzcyUyMiUyQyUyMmFueiUyMiUzQSUyMjE3JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMktvcGYlMjIlMkMlMjJhbnolMjIlM0ElMjIxMyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJHdXRlJTIwTGF1bmUlMjIlMkMlMjJhbnolMjIlM0ElMjI3JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMk5lcnZlbiUyMiUyQyUyMmFueiUyMiUzQSUyMjUlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lbiUyMFNpZSUyMGVpbiUyMFZlcmtlaHJzbWl0dGVsJTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMlZlcmtlaHJzbWl0dGVsJTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMkF1dG8lMjIlMkMlMjJhbnolMjIlM0ElMjIzOCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJCdXMlMjIlMkMlMjJhbnolMjIlM0ElMjIyMSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJGYWhycmFkJTIyJTJDJTIyYW56JTIyJTNBJTIyMTUlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyWnVnJTIyJTJDJTIyYW56JTIyJTNBJTIyMTIlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyU3RyYSVDMyU5RmVuLSUyRlUtQmFobiUyMiUyQyUyMmFueiUyMiUzQSUyMjglMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyRmx1Z3pldWclMjIlMkMlMjJhbnolMjIlM0ElMjI2JTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBldHdhcyUyQyUyMGRhcyUyMGluJTIwa2VpbmVtJTIwUGlja25pY2trb3JiJTIwZmVobGVuJTIwc29sbHRlJTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMlBpY2tuaWNra29yYiUyMCUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJHZXNjaGlyciUyMiUyQyUyMmFueiUyMiUzQSUyMjI2JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkJyb3QlMjIlMkMlMjJhbnolMjIlM0ElMjIyNSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJPYnN0JTIyJTJDJTIyYW56JTIyJTNBJTIyMTclMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQmVzdGVjayUyMiUyQyUyMmFueiUyMiUzQSUyMjE1JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkslQzMlQTRzZSUyMiUyQyUyMmFueiUyMiUzQSUyMjEwJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMldlaW4lMjIlMkMlMjJhbnolMjIlM0ElMjI3JTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBlaW5lJTIwU3BvcnRhcnQlMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyU3BvcnRhcnQlMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyRnUlQzMlOUZiYWxsJTIyJTJDJTIyYW56JTIyJTNBJTIyNDIlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyU2Nod2ltbWVuJTIyJTJDJTIyYW56JTIyJTNBJTIyMjQlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQmFza2V0YmFsbCUyMiUyQyUyMmFueiUyMiUzQSUyMjE0JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkhhbmRiYWxsJTIyJTJDJTIyYW56JTIyJTNBJTIyOSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJSYWRmYWhyZW4lMjIlMkMlMjJhbnolMjIlM0ElMjI4JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkVpc2hvY2tleSUyMiUyQyUyMmFueiUyMiUzQSUyMjMlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lbiUyMFNpZSUyMGVpbiUyMFNjaHVsZmFjaCUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJTY2h1bGZhY2glMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyTWF0aGUlMjIlMkMlMjJhbnolMjIlM0ElMjI0NiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJEZXV0c2NoJTIyJTJDJTIyYW56JTIyJTNBJTIyMTglMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyRW5nbGlzY2glMjIlMkMlMjJhbnolMjIlM0ElMjIxNSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJFcmRrdW5kZSUyMiUyQyUyMmFueiUyMiUzQSUyMjExJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlNwb3J0JTIyJTJDJTIyYW56JTIyJTNBJTIyNyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJDaGVtaWUlMjIlMkMlMjJhbnolMjIlM0ElMjIzJTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5uZW4lMjBTaWUlMjBlaW5lJTIwSGFhcmZhcmJlJTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMkhhYXJmYXJiZSUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJCbG9uZCUyMiUyQyUyMmFueiUyMiUzQSUyMjU5JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlJvdCUyMiUyQyUyMmFueiUyMiUzQSUyMjE1JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkJyYXVuJTIyJTJDJTIyYW56JTIyJTNBJTIyMTQlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQnIlQzMlQkNuZXR0JTIyJTJDJTIyYW56JTIyJTNBJTIyNyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTY2h3YXJ6JTIyJTJDJTIyYW56JTIyJTNBJTIyNCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJCbGF1JTIyJTJDJTIyYW56JTIyJTNBJTIyMSUyMiU3RCU1RCU3RCUyQyU3QiUyMmZyYWdlJTIyJTNBJTIyTmVubmVuJTIwU2llJTIwZWluZSUyMEF1Z2VuZmFyYmUlMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyQXVnZW5mYXJiZSUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJCbGF1JTIyJTJDJTIyYW56JTIyJTNBJTIyNjElMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyR3IlQzMlQkNuJTIyJTJDJTIyYW56JTIyJTNBJTIyMjAlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyQnJhdW4lMjIlMkMlMjJhbnolMjIlM0ElMjIxNiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJHcmF1JTIyJTJDJTIyYW56JTIyJTNBJTIyMSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJHcmF1YmxhdSUyMiUyQyUyMmFueiUyMiUzQSUyMjElMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyVmlvbGV0dCUyMiUyQyUyMmFueiUyMiUzQSUyMjElMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm5lbiUyMFNpZSUyMGVpbiUyMEtsZWlkdW5nc3N0JUMzJUJDY2slMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyS2xlaWR1bmdzc3QlQzMlQkNjayUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJIb3NlJTIyJTJDJTIyYW56JTIyJTNBJTIyNDIlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyVC1TaGlydCUyMiUyQyUyMmFueiUyMiUzQSUyMjI1JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkphY2tlJTIyJTJDJTIyYW56JTIyJTNBJTIyMTElMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIySmVhbnMlMjIlMkMlMjJhbnolMjIlM0ElMjI5JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlVudGVydyVDMyVBNHNjaGUlMjIlMkMlMjJhbnolMjIlM0ElMjI3JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkhlbWQlMjAlMkZQdWxsb3ZlciUyMiUyQyUyMmFueiUyMiUzQSUyMjYlMjIlN0QlNUQlN0QlNUQ= -------------------------------------------------------------------------------- /server/Familien-Duell.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://127.0.0.1:8080/ 3 | -------------------------------------------------------------------------------- /server/StartServer.bat: -------------------------------------------------------------------------------- 1 | node.exe server.js 2 | pause -------------------------------------------------------------------------------- /server/fragen.txt: -------------------------------------------------------------------------------- 1 | JTVCJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5udCUyMGVpbmUlMjBBa3Rpdml0JUMzJUE0dCUyQyUyMGRpZSUyMGRpZSUyMGJlaWRlbiUyMHp1c2FtbWVuJTIwbWFjaGVuJTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMkZyZWl6ZWl0YWt0aXZpdCVDMyVBNHQlMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyRmVybnNlaCUyMGd1Y2tlbiUyMiUyQyUyMmFueiUyMiUzQSUyMjklMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyUmVpc2VuJTIyJTJDJTIyYW56JTIyJTNBJTIyNyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTcG9ydCUyMiUyQyUyMmFueiUyMiUzQSUyMjYlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyU2V4JTIyJTJDJTIyYW56JTIyJTNBJTIyNSUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJFc3NlbiUyMGdlaGVuJTIyJTJDJTIyYW56JTIyJTNBJTIyNCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTYXVuYSUyMiUyQyUyMmFueiUyMiUzQSUyMjMlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm50JTIwZXR3YXMlMkMlMjB3YXMlMjBlciUyMHJlZ2VsbSVDMyVBNCVDMyU5RmlnJTIwaW0lMjBIYXVzaGFsdCUyMG1hY2h0JTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMkhhdXNoYWx0c2F1ZmdhYmUlMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyU3RhdWJzYXVnZW4lMjIlMkMlMjJhbnolMjIlM0ElMjIxMyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJNJUMzJUJDbGwlMjByYXVzYnJpbmdlbiUyMiUyQyUyMmFueiUyMiUzQSUyMjglMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyTmljaHRzJTIyJTJDJTIyYW56JTIyJTNBJTIyNyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJEcmVjayUyMiUyQyUyMmFueiUyMiUzQSUyMjMlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyU3AlQzMlQkNsZW4lMjIlMkMlMjJhbnolMjIlM0ElMjIzJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMiUyMiUyQyUyMmFueiUyMiUzQSUyMiUyMiU3RCU1RCU3RCUyQyU3QiUyMmZyYWdlJTIyJTNBJTIyTmVubnQlMjBlaW4lMjBMYW5kJTJDJTIwaW4lMjBkZW0lMjBkaWUlMjBiZWlkZW4lMjBpbSUyMFVybGF1YiUyMHdhcmVuJTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMlVybGF1YnNsYW5kJTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMkt1YmElMjIlMkMlMjJhbnolMjIlM0ElMjIyMCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTcGFuaWVuJTIyJTJDJTIyYW56JTIyJTNBJTIyOCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJEZXV0c2NobGFuZCUyMiUyQyUyMmFueiUyMiUzQSUyMjQlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyR3JpZWNoZW5sYW5kJTIyJTJDJTIyYW56JTIyJTNBJTIyMyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjIlMjIlMkMlMjJhbnolMjIlM0ElMjIlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyJTIyJTJDJTIyYW56JTIyJTNBJTIyJTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5udCUyMGVpbmUlMjBGZXJuc2Voc2VyaWUlMkMlMjBkaWUlMjBkaWUlMjBCcmF1dCUyMGdlcm5lJTIwbWFnJTIyJTJDJTIya3VlcnplbCUyMiUzQSUyMkxpZWJsaW5nc3NlcmllJTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMkdyZXkncyUyMEFuYXRvbXklMjIlMkMlMjJhbnolMjIlM0ElMjI5JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkdaU1olMjIlMkMlMjJhbnolMjIlM0ElMjI1JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlZlcmJvdGVuZSUyMExpZWJlJTIyJTJDJTIyYW56JTIyJTNBJTIyMyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJHYW1lJTIwb2YlMjBUaHJvbmVzJTIyJTJDJTIyYW56JTIyJTNBJTIyMyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTZXglMjBhbmQlMjB0aGUlMjBDaXR5JTIyJTJDJTIyYW56JTIyJTNBJTIyMyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJPLkMuJTIwQ2FsaWZvcm5pYSUyMiUyQyUyMmFueiUyMiUzQSUyMjMlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm50JTIwZWluZW4lMjBTcGllbGZpbG0lMkMlMjBkZXIlMjB6dSUyMHNlaW5lbSUyMGxpZWJzdGVuJTIwZ2VoJUMzJUI2cnQlMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyTGllYmxpbmdzZmlsbSUyMiUyQyUyMmFudHdvcnRlbiUyMiUzQSU1QiU3QiUyMmFudHdvcnQlMjIlM0ElMjJTdGFyV2FycyUyMiUyQyUyMmFueiUyMiUzQSUyMjclMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyU3RpcmIlMjBMYW5nc2FtJTIyJTJDJTIyYW56JTIyJTNBJTIyMyUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJUaXRhbmljJTIyJTJDJTIyYW56JTIyJTNBJTIyMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJEYXMlMjBmbGllZ2VuZGUlMjBLbGFzc2VuemltbWVyJTIyJTJDJTIyYW56JTIyJTNBJTIyMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJUZXJtaW5hdG9yJTIyJTJDJTIyYW56JTIyJTNBJTIyMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTdGFyJTIwVHJlayUyMiUyQyUyMmFueiUyMiUzQSUyMjElMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm50JTIwZXR3YXMlMkMlMjB3b2YlQzMlQkNyJTIwZGllJTIwYmVpZGVuJTIwZ2VybiUyMEdlbGQlMjBhdXNnZWJlbiUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJHZWxkJTIwYXVzZ2ViZW4lMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyVXJsYXViJTIyJTJDJTIyYW56JTIyJTNBJTIyMTMlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyRXNzZW4lMjBnZWhlbiUyMiUyQyUyMmFueiUyMiUzQSUyMjclMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIySyVDMyVCNmxzY2glMjIlMkMlMjJhbnolMjIlM0ElMjI0JTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkhvY2h6ZWl0JTIyJTJDJTIyYW56JTIyJTNBJTIyNCUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJSZWlzZW4lMjIlMkMlMjJhbnolMjIlM0ElMjIzJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMktpbm8lMjIlMkMlMjJhbnolMjIlM0ElMjIyJTIyJTdEJTVEJTdEJTJDJTdCJTIyZnJhZ2UlMjIlM0ElMjJOZW5udCUyMGV0d2FzJTJDJTIwd2FzJTIwZXIlMjBhdWYlMjBkZW0lMjBSJUMzJUJDY2tlbiUyMGxpZWdlbmQlMjBtYWNodCUyMiUyQyUyMmt1ZXJ6ZWwlMjIlM0ElMjJSJUMzJUJDY2tlbiUyMGxpZWdlbmQlMjIlMkMlMjJhbnR3b3J0ZW4lMjIlM0ElNUIlN0IlMjJhbnR3b3J0JTIyJTNBJTIyU2NobGFmZW4lMjIlMkMlMjJhbnolMjIlM0ElMjIyMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTaXQtdXBzJTIyJTJDJTIyYW56JTIyJTNBJTIyNiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJTZXglMjIlMkMlMjJhbnolMjIlM0ElMjIzJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMllvZ2ElMjIlMkMlMjJhbnolMjIlM0ElMjIyJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkZhdWxlbnplbiUyMiUyQyUyMmFueiUyMiUzQSUyMjIlMjIlN0QlMkMlN0IlMjJhbnR3b3J0JTIyJTNBJTIyTmFjaGRlbmtlbiUyMiUyQyUyMmFueiUyMiUzQSUyMjIlMjIlN0QlNUQlN0QlMkMlN0IlMjJmcmFnZSUyMiUzQSUyMk5lbm50JTIwZXR3YXMlMkMlMjB3YXMlMjBzaWUlMjBhdWYlMjBlaW5lJTIwZWluc2FtZSUyMEluc2VsJTIwbWl0bmltbXQlMjIlMkMlMjJrdWVyemVsJTIyJTNBJTIyRWluc2FtZSUyMEluc2VsJTIyJTJDJTIyYW50d29ydGVuJTIyJTNBJTVCJTdCJTIyYW50d29ydCUyMiUzQSUyMklobiUyMiUyQyUyMmFueiUyMiUzQSUyMjIwJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkdldHIlQzMlQTRua2ViZWNoZXIlMjIlMkMlMjJhbnolMjIlM0ElMjIzJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMkJ1Y2glMjIlMkMlMjJhbnolMjIlM0ElMjIyJTIyJTdEJTJDJTdCJTIyYW50d29ydCUyMiUzQSUyMlNvbm5lbmNyZW1lJTIyJTJDJTIyYW56JTIyJTNBJTIyMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJBbGtvaG9sJTIyJTJDJTIyYW56JTIyJTNBJTIyMiUyMiU3RCUyQyU3QiUyMmFudHdvcnQlMjIlM0ElMjJMaXBwZW5zdGlmdCUyMiUyQyUyMmFueiUyMiUzQSUyMjIlMjIlN0QlNUQlN0QlNUQ= -------------------------------------------------------------------------------- /server/node.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/server/node.exe -------------------------------------------------------------------------------- /server/node_modules/.bin/wscat: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | basedir=`dirname "$0"` 3 | 4 | case `uname` in 5 | *CYGWIN*) basedir=`cygpath -w "$basedir"`;; 6 | esac 7 | 8 | if [ -x "$basedir/node" ]; then 9 | "$basedir/node" "$basedir/../ws/bin/wscat" "$@" 10 | ret=$? 11 | else 12 | node "$basedir/../ws/bin/wscat" "$@" 13 | ret=$? 14 | fi 15 | exit $ret 16 | -------------------------------------------------------------------------------- /server/node_modules/.bin/wscat.cmd: -------------------------------------------------------------------------------- 1 | @IF EXIST "%~dp0\node.exe" ( 2 | "%~dp0\node.exe" "%~dp0\..\ws\bin\wscat" %* 3 | ) ELSE ( 4 | node "%~dp0\..\ws\bin\wscat" %* 5 | ) -------------------------------------------------------------------------------- /server/node_modules/ws/.npmignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | node_modules 3 | .*.swp 4 | .lock-* 5 | build 6 | 7 | -------------------------------------------------------------------------------- /server/node_modules/ws/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | npm_args: --ws:native 3 | node_js: 4 | - 0.6 5 | - 0.8 6 | -------------------------------------------------------------------------------- /server/node_modules/ws/History.md: -------------------------------------------------------------------------------- 1 | v0.4.24 - December 6th, 2012 2 | ===================== 3 | * Removed install.js. [shtylman] 4 | * Added browser field to package.json. [shtylman] 5 | * Support overwriting host header. [Raynos] 6 | * Emit 'listening' also with custom http server. [sebiq] 7 | 8 | v0.4.24 - December 6th, 2012 9 | ===================== 10 | * Yet another intermediate release, to not delay minor features any longer. 11 | * Native support installation issues further circumvented. [einaros] 12 | 13 | v0.4.23 - November 19th, 2012 14 | ===================== 15 | * Service release - last before major upgrade. 16 | * Changes default host from 127.0.0.1 to 0.0.0.0. [einaros] 17 | 18 | v0.4.22 - October 3rd, 2012 19 | ===================== 20 | * clear failsafe cleanup timeout once cleanup is called [AndreasMadsen] 21 | * added w3c compatible CloseEvent for onclose / addEventListener("close", ...). [einaros] 22 | * fix the sub protocol header handler [sonnyp] 23 | * fix unhandled exception if socket closes and 'error' is emitted [jmatthewsr-ms] 24 | 25 | v0.4.21 - July 14th, 2012 26 | ===================== 27 | * Emit error if server reponds with anything other than status code 101. [einaros] 28 | * Added 'headers' event to server. [rauchg] 29 | * path.exists moved to fs.exists. [blakmatrix] 30 | 31 | v0.4.20 - June 26th, 2012 32 | ===================== 33 | * node v0.8.0 compatibility release. 34 | 35 | v0.4.19 - June 19th, 2012 36 | ===================== 37 | * Change sender to merge buffers for relatively small payloads, may improve perf in some cases [einaros] 38 | * Avoid EventEmitter for Receiver classes. As above this may improve perf. [einaros] 39 | * Renamed fallback files from the somewhat misleading '*Windows'. [einaros] 40 | 41 | v0.4.18 - June 14th 2012 42 | ===================== 43 | * Fixed incorrect md5 digest encoding in Hixie handshake [nicokaiser] 44 | * Added example of use with Express 3 [einaros] 45 | * Change installation procedure to not require --ws:native to build native extensions. They will now build if a compiler is available. [einaros] 46 | 47 | v0.4.17 - June 13th 2012 48 | ===================== 49 | * Improve error handling during connection handshaking [einaros] 50 | * Ensure that errors are caught also after connection teardown [nicokaiser] 51 | * Update 'mocha' version to 1.1.0. [einaros] 52 | * Stop showing 'undefined' for some error logs. [tricknotes] 53 | * Update 'should' version to 0.6.3 [tricknotes] 54 | 55 | v0.4.16 - June 1st 2012 56 | ===================== 57 | * Build fix for Windows. [einaros] 58 | 59 | v0.4.15 - May 20th 2012 60 | ===================== 61 | * Enable fauxe streaming for hixie tansport. [einaros] 62 | * Allow hixie sender to deal with buffers. [einaros/pigne] 63 | * Allow error code 1011. [einaros] 64 | * Fix framing for empty packets (empty pings and pongs might break). [einaros] 65 | * Improve error and close handling, to avoid connections lingering in CLOSING state. [einaros] 66 | 67 | v0.4.14 - Apr 30th 2012 68 | ===================== 69 | * use node-gyp instead of node-waf [TooTallNate] 70 | * remove old windows compatibility makefile, and silently fall back to native modules [einaros] 71 | * ensure connection status [nicokaiser] 72 | * websocket client updated to use port 443 by default for wss:// connections [einaros] 73 | * support unix sockets [kschzt] 74 | 75 | v0.4.13 - Apr 12th 2012 76 | ===================== 77 | 78 | * circumvent node 0.6+ related memory leak caused by Object.defineProperty [nicokaiser] 79 | * improved error handling, improving stability in massive load use cases [nicokaiser] 80 | 81 | v0.4.12 - Mar 30th 2012 82 | ===================== 83 | 84 | * various memory leak / possible memory leak cleanups [einaros] 85 | * api documentation [nicokaiser] 86 | * add option to disable client tracking [nicokaiser] 87 | 88 | v0.4.11 - Mar 24th 2012 89 | ===================== 90 | 91 | * node v0.7 compatibillity release 92 | * gyp support [TooTallNate] 93 | * commander dependency update [jwueller] 94 | * loadbalancer support [nicokaiser] 95 | 96 | v0.4.10 - Mar 22th 2012 97 | ===================== 98 | 99 | * Final hixie close frame fixes. [nicokaiser] 100 | 101 | v0.4.9 - Mar 21st 2012 102 | ===================== 103 | 104 | * Various hixie bugfixes (such as proper close frame handling). [einaros] 105 | 106 | v0.4.8 - Feb 29th 2012 107 | ===================== 108 | 109 | * Allow verifyClient to run asynchronously [karlsequin] 110 | * Various bugfixes and cleanups. [einaros] 111 | 112 | v0.4.7 - Feb 21st 2012 113 | ===================== 114 | 115 | * Exposed bytesReceived from websocket client object, which makes it possible to implement bandwidth sampling. [einaros] 116 | * Updated browser based file upload example to include and output per websocket channel bandwidth sampling. [einaros] 117 | * Changed build scripts to check which architecture is currently in use. Required after the node.js changes to have prebuilt packages target ia32 by default. [einaros] 118 | 119 | v0.4.6 - Feb 9th 2012 120 | ===================== 121 | 122 | * Added browser based file upload example. [einaros] 123 | * Added server-to-browser status push example. [einaros] 124 | * Exposed pause() and resume() on WebSocket object, to enable client stream shaping. [einaros] 125 | 126 | v0.4.5 - Feb 7th 2012 127 | ===================== 128 | 129 | * Corrected regression bug in handling of connections with the initial frame delivered across both http upgrade head and a standalone packet. This would lead to a race condition, which in some cases could cause message corruption. [einaros] 130 | 131 | v0.4.4 - Feb 6th 2012 132 | ===================== 133 | 134 | * Pass original request object to verifyClient, for cookie or authentication verifications. [einaros] 135 | * Implemented addEventListener and slightly improved the emulation API by adding a MessageEvent with a readonly data attribute. [aslakhellesoy] 136 | * Rewrite parts of hybi receiver to avoid stack overflows for large amounts of packets bundled in the same buffer / packet. [einaros] 137 | 138 | v0.4.3 - Feb 4th 2012 139 | ===================== 140 | 141 | * Prioritized update: Corrected issue which would cause sockets to stay open longer than necessary, and resource leakage because of this. [einaros] 142 | 143 | v0.4.2 - Feb 4th 2012 144 | ===================== 145 | 146 | * Breaking change: WebSocketServer's verifyOrigin option has been renamed to verifyClient. [einaros] 147 | * verifyClient now receives { origin: 'origin header', secure: true/false }, where 'secure' will be true for ssl connections. [einaros] 148 | * Split benchmark, in preparation for more thorough case. [einaros] 149 | * Introduced hixie-76 draft support for server, since Safari (iPhone / iPad / OS X) and Opera still aren't updated to use Hybi. [einaros] 150 | * Expose 'supports' object from WebSocket, to indicate e.g. the underlying transport's support for binary data. [einaros] 151 | * Test and code cleanups. [einaros] 152 | 153 | v0.4.1 - Jan 25th 2012 154 | ===================== 155 | 156 | * Use readline in wscat [tricknotes] 157 | * Refactor _state away, in favor of the new _readyState [tricknotes] 158 | * travis-ci integration [einaros] 159 | * Fixed race condition in testsuite, causing a few tests to fail (without actually indicating errors) on travis [einaros] 160 | * Expose pong event [paddybyers] 161 | * Enabled running of WebSocketServer in noServer-mode, meaning that upgrades are passed in manually. [einaros] 162 | * Reworked connection procedure for WebSocketServer, and cleaned up tests. [einaros] 163 | 164 | v0.4.0 - Jan 2nd 2012 165 | ===================== 166 | 167 | * Windows compatibility [einaros] 168 | * Windows compatible test script [einaros] 169 | 170 | v0.3.9 - Jan 1st 2012 171 | ====================== 172 | 173 | * Improved protocol framing performance [einaros] 174 | * WSS support [kazuyukitanimura] 175 | * WSS tests [einaros] 176 | * readyState exposed [justinlatimer, tricknotes] 177 | * url property exposed [justinlatimer] 178 | * Removed old 'state' property [einaros] 179 | * Test cleanups [einaros] 180 | 181 | v0.3.8 - Dec 27th 2011 182 | ====================== 183 | 184 | * Made it possible to listen on specific paths, which is especially good to have for precreated http servers [einaros] 185 | * Extensive WebSocket / WebSocketServer cleanup, including changing all internal properties to unconfigurable, unenumerable properties [einaros] 186 | * Receiver modifications to ensure even better performance with fragmented sends [einaros] 187 | * Fixed issue in sender.js, which would cause SlowBuffer instances (such as returned from the crypto library's randomBytes) to be copied (and thus be dead slow) [einaros] 188 | * Removed redundant buffer copy in sender.js, which should improve server performance [einaros] 189 | 190 | v0.3.7 - Dec 25nd 2011 191 | ====================== 192 | 193 | * Added a browser based API which uses EventEmitters internally [3rd-Eden] 194 | * Expose request information from upgrade event for websocket server clients [mmalecki] 195 | 196 | v0.3.6 - Dec 19th 2011 197 | ====================== 198 | 199 | * Added option to let WebSocket.Server use an already existing http server [mmalecki] 200 | * Migrating various option structures to use options.js module [einaros] 201 | * Added a few more tests, options and handshake verifications to ensure that faulty connections are dealt with [einaros] 202 | * Code cleanups in Sender and Receiver, to ensure even faster parsing [einaros] 203 | 204 | v0.3.5 - Dec 13th 2011 205 | ====================== 206 | 207 | * Optimized Sender.js, Receiver.js and bufferutil.cc: 208 | * Apply loop-unrolling-like small block copies rather than use node.js Buffer#copy() (which is slow). 209 | * Mask blocks of data using combination of 32bit xor and loop-unrolling, instead of single bytes. 210 | * Keep pre-made send buffer for small transfers. 211 | * Leak fixes and code cleanups. 212 | 213 | v0.3.3 - Dec 12th 2011 214 | ====================== 215 | 216 | * Compile fix for Linux. 217 | * Rewrote parts of WebSocket.js, to avoid try/catch and thus avoid optimizer bailouts. 218 | 219 | v0.3.2 - Dec 11th 2011 220 | ====================== 221 | 222 | * Further performance updates, including the additions of a native BufferUtil module, which deals with several of the cpu intensive WebSocket operations. 223 | 224 | v0.3.1 - Dec 8th 2011 225 | ====================== 226 | 227 | * Service release, fixing broken tests. 228 | 229 | v0.3.0 - Dec 8th 2011 230 | ====================== 231 | 232 | * Node.js v0.4.x compatibility. 233 | * Code cleanups and efficiency improvements. 234 | * WebSocket server added, although this will still mainly be a client library. 235 | * WebSocket server certified to pass the Autobahn test suite. 236 | * Protocol improvements and corrections - such as handling (redundant) masks for empty fragments. 237 | * 'wscat' command line utility added, which can act as either client or server. 238 | 239 | v0.2.6 - Dec 3rd 2011 240 | ====================== 241 | 242 | * Renamed to 'ws'. Big woop, right -- but easy-websocket really just doesn't cut it anymore! 243 | 244 | v0.2.5 - Dec 3rd 2011 245 | ====================== 246 | 247 | * Rewrote much of the WebSocket parser, to ensure high speed for highly fragmented messages. 248 | * Added a BufferPool, as a start to more efficiently deal with allocations for WebSocket connections. More work to come, in that area. 249 | * Updated the Autobahn report, at http://einaros.github.com/easy-websocket, with comparisons against WebSocket-Node 1.0.2 and Chrome 16. 250 | 251 | v0.2.0 - Nov 25th 2011 252 | ====================== 253 | 254 | * Major rework to make sure all the Autobahn test cases pass. Also updated the internal tests to cover more corner cases. 255 | 256 | v0.1.2 - Nov 14th 2011 257 | ====================== 258 | 259 | * Back and forth, back and forth: now settled on keeping the api (event names, methods) closer to the websocket browser api. This will stick now. 260 | * Started keeping this history record. Better late than never, right? 261 | -------------------------------------------------------------------------------- /server/node_modules/ws/Makefile: -------------------------------------------------------------------------------- 1 | ALL_TESTS = $(shell find test/ -name '*.test.js') 2 | ALL_INTEGRATION = $(shell find test/ -name '*.integration.js') 3 | 4 | all: 5 | node-gyp configure build 6 | 7 | clean: 8 | node-gyp clean 9 | 10 | run-tests: 11 | @./node_modules/.bin/mocha \ 12 | -t 2000 \ 13 | $(TESTFLAGS) \ 14 | $(TESTS) 15 | 16 | run-integrationtests: 17 | @./node_modules/.bin/mocha \ 18 | -t 5000 \ 19 | $(TESTFLAGS) \ 20 | $(TESTS) 21 | 22 | test: 23 | @$(MAKE) NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests 24 | 25 | integrationtest: 26 | @$(MAKE) NODE_PATH=lib TESTS="$(ALL_INTEGRATION)" run-integrationtests 27 | 28 | benchmark: 29 | @node bench/sender.benchmark.js 30 | @node bench/parser.benchmark.js 31 | 32 | autobahn: 33 | @NODE_PATH=lib node test/autobahn.js 34 | 35 | autobahn-server: 36 | @NODE_PATH=lib node test/autobahn-server.js 37 | 38 | .PHONY: test 39 | -------------------------------------------------------------------------------- /server/node_modules/ws/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://secure.travis-ci.org/einaros/ws.png)](http://travis-ci.org/einaros/ws) 2 | 3 | # ws: a node.js websocket library # 4 | 5 | `ws` is a simple to use websocket implementation, up-to-date against RFC-6455, and [probably the fastest WebSocket library for node.js](http://hobbycoding.posterous.com/the-fastest-websocket-module-for-nodejs). 6 | 7 | Passes the quite extensive Autobahn test suite. See http://einaros.github.com/ws for the full reports. 8 | 9 | Comes with a command line utility, `wscat`, which can either act as a server (--listen), or client (--connect); Use it to debug simple websocket services. 10 | 11 | ## Protocol support ## 12 | 13 | * **Hixie draft 76** (Old and deprecated, but still in use by Safari and Opera. Added to ws version 0.4.2, but server only. Can be disabled by setting the `disableHixie` option to true.) 14 | * **HyBi drafts 07-12** (Use the option `protocolVersion: 8`, or argument `-p 8` for wscat) 15 | * **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`, or argument `-p 13` for wscat) 16 | 17 | _See the echo.websocket.org example below for how to use the `protocolVersion` option._ 18 | 19 | ## Usage ## 20 | 21 | ### Installing ### 22 | 23 | `npm install ws` 24 | 25 | ### Sending and receiving text data ### 26 | 27 | ```js 28 | var WebSocket = require('ws'); 29 | var ws = new WebSocket('ws://www.host.com/path'); 30 | ws.on('open', function() { 31 | ws.send('something'); 32 | }); 33 | ws.on('message', function(data, flags) { 34 | // flags.binary will be set if a binary data is received 35 | // flags.masked will be set if the data was masked 36 | }); 37 | ``` 38 | 39 | ### Sending binary data ### 40 | 41 | ```js 42 | var WebSocket = require('ws'); 43 | var ws = new WebSocket('ws://www.host.com/path'); 44 | ws.on('open', function() { 45 | var array = new Float32Array(5); 46 | for (var i = 0; i < array.length; ++i) array[i] = i / 2; 47 | ws.send(array, {binary: true, mask: true}); 48 | }); 49 | ``` 50 | 51 | Setting `mask`, as done for the send options above, will cause the data to be masked according to the websocket protocol. The same option applies for text data. 52 | 53 | ### Server example ### 54 | 55 | ```js 56 | var WebSocketServer = require('ws').Server 57 | , wss = new WebSocketServer({port: 8080}); 58 | wss.on('connection', function(ws) { 59 | ws.on('message', function(message) { 60 | console.log('received: %s', message); 61 | }); 62 | ws.send('something'); 63 | }); 64 | ``` 65 | 66 | ### Error handling best practices ### 67 | 68 | ```js 69 | // If the WebSocket is closed before the following send is attempted 70 | ws.send('something'); 71 | 72 | // Errors (both immediate and async write errors) can be detected in an optional callback. 73 | // The callback is also the only way of being notified that data has actually been sent. 74 | ws.send('something', function(error) { 75 | // if error is null, the send has been completed, 76 | // otherwise the error object will indicate what failed. 77 | }); 78 | 79 | // Immediate errors can also be handled with try/catch-blocks, but **note** 80 | // that since sends are inherently asynchronous, socket write failures will *not* 81 | // be captured when this technique is used. 82 | try { 83 | ws.send('something'); 84 | } 85 | catch (e) { 86 | // handle error 87 | } 88 | ``` 89 | 90 | ### echo.websocket.org demo ### 91 | 92 | ```js 93 | var WebSocket = require('ws'); 94 | var ws = new WebSocket('ws://echo.websocket.org/', {protocolVersion: 8, origin: 'http://websocket.org'}); 95 | ws.on('open', function() { 96 | console.log('connected'); 97 | ws.send(Date.now().toString(), {mask: true}); 98 | }); 99 | ws.on('close', function() { 100 | console.log('disconnected'); 101 | }); 102 | ws.on('message', function(data, flags) { 103 | console.log('Roundtrip time: ' + (Date.now() - parseInt(data)) + 'ms', flags); 104 | setTimeout(function() { 105 | ws.send(Date.now().toString(), {mask: true}); 106 | }, 500); 107 | }); 108 | ``` 109 | 110 | ### wscat against echo.websocket.org ### 111 | 112 | $ npm install -g ws 113 | $ wscat -c ws://echo.websocket.org -p 8 114 | connected (press CTRL+C to quit) 115 | > hi there 116 | < hi there 117 | > are you a happy parrot? 118 | < are you a happy parrot? 119 | 120 | ### Other examples ### 121 | 122 | For a full example with a browser client communicating with a ws server, see the examples folder. 123 | 124 | Note that the usage together with Express 3.0 is quite different from Express 2.x. The difference is expressed in the two different serverstats-examples. 125 | 126 | Otherwise, see the test cases. 127 | 128 | ### Running the tests ### 129 | 130 | `make test` 131 | 132 | ## API Docs ## 133 | 134 | See the doc/ directory for Node.js-like docs for the ws classes. 135 | 136 | ## License ## 137 | 138 | (The MIT License) 139 | 140 | Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com> 141 | 142 | Permission is hereby granted, free of charge, to any person obtaining 143 | a copy of this software and associated documentation files (the 144 | 'Software'), to deal in the Software without restriction, including 145 | without limitation the rights to use, copy, modify, merge, publish, 146 | distribute, sublicense, and/or sell copies of the Software, and to 147 | permit persons to whom the Software is furnished to do so, subject to 148 | the following conditions: 149 | 150 | The above copyright notice and this permission notice shall be 151 | included in all copies or substantial portions of the Software. 152 | 153 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 154 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 155 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 156 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 157 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 158 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 159 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 160 | -------------------------------------------------------------------------------- /server/node_modules/ws/bench/parser.benchmark.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | /** 8 | * Benchmark dependencies. 9 | */ 10 | 11 | var benchmark = require('benchmark') 12 | , Receiver = require('../').Receiver 13 | , suite = new benchmark.Suite('Receiver'); 14 | require('tinycolor'); 15 | require('./util'); 16 | 17 | /** 18 | * Setup receiver. 19 | */ 20 | 21 | suite.on('start', function () { 22 | receiver = new Receiver(); 23 | }); 24 | 25 | suite.on('cycle', function () { 26 | receiver = new Receiver(); 27 | }); 28 | 29 | /** 30 | * Benchmarks. 31 | */ 32 | 33 | var pingMessage = 'Hello' 34 | , pingPacket1 = getBufferFromHexString('89 ' + (pack(2, 0x80 | pingMessage.length)) + 35 | ' 34 83 a8 68 '+ getHexStringFromBuffer(mask(pingMessage, '34 83 a8 68'))); 36 | suite.add('ping message', function () { 37 | receiver.add(pingPacket1); 38 | }); 39 | 40 | var pingPacket2 = getBufferFromHexString('89 00') 41 | suite.add('ping with no data', function () { 42 | receiver.add(pingPacket2); 43 | }); 44 | 45 | var closePacket = getBufferFromHexString('88 00'); 46 | suite.add('close message', function () { 47 | receiver.add(closePacket); 48 | receiver.endPacket(); 49 | }); 50 | 51 | var maskedTextPacket = getBufferFromHexString('81 93 34 83 a8 68 01 b9 92 52 4f a1 c6 09 59 e6 8a 52 16 e6 cb 00 5b a1 d5'); 52 | suite.add('masked text message', function () { 53 | receiver.add(maskedTextPacket); 54 | }); 55 | 56 | binaryDataPacket = (function() { 57 | var length = 125 58 | , message = new Buffer(length) 59 | for (var i = 0; i < length; ++i) message[i] = i % 10; 60 | return getBufferFromHexString('82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' 61 | + getHexStringFromBuffer(mask(message), '34 83 a8 68')); 62 | })(); 63 | suite.add('binary data (125 bytes)', function () { 64 | try { 65 | receiver.add(binaryDataPacket); 66 | 67 | } 68 | catch(e) {console.log(e)} 69 | }); 70 | 71 | binaryDataPacket2 = (function() { 72 | var length = 65535 73 | , message = new Buffer(length) 74 | for (var i = 0; i < length; ++i) message[i] = i % 10; 75 | return getBufferFromHexString('82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' 76 | + getHexStringFromBuffer(mask(message), '34 83 a8 68')); 77 | })(); 78 | suite.add('binary data (65535 bytes)', function () { 79 | receiver.add(binaryDataPacket2); 80 | }); 81 | 82 | binaryDataPacket3 = (function() { 83 | var length = 200*1024 84 | , message = new Buffer(length) 85 | for (var i = 0; i < length; ++i) message[i] = i % 10; 86 | return getBufferFromHexString('82 ' + getHybiLengthAsHexString(length, true) + ' 34 83 a8 68 ' 87 | + getHexStringFromBuffer(mask(message), '34 83 a8 68')); 88 | })(); 89 | suite.add('binary data (200 kB)', function () { 90 | receiver.add(binaryDataPacket3); 91 | }); 92 | 93 | /** 94 | * Output progress. 95 | */ 96 | 97 | suite.on('cycle', function (bench, details) { 98 | console.log('\n ' + suite.name.grey, details.name.white.bold); 99 | console.log(' ' + [ 100 | details.hz.toFixed(2).cyan + ' ops/sec'.grey 101 | , details.count.toString().white + ' times executed'.grey 102 | , 'benchmark took '.grey + details.times.elapsed.toString().white + ' sec.'.grey 103 | , 104 | ].join(', '.grey)); 105 | }); 106 | 107 | /** 108 | * Run/export benchmarks. 109 | */ 110 | 111 | if (!module.parent) { 112 | suite.run(); 113 | } else { 114 | module.exports = suite; 115 | } 116 | -------------------------------------------------------------------------------- /server/node_modules/ws/bench/sender.benchmark.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | /** 8 | * Benchmark dependencies. 9 | */ 10 | 11 | var benchmark = require('benchmark') 12 | , Sender = require('../').Sender 13 | , suite = new benchmark.Suite('Sender'); 14 | require('tinycolor'); 15 | require('./util'); 16 | 17 | /** 18 | * Setup sender. 19 | */ 20 | 21 | suite.on('start', function () { 22 | sender = new Sender(); 23 | sender._socket = { write: function() {} }; 24 | }); 25 | 26 | suite.on('cycle', function () { 27 | sender = new Sender(); 28 | sender._socket = { write: function() {} }; 29 | }); 30 | 31 | /** 32 | * Benchmarks 33 | */ 34 | 35 | framePacket = new Buffer(200*1024); 36 | framePacket.fill(99); 37 | suite.add('frameAndSend, unmasked (200 kB)', function () { 38 | sender.frameAndSend(0x2, framePacket, true, false); 39 | }); 40 | suite.add('frameAndSend, masked (200 kB)', function () { 41 | sender.frameAndSend(0x2, framePacket, true, true); 42 | }); 43 | 44 | /** 45 | * Output progress. 46 | */ 47 | 48 | suite.on('cycle', function (bench, details) { 49 | console.log('\n ' + suite.name.grey, details.name.white.bold); 50 | console.log(' ' + [ 51 | details.hz.toFixed(2).cyan + ' ops/sec'.grey 52 | , details.count.toString().white + ' times executed'.grey 53 | , 'benchmark took '.grey + details.times.elapsed.toString().white + ' sec.'.grey 54 | , 55 | ].join(', '.grey)); 56 | }); 57 | 58 | /** 59 | * Run/export benchmarks. 60 | */ 61 | 62 | if (!module.parent) { 63 | suite.run(); 64 | } else { 65 | module.exports = suite; 66 | } 67 | -------------------------------------------------------------------------------- /server/node_modules/ws/bench/speed.js: -------------------------------------------------------------------------------- 1 | var cluster = require('cluster') 2 | , WebSocket = require('../') 3 | , WebSocketServer = WebSocket.Server 4 | , crypto = require('crypto') 5 | , util = require('util') 6 | , ansi = require('ansi'); 7 | require('tinycolor'); 8 | 9 | function roundPrec(num, prec) { 10 | var mul = Math.pow(10, prec); 11 | return Math.round(num * mul) / mul; 12 | } 13 | 14 | function humanSize(bytes) { 15 | if (bytes >= 1048576) return roundPrec(bytes / 1048576, 2) + ' MB'; 16 | if (bytes >= 1024) return roundPrec(bytes / 1024, 2) + ' kB'; 17 | return roundPrec(bytes, 2) + ' B'; 18 | } 19 | 20 | function generateRandomData(size) { 21 | var buffer = new Buffer(size); 22 | for (var i = 0; i < size; ++i) { 23 | buffer[i] = ~~(Math.random() * 127); 24 | } 25 | return buffer; 26 | } 27 | 28 | if (cluster.isMaster) { 29 | var wss = new WebSocketServer({port: 8181}, function() { 30 | cluster.fork(); 31 | }); 32 | wss.on('connection', function(ws) { 33 | ws.on('message', function(data, flags) { 34 | ws.send(data, {binary: flags&&flags.binary}); 35 | }); 36 | ws.on('close', function() {}); 37 | }); 38 | cluster.on('death', function(worker) { 39 | wss.close(); 40 | }); 41 | } 42 | else { 43 | var cursor = ansi(process.stdout); 44 | 45 | var configs = [ 46 | [true, 10000, 64], 47 | [true, 5000, 16*1024], 48 | [true, 1000, 128*1024], 49 | [true, 100, 1024*1024], 50 | [true, 1, 500*1024*1024], 51 | [false, 10000, 64], 52 | [false, 5000, 16*1024], 53 | [false, 1000, 128*1024], 54 | [false, 100, 1024*1024], 55 | ]; 56 | 57 | var largest = configs[0][1]; 58 | for (var i = 0, l = configs.length; i < l; ++i) { 59 | if (configs[i][2] > largest) largest = configs[i][2]; 60 | } 61 | 62 | console.log('Generating %s of test data ...', humanSize(largest)); 63 | var randomBytes = generateRandomData(largest); 64 | 65 | function roundtrip(useBinary, roundtrips, size, cb) { 66 | var data = randomBytes.slice(0, size); 67 | var prefix = util.format('Running %d roundtrips of %s %s data', roundtrips, humanSize(size), useBinary ? 'binary' : 'text'); 68 | console.log(prefix); 69 | var client = new WebSocket('ws://localhost:' + '8181'); 70 | var dt; 71 | var roundtrip = 0; 72 | function send() { 73 | client.send(data, {binary: useBinary}); 74 | } 75 | client.on('error', function(e) { 76 | console.error(e); 77 | process.exit(); 78 | }); 79 | client.on('open', function() { 80 | dt = Date.now(); 81 | send(); 82 | }); 83 | client.on('message', function(data, flags) { 84 | if (++roundtrip == roundtrips) { 85 | var elapsed = Date.now() - dt; 86 | cursor.up(); 87 | console.log('%s:\t%ss\t%s' 88 | , useBinary ? prefix.green : prefix.cyan 89 | , roundPrec(elapsed / 1000, 1).toString().green.bold 90 | , (humanSize((size * roundtrips) / elapsed * 1000) + '/s').blue.bold); 91 | client.close(); 92 | cb(); 93 | return; 94 | } 95 | process.nextTick(send); 96 | }); 97 | } 98 | 99 | (function run() { 100 | if (configs.length == 0) process.exit(); 101 | var config = configs.shift(); 102 | config.push(run); 103 | roundtrip.apply(null, config); 104 | })(); 105 | } -------------------------------------------------------------------------------- /server/node_modules/ws/bench/util.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | /** 8 | * Returns a Buffer from a "ff 00 ff"-type hex string. 9 | */ 10 | 11 | getBufferFromHexString = function(byteStr) { 12 | var bytes = byteStr.split(' '); 13 | var buf = new Buffer(bytes.length); 14 | for (var i = 0; i < bytes.length; ++i) { 15 | buf[i] = parseInt(bytes[i], 16); 16 | } 17 | return buf; 18 | } 19 | 20 | /** 21 | * Returns a hex string from a Buffer. 22 | */ 23 | 24 | getHexStringFromBuffer = function(data) { 25 | var s = ''; 26 | for (var i = 0; i < data.length; ++i) { 27 | s += padl(data[i].toString(16), 2, '0') + ' '; 28 | } 29 | return s.trim(); 30 | } 31 | 32 | /** 33 | * Splits a buffer in two parts. 34 | */ 35 | 36 | splitBuffer = function(buffer) { 37 | var b1 = new Buffer(Math.ceil(buffer.length / 2)); 38 | buffer.copy(b1, 0, 0, b1.length); 39 | var b2 = new Buffer(Math.floor(buffer.length / 2)); 40 | buffer.copy(b2, 0, b1.length, b1.length + b2.length); 41 | return [b1, b2]; 42 | } 43 | 44 | /** 45 | * Performs hybi07+ type masking on a hex string or buffer. 46 | */ 47 | 48 | mask = function(buf, maskString) { 49 | if (typeof buf == 'string') buf = new Buffer(buf); 50 | var mask = getBufferFromHexString(maskString || '34 83 a8 68'); 51 | for (var i = 0; i < buf.length; ++i) { 52 | buf[i] ^= mask[i % 4]; 53 | } 54 | return buf; 55 | } 56 | 57 | /** 58 | * Returns a hex string representing the length of a message 59 | */ 60 | 61 | getHybiLengthAsHexString = function(len, masked) { 62 | if (len < 126) { 63 | var buf = new Buffer(1); 64 | buf[0] = (masked ? 0x80 : 0) | len; 65 | } 66 | else if (len < 65536) { 67 | var buf = new Buffer(3); 68 | buf[0] = (masked ? 0x80 : 0) | 126; 69 | getBufferFromHexString(pack(4, len)).copy(buf, 1); 70 | } 71 | else { 72 | var buf = new Buffer(9); 73 | buf[0] = (masked ? 0x80 : 0) | 127; 74 | getBufferFromHexString(pack(16, len)).copy(buf, 1); 75 | } 76 | return getHexStringFromBuffer(buf); 77 | } 78 | 79 | /** 80 | * Unpacks a Buffer into a number. 81 | */ 82 | 83 | unpack = function(buffer) { 84 | var n = 0; 85 | for (var i = 0; i < buffer.length; ++i) { 86 | n = (i == 0) ? buffer[i] : (n * 256) + buffer[i]; 87 | } 88 | return n; 89 | } 90 | 91 | /** 92 | * Returns a hex string, representing a specific byte count 'length', from a number. 93 | */ 94 | 95 | pack = function(length, number) { 96 | return padl(number.toString(16), length, '0').replace(/([0-9a-f][0-9a-f])/gi, '$1 ').trim(); 97 | } 98 | 99 | /** 100 | * Left pads the string 's' to a total length of 'n' with char 'c'. 101 | */ 102 | 103 | padl = function(s, n, c) { 104 | return new Array(1 + n - s.length).join(c) + s; 105 | } 106 | -------------------------------------------------------------------------------- /server/node_modules/ws/binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'targets': [ 3 | { 4 | 'target_name': 'validation', 5 | 'cflags': [ '-O3' ], 6 | 'sources': [ 'src/validation.cc' ] 7 | }, 8 | { 9 | 'target_name': 'bufferutil', 10 | 'cflags': [ '-O3' ], 11 | 'sources': [ 'src/bufferutil.cc' ] 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /server/node_modules/ws/builderror.log: -------------------------------------------------------------------------------- 1 | gyp ERR! configure error 2 | gyp ERR! stack Error: Can't find Python executable "python", you can set the PYTHON env variable. 3 | gyp ERR! stack at failNoPython (C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\node-gyp\lib\configure.js:113:14) 4 | gyp ERR! stack at C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\node-gyp\lib\configure.js:81:11 5 | gyp ERR! stack at Object.oncomplete (fs.js:107:15) 6 | gyp ERR! System Windows_NT 6.2.9200 7 | gyp ERR! command "node" "C:\\Program Files (x86)\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild" 8 | gyp ERR! cwd C:\node_test\node_modules\ws 9 | gyp ERR! node -v v0.10.10 10 | gyp ERR! node-gyp -v v0.9.6 11 | gyp ERR! not ok 12 | -------------------------------------------------------------------------------- /server/node_modules/ws/doc/ws.md: -------------------------------------------------------------------------------- 1 | # ws 2 | 3 | ## Class: ws.Server 4 | 5 | This class is a WebSocket server. It is an `EventEmitter`. 6 | 7 | ### new ws.Server([options], [callback]) 8 | 9 | * `options` Object 10 | * `host` String 11 | * `port` Number 12 | * `server` http.Server 13 | * `verifyClient` Function 14 | * `path` String 15 | * `noServer` Boolean 16 | * `disableHixie` Boolean 17 | * `clientTracking` Boolean 18 | * `callback` Function 19 | 20 | Construct a new server object. 21 | 22 | Either `port` or `server` must be provided, otherwise you might enable `noServer` if you want to pass the requests directly. 23 | 24 | ### server.close([code], [data]) 25 | 26 | Close the server and terminate all clients 27 | 28 | ### server.handleUpgrade(request, socket, upgradeHead, callback) 29 | 30 | Handles a HTTP Upgrade request. `request` is an instance of `http.ServerRequest`, `socket` is an instance of `net.Socket`. 31 | 32 | When the Upgrade was successfully, the `callback` will be called with a `ws.WebSocket` object as parameter. 33 | 34 | ### Event: 'error' 35 | 36 | `function (error) { }` 37 | 38 | If the underlying server emits an error, it will be forwarded here. 39 | 40 | ### Event: 'headers' 41 | 42 | `function (headers) { }` 43 | 44 | Emitted with the object of HTTP headers that are going to be written to the `Stream` as part of the handshake. 45 | 46 | ### Event: 'connection' 47 | 48 | `function (socket) { }` 49 | 50 | When a new WebSocket connection is established. `socket` is an object of type `ws.WebSocket`. 51 | 52 | 53 | ## Class: ws.WebSocket 54 | 55 | This class represents a WebSocket connection. It is an `EventEmitter`. 56 | 57 | ### new ws.WebSocket(address, [options]) 58 | 59 | Instantiating with an `address` creates a new WebSocket client object. If `address` is an Array (request, socket, rest), it is instantiated as a Server client (e.g. called from the `ws.Server`). 60 | 61 | ### websocket.bytesReceived 62 | 63 | Received bytes count. 64 | 65 | ### websocket.readyState 66 | 67 | Possible states are `WebSocket.CONNECTING`, `WebSocket.OPEN`, `WebSocket.CLOSING`, `WebSocket.CLOSED`. 68 | 69 | ### websocket.protocolVersion 70 | 71 | The WebSocket protocol version used for this connection, `8`, `13` or `hixie-76` (the latter only for server clients). 72 | 73 | ### websocket.url 74 | 75 | The URL of the WebSocket server (only for clients) 76 | 77 | ### websocket.supports 78 | 79 | Describes the feature of the used protocol version. E.g. `supports.binary` is a boolean that describes if the connection supports binary messages. 80 | 81 | ### websocket.close([code], [data]) 82 | 83 | Gracefully closes the connection, after sending a description message 84 | 85 | ### websocket.pause() 86 | 87 | Pause the client stream 88 | 89 | ### websocket.ping([data], [options], [dontFailWhenClosed]) 90 | 91 | Sends a ping. `data` is sent, `options` is an object with members `mask` and `binary`. `dontFailWhenClosed` indicates whether or not to throw if the connection isnt open. 92 | 93 | ### websocket.pong([data], [options], [dontFailWhenClosed]) 94 | 95 | Sends a pong. `data` is sent, `options` is an object with members `mask` and `binary`. `dontFailWhenClosed` indicates whether or not to throw if the connection isnt open. 96 | 97 | 98 | ### websocket.resume() 99 | 100 | Resume the client stream 101 | 102 | ### websocket.send(data, [options], [callback]) 103 | 104 | Sends `data` through the connection. `options` can be an object with members `mask` and `binary`. The optional `callback` is executed after the send completes. 105 | 106 | ### websocket.stream([options], callback) 107 | 108 | Streams data through calls to a user supplied function. `options` can be an object with members `mask` and `binary`. `callback` is executed on successive ticks of which send is `function (data, final)`. 109 | 110 | ### websocket.terminate() 111 | 112 | Immediately shuts down the connection 113 | 114 | ### websocket.onopen 115 | ### websocket.onerror 116 | ### websocket.onclose 117 | ### websocket.onmessage 118 | 119 | Emulates the W3C Browser based WebSocket interface using function members. 120 | 121 | ### websocket.addEventListener(method, listener) 122 | 123 | Emulates the W3C Browser based WebSocket interface using addEventListener. 124 | 125 | ### Event: 'error' 126 | 127 | `function (error) { }` 128 | 129 | If the client emits an error, this event is emitted (errors from the underlying `net.Socket` are forwarded here). 130 | 131 | ### Event: 'close' 132 | 133 | `function (code, message) { }` 134 | 135 | Is emitted when the connection is closed. `code` is defined in the WebSocket specification. 136 | 137 | The `close` event is also emitted when then underlying `net.Socket` closes the connection (`end` or `close`). 138 | 139 | ### Event: 'message' 140 | 141 | `function (data, flags) { }` 142 | 143 | Is emitted when data is received. `flags` is an object with member `binary`. 144 | 145 | ### Event: 'ping' 146 | 147 | `function (data, flags) { }` 148 | 149 | Is emitted when a ping is received. `flags` is an object with member `binary`. 150 | 151 | ### Event: 'pong' 152 | 153 | `function (data, flags) { }` 154 | 155 | Is emitted when a pong is received. `flags` is an object with member `binary`. 156 | 157 | ### Event: 'open' 158 | 159 | `function () { }` 160 | 161 | Emitted when the connection is established. 162 | 163 | -------------------------------------------------------------------------------- /server/node_modules/ws/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | module.exports = require('./lib/WebSocket'); 8 | module.exports.Server = require('./lib/WebSocketServer'); 9 | module.exports.Sender = require('./lib/Sender'); 10 | module.exports.Receiver = require('./lib/Receiver'); 11 | 12 | module.exports.createServer = function (options, connectionListener) { 13 | var server = new module.exports.Server(options); 14 | if (typeof connectionListener === 'function') { 15 | server.on('connection', connectionListener); 16 | } 17 | return server; 18 | }; 19 | 20 | module.exports.connect = module.exports.createConnection = function (address, openListener) { 21 | var client = new module.exports(address); 22 | if (typeof openListener === 'function') { 23 | client.on('open', openListener); 24 | } 25 | return client; 26 | }; 27 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/BufferPool.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | var util = require('util'); 8 | 9 | function BufferPool(initialSize, growStrategy, shrinkStrategy) { 10 | if (typeof initialSize === 'function') { 11 | shrinkStrategy = growStrategy; 12 | growStrategy = initialSize; 13 | initialSize = 0; 14 | } 15 | else if (typeof initialSize === 'undefined') { 16 | initialSize = 0; 17 | } 18 | this._growStrategy = (growStrategy || function(db, size) { 19 | return db.used + size; 20 | }).bind(null, this); 21 | this._shrinkStrategy = (shrinkStrategy || function(db) { 22 | return initialSize; 23 | }).bind(null, this); 24 | this._buffer = initialSize ? new Buffer(initialSize) : null; 25 | this._offset = 0; 26 | this._used = 0; 27 | this._changeFactor = 0; 28 | this.__defineGetter__('size', function(){ 29 | return this._buffer == null ? 0 : this._buffer.length; 30 | }); 31 | this.__defineGetter__('used', function(){ 32 | return this._used; 33 | }); 34 | } 35 | 36 | BufferPool.prototype.get = function(length) { 37 | if (this._buffer == null || this._offset + length > this._buffer.length) { 38 | var newBuf = new Buffer(this._growStrategy(length)); 39 | this._buffer = newBuf; 40 | this._offset = 0; 41 | } 42 | this._used += length; 43 | var buf = this._buffer.slice(this._offset, this._offset + length); 44 | this._offset += length; 45 | return buf; 46 | } 47 | 48 | BufferPool.prototype.reset = function(forceNewBuffer) { 49 | var len = this._shrinkStrategy(); 50 | if (len < this.size) this._changeFactor -= 1; 51 | if (forceNewBuffer || this._changeFactor < -2) { 52 | this._changeFactor = 0; 53 | this._buffer = len ? new Buffer(len) : null; 54 | } 55 | this._offset = 0; 56 | this._used = 0; 57 | } 58 | 59 | module.exports = BufferPool; 60 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/BufferUtil.fallback.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | module.exports.BufferUtil = { 8 | merge: function(mergedBuffer, buffers) { 9 | var offset = 0; 10 | for (var i = 0, l = buffers.length; i < l; ++i) { 11 | var buf = buffers[i]; 12 | buf.copy(mergedBuffer, offset); 13 | offset += buf.length; 14 | } 15 | }, 16 | mask: function(source, mask, output, offset, length) { 17 | var maskNum = mask.readUInt32LE(0, true); 18 | var i = 0; 19 | for (; i < length - 3; i += 4) { 20 | var num = maskNum ^ source.readUInt32LE(i, true); 21 | if (num < 0) num = 4294967296 + num; 22 | output.writeUInt32LE(num, offset + i, true); 23 | } 24 | switch (length % 4) { 25 | case 3: output[offset + i + 2] = source[i + 2] ^ mask[2]; 26 | case 2: output[offset + i + 1] = source[i + 1] ^ mask[1]; 27 | case 1: output[offset + i] = source[i] ^ mask[0]; 28 | case 0:; 29 | } 30 | }, 31 | unmask: function(data, mask) { 32 | var maskNum = mask.readUInt32LE(0, true); 33 | var length = data.length; 34 | var i = 0; 35 | for (; i < length - 3; i += 4) { 36 | var num = maskNum ^ data.readUInt32LE(i, true); 37 | if (num < 0) num = 4294967296 + num; 38 | data.writeUInt32LE(num, i, true); 39 | } 40 | switch (length % 4) { 41 | case 3: data[i + 2] = data[i + 2] ^ mask[2]; 42 | case 2: data[i + 1] = data[i + 1] ^ mask[1]; 43 | case 1: data[i] = data[i] ^ mask[0]; 44 | case 0:; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/BufferUtil.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | try { 8 | module.exports = require('../build/Release/bufferutil'); 9 | } catch (e) { try { 10 | module.exports = require('../build/default/bufferutil'); 11 | } catch (e) { try { 12 | module.exports = require('./BufferUtil.fallback'); 13 | } catch (e) { 14 | console.error('bufferutil.node seems to not have been built. Run npm install.'); 15 | throw e; 16 | }}} 17 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/ErrorCodes.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | module.exports = { 8 | isValidErrorCode: function(code) { 9 | return (code >= 1000 && code <= 1011 && code != 1004 && code != 1005 && code != 1006) || 10 | (code >= 3000 && code <= 4999); 11 | }, 12 | 1000: 'normal', 13 | 1001: 'going away', 14 | 1002: 'protocol error', 15 | 1003: 'unsupported data', 16 | 1004: 'reserved', 17 | 1005: 'reserved for extensions', 18 | 1006: 'reserved for extensions', 19 | 1007: 'inconsistent or invalid data', 20 | 1008: 'policy violation', 21 | 1009: 'message too big', 22 | 1010: 'extension handshake missing', 23 | 1011: 'an unexpected condition prevented the request from being fulfilled', 24 | }; -------------------------------------------------------------------------------- /server/node_modules/ws/lib/Receiver.hixie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | var util = require('util'); 8 | 9 | /** 10 | * State constants 11 | */ 12 | 13 | var EMPTY = 0 14 | , BODY = 1; 15 | var BINARYLENGTH = 2 16 | , BINARYBODY = 3; 17 | 18 | /** 19 | * Hixie Receiver implementation 20 | */ 21 | 22 | function Receiver () { 23 | this.state = EMPTY; 24 | this.buffers = []; 25 | this.messageEnd = -1; 26 | this.spanLength = 0; 27 | this.dead = false; 28 | 29 | this.onerror = function() {}; 30 | this.ontext = function() {}; 31 | this.onbinary = function() {}; 32 | this.onclose = function() {}; 33 | this.onping = function() {}; 34 | this.onpong = function() {}; 35 | } 36 | 37 | module.exports = Receiver; 38 | 39 | /** 40 | * Add new data to the parser. 41 | * 42 | * @api public 43 | */ 44 | 45 | Receiver.prototype.add = function(data) { 46 | var self = this; 47 | function doAdd() { 48 | if (self.state === EMPTY) { 49 | if (data.length == 2 && data[0] == 0xFF && data[1] == 0x00) { 50 | self.reset(); 51 | self.onclose(); 52 | return; 53 | } 54 | if (data[0] === 0x80) { 55 | self.messageEnd = 0; 56 | self.state = BINARYLENGTH; 57 | data = data.slice(1); 58 | } else { 59 | 60 | if (data[0] !== 0x00) { 61 | self.error('payload must start with 0x00 byte', true); 62 | return; 63 | } 64 | data = data.slice(1); 65 | self.state = BODY; 66 | 67 | } 68 | } 69 | if (self.state === BINARYLENGTH) { 70 | var i = 0; 71 | while ((i < data.length) && (data[i] & 0x80)) { 72 | self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); 73 | ++i; 74 | } 75 | if (i < data.length) { 76 | self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); 77 | self.state = BINARYBODY; 78 | ++i; 79 | } 80 | if (i > 0) 81 | data = data.slice(i); 82 | } 83 | if (self.state === BINARYBODY) { 84 | var dataleft = self.messageEnd - self.spanLength; 85 | if (data.length >= dataleft) { 86 | // consume the whole buffer to finish the frame 87 | self.buffers.push(data); 88 | self.spanLength += dataleft; 89 | self.messageEnd = dataleft; 90 | return self.parse(); 91 | } 92 | // frame's not done even if we consume it all 93 | self.buffers.push(data); 94 | self.spanLength += data.length; 95 | return; 96 | } 97 | self.buffers.push(data); 98 | if ((self.messageEnd = bufferIndex(data, 0xFF)) != -1) { 99 | self.spanLength += self.messageEnd; 100 | return self.parse(); 101 | } 102 | else self.spanLength += data.length; 103 | } 104 | while(data) data = doAdd(); 105 | } 106 | 107 | /** 108 | * Releases all resources used by the receiver. 109 | * 110 | * @api public 111 | */ 112 | 113 | Receiver.prototype.cleanup = function() { 114 | this.dead = true; 115 | this.state = EMPTY; 116 | this.buffers = []; 117 | } 118 | 119 | /** 120 | * Process buffered data. 121 | * 122 | * @api public 123 | */ 124 | 125 | Receiver.prototype.parse = function() { 126 | var output = new Buffer(this.spanLength); 127 | var outputIndex = 0; 128 | for (var bi = 0, bl = this.buffers.length; bi < bl - 1; ++bi) { 129 | var buffer = this.buffers[bi]; 130 | buffer.copy(output, outputIndex); 131 | outputIndex += buffer.length; 132 | } 133 | var lastBuffer = this.buffers[this.buffers.length - 1]; 134 | if (this.messageEnd > 0) lastBuffer.copy(output, outputIndex, 0, this.messageEnd); 135 | if (this.state !== BODY) --this.messageEnd; 136 | var tail = null; 137 | if (this.messageEnd < lastBuffer.length - 1) { 138 | tail = lastBuffer.slice(this.messageEnd + 1); 139 | } 140 | this.reset(); 141 | this.ontext(output.toString('utf8')); 142 | return tail; 143 | } 144 | 145 | /** 146 | * Handles an error 147 | * 148 | * @api private 149 | */ 150 | 151 | Receiver.prototype.error = function (reason, terminate) { 152 | this.reset(); 153 | this.onerror(reason, terminate); 154 | return this; 155 | } 156 | 157 | /** 158 | * Reset parser state 159 | * 160 | * @api private 161 | */ 162 | 163 | Receiver.prototype.reset = function (reason) { 164 | if (this.dead) return; 165 | this.state = EMPTY; 166 | this.buffers = []; 167 | this.messageEnd = -1; 168 | this.spanLength = 0; 169 | } 170 | 171 | /** 172 | * Internal api 173 | */ 174 | 175 | function bufferIndex(buffer, byte) { 176 | for (var i = 0, l = buffer.length; i < l; ++i) { 177 | if (buffer[i] === byte) return i; 178 | } 179 | return -1; 180 | } 181 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/Sender.hixie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | var events = require('events') 8 | , util = require('util') 9 | , EventEmitter = events.EventEmitter; 10 | 11 | /** 12 | * Hixie Sender implementation 13 | */ 14 | 15 | function Sender(socket) { 16 | this.socket = socket; 17 | this.continuationFrame = false; 18 | this.isClosed = false; 19 | } 20 | 21 | module.exports = Sender; 22 | 23 | /** 24 | * Inherits from EventEmitter. 25 | */ 26 | 27 | util.inherits(Sender, events.EventEmitter); 28 | 29 | /** 30 | * Frames and writes data. 31 | * 32 | * @api public 33 | */ 34 | 35 | Sender.prototype.send = function(data, options, cb) { 36 | if (this.isClosed) return; 37 | /* 38 | if (options && options.binary) { 39 | this.error('hixie websockets do not support binary'); 40 | return; 41 | } 42 | */ 43 | var isString = typeof data == 'string' 44 | , length = isString ? Buffer.byteLength(data) : data.length 45 | , lengthbytes = (length > 127) ? 2 : 1 // assume less than 2**14 bytes 46 | , writeStartMarker = this.continuationFrame == false 47 | , writeEndMarker = !options || !(typeof options.fin != 'undefined' && !options.fin) 48 | , buffer = new Buffer((writeStartMarker ? ((options && options.binary) ? (1 + lengthbytes) : 1) : 0) + length + ((writeEndMarker && !(options && options.binary)) ? 1 : 0)) 49 | , offset = writeStartMarker ? 1 : 0; 50 | 51 | if (writeStartMarker) { 52 | if (options && options.binary) { 53 | buffer.write('\x80', 'binary'); 54 | // assume length less than 2**14 bytes 55 | if (lengthbytes > 1) 56 | buffer.write(String.fromCharCode(128+length/128), offset++, 'binary'); 57 | buffer.write(String.fromCharCode(length&0x7f), offset++, 'binary'); 58 | } else 59 | buffer.write('\x00', 'binary'); 60 | } 61 | 62 | if (isString) buffer.write(data, offset, 'utf8'); 63 | else data.copy(buffer, offset, 0); 64 | 65 | if (writeEndMarker) { 66 | if (options && options.binary) { 67 | // sending binary, not writing end marker 68 | } else 69 | buffer.write('\xff', offset + length, 'binary'); 70 | this.continuationFrame = false; 71 | } 72 | else this.continuationFrame = true; 73 | 74 | try { 75 | this.socket.write(buffer, 'binary', cb); 76 | } catch (e) { 77 | this.error(e.toString()); 78 | } 79 | } 80 | 81 | /** 82 | * Sends a close instruction to the remote party. 83 | * 84 | * @api public 85 | */ 86 | 87 | Sender.prototype.close = function(code, data, mask, cb) { 88 | if (this.isClosed) return; 89 | this.isClosed = true; 90 | try { 91 | if (this.continuationFrame) this.socket.write(new Buffer([0xff], 'binary')); 92 | this.socket.write(new Buffer([0xff, 0x00]), 'binary', cb); 93 | } catch (e) { 94 | this.error(e.toString()); 95 | } 96 | } 97 | 98 | /** 99 | * Sends a ping message to the remote party. Not available for hixie. 100 | * 101 | * @api public 102 | */ 103 | 104 | Sender.prototype.ping = function(data, options) {} 105 | 106 | /** 107 | * Sends a pong message to the remote party. Not available for hixie. 108 | * 109 | * @api public 110 | */ 111 | 112 | Sender.prototype.pong = function(data, options) {} 113 | 114 | /** 115 | * Handles an error 116 | * 117 | * @api private 118 | */ 119 | 120 | Sender.prototype.error = function (reason) { 121 | this.emit('error', reason); 122 | return this; 123 | } 124 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/Sender.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | var events = require('events') 8 | , util = require('util') 9 | , EventEmitter = events.EventEmitter 10 | , ErrorCodes = require('./ErrorCodes') 11 | , bufferUtil = require('./BufferUtil').BufferUtil; 12 | 13 | /** 14 | * HyBi Sender implementation 15 | */ 16 | 17 | function Sender(socket) { 18 | this._socket = socket; 19 | this.firstFragment = true; 20 | } 21 | 22 | /** 23 | * Inherits from EventEmitter. 24 | */ 25 | 26 | util.inherits(Sender, events.EventEmitter); 27 | 28 | /** 29 | * Sends a close instruction to the remote party. 30 | * 31 | * @api public 32 | */ 33 | 34 | Sender.prototype.close = function(code, data, mask) { 35 | if (typeof code !== 'undefined') { 36 | if (typeof code !== 'number' || 37 | !ErrorCodes.isValidErrorCode(code)) throw new Error('first argument must be a valid error code number'); 38 | } 39 | code = code || 1000; 40 | var dataBuffer = new Buffer(2 + (data ? Buffer.byteLength(data) : 0)); 41 | writeUInt16BE.call(dataBuffer, code, 0); 42 | if (dataBuffer.length > 2) dataBuffer.write(data, 2); 43 | this.frameAndSend(0x8, dataBuffer, true, mask); 44 | } 45 | 46 | /** 47 | * Sends a ping message to the remote party. 48 | * 49 | * @api public 50 | */ 51 | 52 | Sender.prototype.ping = function(data, options) { 53 | var mask = options && options.mask; 54 | this.frameAndSend(0x9, data || '', true, mask); 55 | } 56 | 57 | /** 58 | * Sends a pong message to the remote party. 59 | * 60 | * @api public 61 | */ 62 | 63 | Sender.prototype.pong = function(data, options) { 64 | var mask = options && options.mask; 65 | this.frameAndSend(0xa, data || '', true, mask); 66 | } 67 | 68 | /** 69 | * Sends text or binary data to the remote party. 70 | * 71 | * @api public 72 | */ 73 | 74 | Sender.prototype.send = function(data, options, cb) { 75 | var finalFragment = options && options.fin === false ? false : true; 76 | var mask = options && options.mask; 77 | var opcode = options && options.binary ? 2 : 1; 78 | if (this.firstFragment === false) opcode = 0; 79 | else this.firstFragment = false; 80 | if (finalFragment) this.firstFragment = true 81 | this.frameAndSend(opcode, data, finalFragment, mask, cb); 82 | } 83 | 84 | /** 85 | * Frames and sends a piece of data according to the HyBi WebSocket protocol. 86 | * 87 | * @api private 88 | */ 89 | 90 | Sender.prototype.frameAndSend = function(opcode, data, finalFragment, maskData, cb) { 91 | var canModifyData = false; 92 | 93 | if (!data) { 94 | try { 95 | this._socket.write(new Buffer([opcode | (finalFragment ? 0x80 : 0), 0 | (maskData ? 0x80 : 0)].concat(maskData ? [0, 0, 0, 0] : [])), 'binary', cb); 96 | } 97 | catch (e) { 98 | if (typeof cb == 'function') cb(e); 99 | else this.emit('error', e); 100 | } 101 | return; 102 | } 103 | 104 | if (!Buffer.isBuffer(data)) { 105 | canModifyData = true; 106 | data = (data && typeof data.buffer !== 'undefined') ? getArrayBuffer(data.buffer) : new Buffer(data); 107 | } 108 | 109 | var dataLength = data.length 110 | , dataOffset = maskData ? 6 : 2 111 | , secondByte = dataLength; 112 | 113 | if (dataLength >= 65536) { 114 | dataOffset += 8; 115 | secondByte = 127; 116 | } 117 | else if (dataLength > 125) { 118 | dataOffset += 2; 119 | secondByte = 126; 120 | } 121 | 122 | var mergeBuffers = dataLength < 32768 || (maskData && !canModifyData); 123 | var totalLength = mergeBuffers ? dataLength + dataOffset : dataOffset; 124 | var outputBuffer = new Buffer(totalLength); 125 | outputBuffer[0] = finalFragment ? opcode | 0x80 : opcode; 126 | 127 | switch (secondByte) { 128 | case 126: 129 | writeUInt16BE.call(outputBuffer, dataLength, 2); 130 | break; 131 | case 127: 132 | writeUInt32BE.call(outputBuffer, 0, 2); 133 | writeUInt32BE.call(outputBuffer, dataLength, 6); 134 | } 135 | 136 | if (maskData) { 137 | outputBuffer[1] = secondByte | 0x80; 138 | var mask = this._randomMask || (this._randomMask = getRandomMask()); 139 | outputBuffer[dataOffset - 4] = mask[0]; 140 | outputBuffer[dataOffset - 3] = mask[1]; 141 | outputBuffer[dataOffset - 2] = mask[2]; 142 | outputBuffer[dataOffset - 1] = mask[3]; 143 | if (mergeBuffers) { 144 | bufferUtil.mask(data, mask, outputBuffer, dataOffset, dataLength); 145 | try { 146 | this._socket.write(outputBuffer, 'binary', cb); 147 | } 148 | catch (e) { 149 | if (typeof cb == 'function') cb(e); 150 | else this.emit('error', e); 151 | } 152 | } 153 | else { 154 | bufferUtil.mask(data, mask, data, 0, dataLength); 155 | try { 156 | this._socket.write(outputBuffer, 'binary'); 157 | this._socket.write(data, 'binary', cb); 158 | } 159 | catch (e) { 160 | if (typeof cb == 'function') cb(e); 161 | else this.emit('error', e); 162 | } 163 | } 164 | } 165 | else { 166 | outputBuffer[1] = secondByte; 167 | if (mergeBuffers) { 168 | data.copy(outputBuffer, dataOffset); 169 | try { 170 | this._socket.write(outputBuffer, 'binary', cb); 171 | } 172 | catch (e) { 173 | if (typeof cb == 'function') cb(e); 174 | else this.emit('error', e); 175 | } 176 | } 177 | else { 178 | try { 179 | this._socket.write(outputBuffer, 'binary'); 180 | this._socket.write(data, 'binary', cb); 181 | } 182 | catch (e) { 183 | if (typeof cb == 'function') cb(e); 184 | else this.emit('error', e); 185 | } 186 | } 187 | } 188 | } 189 | 190 | module.exports = Sender; 191 | 192 | function writeUInt16BE(value, offset) { 193 | this[offset] = (value & 0xff00)>>8; 194 | this[offset+1] = value & 0xff; 195 | } 196 | 197 | function writeUInt32BE(value, offset) { 198 | this[offset] = (value & 0xff000000)>>24; 199 | this[offset+1] = (value & 0xff0000)>>16; 200 | this[offset+2] = (value & 0xff00)>>8; 201 | this[offset+3] = value & 0xff; 202 | } 203 | 204 | function getArrayBuffer(array) { 205 | var l = array.byteLength 206 | , buffer = new Buffer(l); 207 | for (var i = 0; i < l; ++i) { 208 | buffer[i] = array[i]; 209 | } 210 | return buffer; 211 | } 212 | 213 | function getRandomMask() { 214 | return new Buffer([ 215 | ~~(Math.random() * 255), 216 | ~~(Math.random() * 255), 217 | ~~(Math.random() * 255), 218 | ~~(Math.random() * 255) 219 | ]); 220 | } 221 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/Validation.fallback.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | module.exports.Validation = { 8 | isValidUTF8: function(buffer) { 9 | return true; 10 | } 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/Validation.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | try { 8 | module.exports = require('../build/Release/validation'); 9 | } catch (e) { try { 10 | module.exports = require('../build/default/validation'); 11 | } catch (e) { try { 12 | module.exports = require('./Validation.fallback'); 13 | } catch (e) { 14 | console.error('validation.node seems to not have been built. Run npm install.'); 15 | throw e; 16 | }}} 17 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/WebSocketServer.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | var util = require('util') 8 | , events = require('events') 9 | , http = require('http') 10 | , crypto = require('crypto') 11 | , url = require('url') 12 | , Options = require('options') 13 | , WebSocket = require('./WebSocket') 14 | , tls = require('tls') 15 | , url = require('url'); 16 | 17 | /** 18 | * WebSocket Server implementation 19 | */ 20 | 21 | function WebSocketServer(options, callback) { 22 | options = new Options({ 23 | host: '0.0.0.0', 24 | port: null, 25 | server: null, 26 | verifyClient: null, 27 | path: null, 28 | noServer: false, 29 | disableHixie: false, 30 | clientTracking: true 31 | }).merge(options); 32 | if (!options.value.port && !options.value.server && !options.value.noServer) { 33 | throw new TypeError('`port` or a `server` must be provided'); 34 | } 35 | 36 | var self = this; 37 | 38 | if (options.value.port) { 39 | this._server = http.createServer(function (req, res) { 40 | res.writeHead(200, {'Content-Type': 'text/plain'}); 41 | res.end('Not implemented'); 42 | }); 43 | this._server.listen(options.value.port, options.value.host, callback); 44 | this._closeServer = function() { self._server.close(); }; 45 | } 46 | else if (options.value.server) { 47 | this._server = options.value.server; 48 | if (options.value.path) { 49 | // take note of the path, to avoid collisions when multiple websocket servers are 50 | // listening on the same http server 51 | if (this._server._webSocketPaths && options.value.server._webSocketPaths[options.value.path]) { 52 | throw new Error('two instances of WebSocketServer cannot listen on the same http server path'); 53 | } 54 | if (typeof this._server._webSocketPaths !== 'object') { 55 | this._server._webSocketPaths = {}; 56 | } 57 | this._server._webSocketPaths[options.value.path] = 1; 58 | } 59 | } 60 | if (this._server) this._server.once('listening', function() { self.emit('listening'); }); 61 | 62 | if (typeof this._server != 'undefined') { 63 | this._server.on('error', function(error) { 64 | self.emit('error', error) 65 | }); 66 | this._server.on('upgrade', function(req, socket, upgradeHead) { 67 | self.handleUpgrade(req, socket, upgradeHead, function(client) { 68 | self.emit('connection'+req.url, client); 69 | self.emit('connection', client); 70 | }); 71 | }); 72 | } 73 | 74 | this.options = options.value; 75 | this.path = options.value.path; 76 | this.clients = []; 77 | } 78 | 79 | /** 80 | * Inherits from EventEmitter. 81 | */ 82 | 83 | util.inherits(WebSocketServer, events.EventEmitter); 84 | 85 | /** 86 | * Immediately shuts down the connection. 87 | * 88 | * @api public 89 | */ 90 | 91 | WebSocketServer.prototype.close = function() { 92 | // terminate all associated clients 93 | var error = null; 94 | try { 95 | for (var i = 0, l = this.clients.length; i < l; ++i) { 96 | this.clients[i].terminate(); 97 | } 98 | } 99 | catch (e) { 100 | error = e; 101 | } 102 | 103 | // remove path descriptor, if any 104 | if (this.path && this._server._webSocketPaths) { 105 | delete this._server._webSocketPaths[this.path]; 106 | if (Object.keys(this._server._webSocketPaths).length == 0) { 107 | delete this._server._webSocketPaths; 108 | } 109 | } 110 | 111 | // close the http server if it was internally created 112 | try { 113 | if (typeof this._closeServer !== 'undefined') { 114 | this._closeServer(); 115 | } 116 | } 117 | finally { 118 | delete this._server; 119 | } 120 | if (error) throw error; 121 | } 122 | 123 | /** 124 | * Handle a HTTP Upgrade request. 125 | * 126 | * @api public 127 | */ 128 | 129 | WebSocketServer.prototype.handleUpgrade = function(req, socket, upgradeHead, cb) { 130 | // check for wrong path 131 | if (this.options.path) { 132 | var u = url.parse(req.url); 133 | if (u && u.pathname !== this.options.path) return; 134 | } 135 | 136 | if (typeof req.headers.upgrade === 'undefined' || req.headers.upgrade.toLowerCase() !== 'websocket') { 137 | abortConnection(socket, 400, 'Bad Request'); 138 | return; 139 | } 140 | 141 | if (req.headers['sec-websocket-key1']) handleHixieUpgrade.apply(this, arguments); 142 | else handleHybiUpgrade.apply(this, arguments); 143 | } 144 | 145 | module.exports = WebSocketServer; 146 | 147 | /** 148 | * Entirely private apis, 149 | * which may or may not be bound to a sepcific WebSocket instance. 150 | */ 151 | 152 | function handleHybiUpgrade(req, socket, upgradeHead, cb) { 153 | // handle premature socket errors 154 | var errorHandler = function() { 155 | try { socket.destroy(); } catch (e) {} 156 | } 157 | socket.on('error', errorHandler); 158 | 159 | // verify key presence 160 | if (!req.headers['sec-websocket-key']) { 161 | abortConnection(socket, 400, 'Bad Request'); 162 | return; 163 | } 164 | 165 | // verify version 166 | var version = parseInt(req.headers['sec-websocket-version']); 167 | if ([8, 13].indexOf(version) === -1) { 168 | abortConnection(socket, 400, 'Bad Request'); 169 | return; 170 | } 171 | 172 | // verify client 173 | var origin = version < 13 ? 174 | req.headers['sec-websocket-origin'] : 175 | req.headers['origin']; 176 | 177 | // handler to call when the connection sequence completes 178 | var self = this; 179 | var completeHybiUpgrade = function() { 180 | var protocol = req.headers['sec-websocket-protocol']; 181 | 182 | // calc key 183 | var key = req.headers['sec-websocket-key']; 184 | var shasum = crypto.createHash('sha1'); 185 | shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); 186 | key = shasum.digest('base64'); 187 | 188 | var headers = [ 189 | 'HTTP/1.1 101 Switching Protocols' 190 | , 'Upgrade: websocket' 191 | , 'Connection: Upgrade' 192 | , 'Sec-WebSocket-Accept: ' + key 193 | ]; 194 | 195 | if (typeof protocol != 'undefined') { 196 | headers.push('Sec-WebSocket-Protocol: ' + protocol); 197 | } 198 | 199 | // allows external modification/inspection of handshake headers 200 | self.emit('headers', headers); 201 | 202 | socket.setTimeout(0); 203 | socket.setNoDelay(true); 204 | try { 205 | socket.write(headers.concat('', '').join('\r\n')); 206 | } 207 | catch (e) { 208 | // if the upgrade write fails, shut the connection down hard 209 | try { socket.destroy(); } catch (e) {} 210 | return; 211 | } 212 | 213 | var client = new WebSocket([req, socket, upgradeHead], { 214 | protocolVersion: version, 215 | protocol: protocol 216 | }); 217 | 218 | if (self.options.clientTracking) { 219 | self.clients.push(client); 220 | client.on('close', function() { 221 | var index = self.clients.indexOf(client); 222 | if (index != -1) { 223 | self.clients.splice(index, 1); 224 | } 225 | }); 226 | } 227 | 228 | // signal upgrade complete 229 | socket.removeListener('error', errorHandler); 230 | cb(client); 231 | } 232 | 233 | // optionally call external client verification handler 234 | if (typeof this.options.verifyClient == 'function') { 235 | var info = { 236 | origin: origin, 237 | secure: typeof req.connection.encrypted !== 'undefined', 238 | req: req 239 | }; 240 | if (this.options.verifyClient.length == 2) { 241 | this.options.verifyClient(info, function(result) { 242 | if (!result) abortConnection(socket, 401, 'Unauthorized') 243 | else completeHybiUpgrade(); 244 | }); 245 | return; 246 | } 247 | else if (!this.options.verifyClient(info)) { 248 | abortConnection(socket, 401, 'Unauthorized'); 249 | return; 250 | } 251 | } 252 | 253 | completeHybiUpgrade(); 254 | } 255 | 256 | function handleHixieUpgrade(req, socket, upgradeHead, cb) { 257 | // handle premature socket errors 258 | var errorHandler = function() { 259 | try { socket.destroy(); } catch (e) {} 260 | } 261 | socket.on('error', errorHandler); 262 | 263 | // bail if options prevent hixie 264 | if (this.options.disableHixie) { 265 | abortConnection(socket, 401, 'Hixie support disabled'); 266 | return; 267 | } 268 | 269 | // verify key presence 270 | if (!req.headers['sec-websocket-key2']) { 271 | abortConnection(socket, 400, 'Bad Request'); 272 | return; 273 | } 274 | 275 | var origin = req.headers['origin'] 276 | , self = this; 277 | 278 | // setup handshake completion to run after client has been verified 279 | var onClientVerified = function() { 280 | var wshost; 281 | if (!req.headers['x-forwarded-host']) 282 | wshost = req.headers.host; 283 | else 284 | wshost = req.headers['x-forwarded-host']; 285 | var location = ((req.headers['x-forwarded-proto'] === 'https' || socket.encrypted) ? 'wss' : 'ws') + '://' + wshost + req.url 286 | , protocol = req.headers['sec-websocket-protocol']; 287 | 288 | // handshake completion code to run once nonce has been successfully retrieved 289 | var completeHandshake = function(nonce, rest) { 290 | // calculate key 291 | var k1 = req.headers['sec-websocket-key1'] 292 | , k2 = req.headers['sec-websocket-key2'] 293 | , md5 = crypto.createHash('md5'); 294 | 295 | [k1, k2].forEach(function (k) { 296 | var n = parseInt(k.replace(/[^\d]/g, '')) 297 | , spaces = k.replace(/[^ ]/g, '').length; 298 | if (spaces === 0 || n % spaces !== 0){ 299 | abortConnection(socket, 400, 'Bad Request'); 300 | return; 301 | } 302 | n /= spaces; 303 | md5.update(String.fromCharCode( 304 | n >> 24 & 0xFF, 305 | n >> 16 & 0xFF, 306 | n >> 8 & 0xFF, 307 | n & 0xFF)); 308 | }); 309 | md5.update(nonce.toString('binary')); 310 | 311 | var headers = [ 312 | 'HTTP/1.1 101 Switching Protocols' 313 | , 'Upgrade: WebSocket' 314 | , 'Connection: Upgrade' 315 | , 'Sec-WebSocket-Location: ' + location 316 | ]; 317 | if (typeof protocol != 'undefined') headers.push('Sec-WebSocket-Protocol: ' + protocol); 318 | if (typeof origin != 'undefined') headers.push('Sec-WebSocket-Origin: ' + origin); 319 | 320 | socket.setTimeout(0); 321 | socket.setNoDelay(true); 322 | try { 323 | // merge header and hash buffer 324 | var headerBuffer = new Buffer(headers.concat('', '').join('\r\n')); 325 | var hashBuffer = new Buffer(md5.digest('binary'), 'binary'); 326 | var handshakeBuffer = new Buffer(headerBuffer.length + hashBuffer.length); 327 | headerBuffer.copy(handshakeBuffer, 0); 328 | hashBuffer.copy(handshakeBuffer, headerBuffer.length); 329 | 330 | // do a single write, which - upon success - causes a new client websocket to be setup 331 | socket.write(handshakeBuffer, 'binary', function(err) { 332 | if (err) return; // do not create client if an error happens 333 | var client = new WebSocket([req, socket, rest], { 334 | protocolVersion: 'hixie-76', 335 | protocol: protocol 336 | }); 337 | if (self.options.clientTracking) { 338 | self.clients.push(client); 339 | client.on('close', function() { 340 | var index = self.clients.indexOf(client); 341 | if (index != -1) { 342 | self.clients.splice(index, 1); 343 | } 344 | }); 345 | } 346 | 347 | // signal upgrade complete 348 | socket.removeListener('error', errorHandler); 349 | cb(client); 350 | }); 351 | } 352 | catch (e) { 353 | try { socket.destroy(); } catch (e) {} 354 | return; 355 | } 356 | } 357 | 358 | // retrieve nonce 359 | var nonceLength = 8; 360 | if (upgradeHead && upgradeHead.length >= nonceLength) { 361 | var nonce = upgradeHead.slice(0, nonceLength); 362 | var rest = upgradeHead.length > nonceLength ? upgradeHead.slice(nonceLength) : null; 363 | completeHandshake.call(self, nonce, rest); 364 | } 365 | else { 366 | // nonce not present in upgradeHead, so we must wait for enough data 367 | // data to arrive before continuing 368 | var nonce = new Buffer(nonceLength); 369 | upgradeHead.copy(nonce, 0); 370 | var received = upgradeHead.length; 371 | var rest = null; 372 | var handler = function (data) { 373 | var toRead = Math.min(data.length, nonceLength - received); 374 | if (toRead === 0) return; 375 | data.copy(nonce, received, 0, toRead); 376 | received += toRead; 377 | if (received == nonceLength) { 378 | socket.removeListener('data', handler); 379 | if (toRead < data.length) rest = data.slice(toRead); 380 | completeHandshake.call(self, nonce, rest); 381 | } 382 | } 383 | socket.on('data', handler); 384 | } 385 | } 386 | 387 | // verify client 388 | if (typeof this.options.verifyClient == 'function') { 389 | var info = { 390 | origin: origin, 391 | secure: typeof req.connection.encrypted !== 'undefined', 392 | req: req 393 | }; 394 | if (this.options.verifyClient.length == 2) { 395 | var self = this; 396 | this.options.verifyClient(info, function(result) { 397 | if (!result) abortConnection(socket, 401, 'Unauthorized') 398 | else onClientVerified.apply(self); 399 | }); 400 | return; 401 | } 402 | else if (!this.options.verifyClient(info)) { 403 | abortConnection(socket, 401, 'Unauthorized'); 404 | return; 405 | } 406 | } 407 | 408 | // no client verification required 409 | onClientVerified(); 410 | } 411 | 412 | function abortConnection(socket, code, name) { 413 | try { 414 | var response = [ 415 | 'HTTP/1.1 ' + code + ' ' + name, 416 | 'Content-type: text/html' 417 | ]; 418 | socket.write(response.concat('', '').join('\r\n')); 419 | } 420 | catch (e) { /* ignore errors - we've aborted this connection */ } 421 | finally { 422 | // ensure that an early aborted connection is shut down completely 423 | try { socket.destroy(); } catch (e) {} 424 | } 425 | } 426 | -------------------------------------------------------------------------------- /server/node_modules/ws/lib/browser.js: -------------------------------------------------------------------------------- 1 | /// shim for browser packaging 2 | 3 | module.exports = function() { 4 | return global.WebSocket || global.MozWebSocket; 5 | } 6 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/commander/.npmignore: -------------------------------------------------------------------------------- 1 | support 2 | test 3 | examples 4 | *.sock 5 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/commander/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.4 4 | - 0.6 5 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/commander/History.md: -------------------------------------------------------------------------------- 1 | 2 | 0.6.1 / 2012-06-01 3 | ================== 4 | 5 | * Added: append (yes or no) on confirmation 6 | * Added: allow node.js v0.7.x 7 | 8 | 0.6.0 / 2012-04-10 9 | ================== 10 | 11 | * Added `.prompt(obj, callback)` support. Closes #49 12 | * Added default support to .choose(). Closes #41 13 | * Fixed the choice example 14 | 15 | 0.5.1 / 2011-12-20 16 | ================== 17 | 18 | * Fixed `password()` for recent nodes. Closes #36 19 | 20 | 0.5.0 / 2011-12-04 21 | ================== 22 | 23 | * Added sub-command option support [itay] 24 | 25 | 0.4.3 / 2011-12-04 26 | ================== 27 | 28 | * Fixed custom help ordering. Closes #32 29 | 30 | 0.4.2 / 2011-11-24 31 | ================== 32 | 33 | * Added travis support 34 | * Fixed: line-buffered input automatically trimmed. Closes #31 35 | 36 | 0.4.1 / 2011-11-18 37 | ================== 38 | 39 | * Removed listening for "close" on --help 40 | 41 | 0.4.0 / 2011-11-15 42 | ================== 43 | 44 | * Added support for `--`. Closes #24 45 | 46 | 0.3.3 / 2011-11-14 47 | ================== 48 | 49 | * Fixed: wait for close event when writing help info [Jerry Hamlet] 50 | 51 | 0.3.2 / 2011-11-01 52 | ================== 53 | 54 | * Fixed long flag definitions with values [felixge] 55 | 56 | 0.3.1 / 2011-10-31 57 | ================== 58 | 59 | * Changed `--version` short flag to `-V` from `-v` 60 | * Changed `.version()` so it's configurable [felixge] 61 | 62 | 0.3.0 / 2011-10-31 63 | ================== 64 | 65 | * Added support for long flags only. Closes #18 66 | 67 | 0.2.1 / 2011-10-24 68 | ================== 69 | 70 | * "node": ">= 0.4.x < 0.7.0". Closes #20 71 | 72 | 0.2.0 / 2011-09-26 73 | ================== 74 | 75 | * Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs] 76 | 77 | 0.1.0 / 2011-08-24 78 | ================== 79 | 80 | * Added support for custom `--help` output 81 | 82 | 0.0.5 / 2011-08-18 83 | ================== 84 | 85 | * Changed: when the user enters nothing prompt for password again 86 | * Fixed issue with passwords beginning with numbers [NuckChorris] 87 | 88 | 0.0.4 / 2011-08-15 89 | ================== 90 | 91 | * Fixed `Commander#args` 92 | 93 | 0.0.3 / 2011-08-15 94 | ================== 95 | 96 | * Added default option value support 97 | 98 | 0.0.2 / 2011-08-15 99 | ================== 100 | 101 | * Added mask support to `Command#password(str[, mask], fn)` 102 | * Added `Command#password(str, fn)` 103 | 104 | 0.0.1 / 2010-01-03 105 | ================== 106 | 107 | * Initial release 108 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/commander/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TESTS = $(shell find test/test.*.js) 3 | 4 | test: 5 | @./test/run $(TESTS) 6 | 7 | .PHONY: test -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/commander/Readme.md: -------------------------------------------------------------------------------- 1 | # Commander.js 2 | 3 | The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander). 4 | 5 | [![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js) 6 | 7 | ## Installation 8 | 9 | $ npm install commander 10 | 11 | ## Option parsing 12 | 13 | Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options. 14 | 15 | ```js 16 | #!/usr/bin/env node 17 | 18 | /** 19 | * Module dependencies. 20 | */ 21 | 22 | var program = require('commander'); 23 | 24 | program 25 | .version('0.0.1') 26 | .option('-p, --peppers', 'Add peppers') 27 | .option('-P, --pineapple', 'Add pineapple') 28 | .option('-b, --bbq', 'Add bbq sauce') 29 | .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble') 30 | .parse(process.argv); 31 | 32 | console.log('you ordered a pizza with:'); 33 | if (program.peppers) console.log(' - peppers'); 34 | if (program.pineapple) console.log(' - pineappe'); 35 | if (program.bbq) console.log(' - bbq'); 36 | console.log(' - %s cheese', program.cheese); 37 | ``` 38 | 39 | Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc. 40 | 41 | ## Automated --help 42 | 43 | The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free: 44 | 45 | ``` 46 | $ ./examples/pizza --help 47 | 48 | Usage: pizza [options] 49 | 50 | Options: 51 | 52 | -V, --version output the version number 53 | -p, --peppers Add peppers 54 | -P, --pineapple Add pineappe 55 | -b, --bbq Add bbq sauce 56 | -c, --cheese Add the specified type of cheese [marble] 57 | -h, --help output usage information 58 | 59 | ``` 60 | 61 | ## Coercion 62 | 63 | ```js 64 | function range(val) { 65 | return val.split('..').map(Number); 66 | } 67 | 68 | function list(val) { 69 | return val.split(','); 70 | } 71 | 72 | program 73 | .version('0.0.1') 74 | .usage('[options] ') 75 | .option('-i, --integer ', 'An integer argument', parseInt) 76 | .option('-f, --float ', 'A float argument', parseFloat) 77 | .option('-r, --range ..', 'A range', range) 78 | .option('-l, --list ', 'A list', list) 79 | .option('-o, --optional [value]', 'An optional value') 80 | .parse(process.argv); 81 | 82 | console.log(' int: %j', program.integer); 83 | console.log(' float: %j', program.float); 84 | console.log(' optional: %j', program.optional); 85 | program.range = program.range || []; 86 | console.log(' range: %j..%j', program.range[0], program.range[1]); 87 | console.log(' list: %j', program.list); 88 | console.log(' args: %j', program.args); 89 | ``` 90 | 91 | ## Custom help 92 | 93 | You can display arbitrary `-h, --help` information 94 | by listening for "--help". Commander will automatically 95 | exit once you are done so that the remainder of your program 96 | does not execute causing undesired behaviours, for example 97 | in the following executable "stuff" will not output when 98 | `--help` is used. 99 | 100 | ```js 101 | #!/usr/bin/env node 102 | 103 | /** 104 | * Module dependencies. 105 | */ 106 | 107 | var program = require('../'); 108 | 109 | function list(val) { 110 | return val.split(',').map(Number); 111 | } 112 | 113 | program 114 | .version('0.0.1') 115 | .option('-f, --foo', 'enable some foo') 116 | .option('-b, --bar', 'enable some bar') 117 | .option('-B, --baz', 'enable some baz'); 118 | 119 | // must be before .parse() since 120 | // node's emit() is immediate 121 | 122 | program.on('--help', function(){ 123 | console.log(' Examples:'); 124 | console.log(''); 125 | console.log(' $ custom-help --help'); 126 | console.log(' $ custom-help -h'); 127 | console.log(''); 128 | }); 129 | 130 | program.parse(process.argv); 131 | 132 | console.log('stuff'); 133 | ``` 134 | 135 | yielding the following help output: 136 | 137 | ``` 138 | 139 | Usage: custom-help [options] 140 | 141 | Options: 142 | 143 | -h, --help output usage information 144 | -V, --version output the version number 145 | -f, --foo enable some foo 146 | -b, --bar enable some bar 147 | -B, --baz enable some baz 148 | 149 | Examples: 150 | 151 | $ custom-help --help 152 | $ custom-help -h 153 | 154 | ``` 155 | 156 | ## .prompt(msg, fn) 157 | 158 | Single-line prompt: 159 | 160 | ```js 161 | program.prompt('name: ', function(name){ 162 | console.log('hi %s', name); 163 | }); 164 | ``` 165 | 166 | Multi-line prompt: 167 | 168 | ```js 169 | program.prompt('description:', function(name){ 170 | console.log('hi %s', name); 171 | }); 172 | ``` 173 | 174 | Coercion: 175 | 176 | ```js 177 | program.prompt('Age: ', Number, function(age){ 178 | console.log('age: %j', age); 179 | }); 180 | ``` 181 | 182 | ```js 183 | program.prompt('Birthdate: ', Date, function(date){ 184 | console.log('date: %s', date); 185 | }); 186 | ``` 187 | 188 | ## .password(msg[, mask], fn) 189 | 190 | Prompt for password without echoing: 191 | 192 | ```js 193 | program.password('Password: ', function(pass){ 194 | console.log('got "%s"', pass); 195 | process.stdin.destroy(); 196 | }); 197 | ``` 198 | 199 | Prompt for password with mask char "*": 200 | 201 | ```js 202 | program.password('Password: ', '*', function(pass){ 203 | console.log('got "%s"', pass); 204 | process.stdin.destroy(); 205 | }); 206 | ``` 207 | 208 | ## .confirm(msg, fn) 209 | 210 | Confirm with the given `msg`: 211 | 212 | ```js 213 | program.confirm('continue? ', function(ok){ 214 | console.log(' got %j', ok); 215 | }); 216 | ``` 217 | 218 | ## .choose(list, fn) 219 | 220 | Let the user choose from a `list`: 221 | 222 | ```js 223 | var list = ['tobi', 'loki', 'jane', 'manny', 'luna']; 224 | 225 | console.log('Choose the coolest pet:'); 226 | program.choose(list, function(i){ 227 | console.log('you chose %d "%s"', i, list[i]); 228 | }); 229 | ``` 230 | 231 | ## Links 232 | 233 | - [API documentation](http://visionmedia.github.com/commander.js/) 234 | - [ascii tables](https://github.com/LearnBoost/cli-table) 235 | - [progress bars](https://github.com/visionmedia/node-progress) 236 | - [more progress bars](https://github.com/substack/node-multimeter) 237 | - [examples](https://github.com/visionmedia/commander.js/tree/master/examples) 238 | 239 | ## License 240 | 241 | (The MIT License) 242 | 243 | Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> 244 | 245 | Permission is hereby granted, free of charge, to any person obtaining 246 | a copy of this software and associated documentation files (the 247 | 'Software'), to deal in the Software without restriction, including 248 | without limitation the rights to use, copy, modify, merge, publish, 249 | distribute, sublicense, and/or sell copies of the Software, and to 250 | permit persons to whom the Software is furnished to do so, subject to 251 | the following conditions: 252 | 253 | The above copyright notice and this permission notice shall be 254 | included in all copies or substantial portions of the Software. 255 | 256 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 257 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 258 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 259 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 260 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 261 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 262 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/commander/index.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = require('./lib/commander'); -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/commander/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commander", 3 | "version": "0.6.1", 4 | "description": "the complete solution for node.js command-line programs", 5 | "keywords": [ 6 | "command", 7 | "option", 8 | "parser", 9 | "prompt", 10 | "stdin" 11 | ], 12 | "author": { 13 | "name": "TJ Holowaychuk", 14 | "email": "tj@vision-media.ca" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/visionmedia/commander.js.git" 19 | }, 20 | "dependencies": {}, 21 | "devDependencies": { 22 | "should": ">= 0.0.1" 23 | }, 24 | "scripts": { 25 | "test": "make test" 26 | }, 27 | "main": "index", 28 | "engines": { 29 | "node": ">= 0.4.x" 30 | }, 31 | "readme": "# Commander.js\n\n The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander).\n\n [![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js)\n\n## Installation\n\n $ npm install commander\n\n## Option parsing\n\n Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.\n\n```js\n#!/usr/bin/env node\n\n/**\n * Module dependencies.\n */\n\nvar program = require('commander');\n\nprogram\n .version('0.0.1')\n .option('-p, --peppers', 'Add peppers')\n .option('-P, --pineapple', 'Add pineapple')\n .option('-b, --bbq', 'Add bbq sauce')\n .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')\n .parse(process.argv);\n\nconsole.log('you ordered a pizza with:');\nif (program.peppers) console.log(' - peppers');\nif (program.pineapple) console.log(' - pineappe');\nif (program.bbq) console.log(' - bbq');\nconsole.log(' - %s cheese', program.cheese);\n```\n\n Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as \"--template-engine\" are camel-cased, becoming `program.templateEngine` etc.\n\n## Automated --help\n\n The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:\n\n``` \n $ ./examples/pizza --help\n\n Usage: pizza [options]\n\n Options:\n\n -V, --version output the version number\n -p, --peppers Add peppers\n -P, --pineapple Add pineappe\n -b, --bbq Add bbq sauce\n -c, --cheese Add the specified type of cheese [marble]\n -h, --help output usage information\n\n```\n\n## Coercion\n\n```js\nfunction range(val) {\n return val.split('..').map(Number);\n}\n\nfunction list(val) {\n return val.split(',');\n}\n\nprogram\n .version('0.0.1')\n .usage('[options] ')\n .option('-i, --integer ', 'An integer argument', parseInt)\n .option('-f, --float ', 'A float argument', parseFloat)\n .option('-r, --range ..', 'A range', range)\n .option('-l, --list ', 'A list', list)\n .option('-o, --optional [value]', 'An optional value')\n .parse(process.argv);\n\nconsole.log(' int: %j', program.integer);\nconsole.log(' float: %j', program.float);\nconsole.log(' optional: %j', program.optional);\nprogram.range = program.range || [];\nconsole.log(' range: %j..%j', program.range[0], program.range[1]);\nconsole.log(' list: %j', program.list);\nconsole.log(' args: %j', program.args);\n```\n\n## Custom help\n\n You can display arbitrary `-h, --help` information\n by listening for \"--help\". Commander will automatically\n exit once you are done so that the remainder of your program\n does not execute causing undesired behaviours, for example\n in the following executable \"stuff\" will not output when\n `--help` is used.\n\n```js\n#!/usr/bin/env node\n\n/**\n * Module dependencies.\n */\n\nvar program = require('../');\n\nfunction list(val) {\n return val.split(',').map(Number);\n}\n\nprogram\n .version('0.0.1')\n .option('-f, --foo', 'enable some foo')\n .option('-b, --bar', 'enable some bar')\n .option('-B, --baz', 'enable some baz');\n\n// must be before .parse() since\n// node's emit() is immediate\n\nprogram.on('--help', function(){\n console.log(' Examples:');\n console.log('');\n console.log(' $ custom-help --help');\n console.log(' $ custom-help -h');\n console.log('');\n});\n\nprogram.parse(process.argv);\n\nconsole.log('stuff');\n```\n\nyielding the following help output:\n\n```\n\nUsage: custom-help [options]\n\nOptions:\n\n -h, --help output usage information\n -V, --version output the version number\n -f, --foo enable some foo\n -b, --bar enable some bar\n -B, --baz enable some baz\n\nExamples:\n\n $ custom-help --help\n $ custom-help -h\n\n```\n\n## .prompt(msg, fn)\n\n Single-line prompt:\n\n```js\nprogram.prompt('name: ', function(name){\n console.log('hi %s', name);\n});\n```\n\n Multi-line prompt:\n\n```js\nprogram.prompt('description:', function(name){\n console.log('hi %s', name);\n});\n```\n\n Coercion:\n\n```js\nprogram.prompt('Age: ', Number, function(age){\n console.log('age: %j', age);\n});\n```\n\n```js\nprogram.prompt('Birthdate: ', Date, function(date){\n console.log('date: %s', date);\n});\n```\n\n## .password(msg[, mask], fn)\n\nPrompt for password without echoing:\n\n```js\nprogram.password('Password: ', function(pass){\n console.log('got \"%s\"', pass);\n process.stdin.destroy();\n});\n```\n\nPrompt for password with mask char \"*\":\n\n```js\nprogram.password('Password: ', '*', function(pass){\n console.log('got \"%s\"', pass);\n process.stdin.destroy();\n});\n```\n\n## .confirm(msg, fn)\n\n Confirm with the given `msg`:\n\n```js\nprogram.confirm('continue? ', function(ok){\n console.log(' got %j', ok);\n});\n```\n\n## .choose(list, fn)\n\n Let the user choose from a `list`:\n\n```js\nvar list = ['tobi', 'loki', 'jane', 'manny', 'luna'];\n\nconsole.log('Choose the coolest pet:');\nprogram.choose(list, function(i){\n console.log('you chose %d \"%s\"', i, list[i]);\n});\n```\n\n## Links\n\n - [API documentation](http://visionmedia.github.com/commander.js/)\n - [ascii tables](https://github.com/LearnBoost/cli-table)\n - [progress bars](https://github.com/visionmedia/node-progress)\n - [more progress bars](https://github.com/substack/node-multimeter)\n - [examples](https://github.com/visionmedia/commander.js/tree/master/examples)\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", 32 | "readmeFilename": "Readme.md", 33 | "bugs": { 34 | "url": "https://github.com/visionmedia/commander.js/issues" 35 | }, 36 | "_id": "commander@0.6.1", 37 | "dist": { 38 | "shasum": "21346295a341e5032e1cb9e64c1d7d7d5b99c405" 39 | }, 40 | "_from": "commander@~0.6.1", 41 | "_resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz" 42 | } 43 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/options/.npmignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | node_modules 3 | .*.swp 4 | .lock-* 5 | build/ 6 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/options/Makefile: -------------------------------------------------------------------------------- 1 | ALL_TESTS = $(shell find test/ -name '*.test.js') 2 | 3 | run-tests: 4 | @./node_modules/.bin/mocha \ 5 | -t 2000 \ 6 | $(TESTFLAGS) \ 7 | $(TESTS) 8 | 9 | test: 10 | @$(MAKE) NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests 11 | 12 | .PHONY: test 13 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/options/README.md: -------------------------------------------------------------------------------- 1 | # options.js # 2 | 3 | A very light-weight in-code option parsers for node.js. 4 | 5 | ## License ## 6 | 7 | (The MIT License) 8 | 9 | Copyright (c) 2012 Einar Otto Stangvik <einaros@gmail.com> 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining 12 | a copy of this software and associated documentation files (the 13 | 'Software'), to deal in the Software without restriction, including 14 | without limitation the rights to use, copy, modify, merge, publish, 15 | distribute, sublicense, and/or sell copies of the Software, and to 16 | permit persons to whom the Software is furnished to do so, subject to 17 | the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be 20 | included in all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 23 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 26 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 27 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 28 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/options/lib/options.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright(c) 2011 Einar Otto Stangvik 3 | * MIT Licensed 4 | */ 5 | 6 | var fs = require('fs'); 7 | 8 | function Options(defaults) { 9 | var internalValues = {}; 10 | var values = this.value = {}; 11 | Object.keys(defaults).forEach(function(key) { 12 | internalValues[key] = defaults[key]; 13 | Object.defineProperty(values, key, { 14 | get: function() { return internalValues[key]; }, 15 | configurable: false, 16 | enumerable: true 17 | }); 18 | }); 19 | this.reset = function() { 20 | Object.keys(defaults).forEach(function(key) { 21 | internalValues[key] = defaults[key]; 22 | }); 23 | return this; 24 | }; 25 | this.merge = function(options, required) { 26 | options = options || {}; 27 | if (Object.prototype.toString.call(required) === '[object Array]') { 28 | var missing = []; 29 | for (var i = 0, l = required.length; i < l; ++i) { 30 | var key = required[i]; 31 | if (!(key in options)) { 32 | missing.push(key); 33 | } 34 | } 35 | if (missing.length > 0) { 36 | if (missing.length > 1) { 37 | throw new Error('options ' + 38 | missing.slice(0, missing.length - 1).join(', ') + ' and ' + 39 | missing[missing.length - 1] + ' must be defined'); 40 | } 41 | else throw new Error('option ' + missing[0] + ' must be defined'); 42 | } 43 | } 44 | Object.keys(options).forEach(function(key) { 45 | if (key in internalValues) { 46 | internalValues[key] = options[key]; 47 | } 48 | }); 49 | return this; 50 | }; 51 | this.copy = function(keys) { 52 | var obj = {}; 53 | Object.keys(defaults).forEach(function(key) { 54 | if (keys.indexOf(key) !== -1) { 55 | obj[key] = values[key]; 56 | } 57 | }); 58 | return obj; 59 | }; 60 | this.read = function(filename, cb) { 61 | if (typeof cb == 'function') { 62 | var self = this; 63 | fs.readFile(filename, function(error, data) { 64 | if (error) return cb(error); 65 | var conf = JSON.parse(data); 66 | self.merge(conf); 67 | cb(); 68 | }); 69 | } 70 | else { 71 | var conf = JSON.parse(fs.readFileSync(filename)); 72 | this.merge(conf); 73 | } 74 | return this; 75 | }; 76 | this.isDefined = function(key) { 77 | return typeof values[key] != 'undefined'; 78 | }; 79 | this.isDefinedAndNonNull = function(key) { 80 | return typeof values[key] != 'undefined' && values[key] !== null; 81 | }; 82 | Object.freeze(values); 83 | Object.freeze(this); 84 | } 85 | 86 | module.exports = Options; 87 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/options/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": { 3 | "name": "Einar Otto Stangvik", 4 | "email": "einaros@gmail.com", 5 | "url": "http://2x.io" 6 | }, 7 | "name": "options", 8 | "description": "A very light-weight in-code option parsers for node.js.", 9 | "version": "0.0.5", 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/einaros/options.js.git" 13 | }, 14 | "main": "lib/options", 15 | "scripts": { 16 | "test": "make test" 17 | }, 18 | "engines": { 19 | "node": ">=0.4.0" 20 | }, 21 | "dependencies": {}, 22 | "devDependencies": { 23 | "mocha": "latest" 24 | }, 25 | "readme": "# options.js #\n\nA very light-weight in-code option parsers for node.js.\n\n## License ##\n\n(The MIT License)\n\nCopyright (c) 2012 Einar Otto Stangvik <einaros@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", 26 | "readmeFilename": "README.md", 27 | "bugs": { 28 | "url": "https://github.com/einaros/options.js/issues" 29 | }, 30 | "_id": "options@0.0.5", 31 | "dist": { 32 | "shasum": "b92acd56877f43be9e6de3e777371f60268a6f1d" 33 | }, 34 | "_from": "options@latest", 35 | "_resolved": "https://registry.npmjs.org/options/-/options-0.0.5.tgz" 36 | } 37 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/options/test/fixtures/test.conf: -------------------------------------------------------------------------------- 1 | { 2 | "a": "foobar", 3 | "b": false 4 | } -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/options/test/options.test.js: -------------------------------------------------------------------------------- 1 | var Options = require('options') 2 | , assert = require('assert'); 3 | 4 | describe('Options', function() { 5 | describe('#ctor', function() { 6 | it('initializes options', function() { 7 | var option = new Options({a: true, b: false}); 8 | assert.strictEqual(true, option.value.a); 9 | assert.strictEqual(false, option.value.b); 10 | }); 11 | }); 12 | 13 | describe('#merge', function() { 14 | it('merges options from another object', function() { 15 | var option = new Options({a: true, b: false}); 16 | option.merge({b: true}); 17 | assert.strictEqual(true, option.value.a); 18 | assert.strictEqual(true, option.value.b); 19 | }); 20 | it('does nothing when arguments are undefined', function() { 21 | var option = new Options({a: true, b: false}); 22 | option.merge(undefined); 23 | assert.strictEqual(true, option.value.a); 24 | assert.strictEqual(false, option.value.b); 25 | }); 26 | it('cannot set values that werent already there', function() { 27 | var option = new Options({a: true, b: false}); 28 | option.merge({c: true}); 29 | assert.strictEqual('undefined', typeof option.value.c); 30 | }); 31 | it('can require certain options to be defined', function() { 32 | var option = new Options({a: true, b: false, c: 3}); 33 | var caughtException = false; 34 | try { 35 | option.merge({}, ['a', 'b', 'c']); 36 | } 37 | catch (e) { 38 | caughtException = e.toString() == 'Error: options a, b and c must be defined'; 39 | } 40 | assert.strictEqual(true, caughtException); 41 | }); 42 | it('can require certain options to be defined, when options are undefined', function() { 43 | var option = new Options({a: true, b: false, c: 3}); 44 | var caughtException = false; 45 | try { 46 | option.merge(undefined, ['a', 'b', 'c']); 47 | } 48 | catch (e) { 49 | caughtException = e.toString() == 'Error: options a, b and c must be defined'; 50 | } 51 | assert.strictEqual(true, caughtException); 52 | }); 53 | it('returns "this"', function() { 54 | var option = new Options({a: true, b: false, c: 3}); 55 | assert.strictEqual(option, option.merge()); 56 | }); 57 | }); 58 | 59 | describe('#copy', function() { 60 | it('returns a new object with the indicated options', function() { 61 | var option = new Options({a: true, b: false, c: 3}); 62 | option.merge({c: 4}); 63 | var obj = option.copy(['a', 'c']); 64 | assert.strictEqual(true, obj.a); 65 | assert.strictEqual(4, obj.c); 66 | assert.strictEqual('undefined', typeof obj.b); 67 | }); 68 | }); 69 | 70 | describe('#value', function() { 71 | it('can be enumerated', function() { 72 | var option = new Options({a: true, b: false}); 73 | assert.strictEqual(2, Object.keys(option.value).length); 74 | }); 75 | it('can not be used to set values', function() { 76 | var option = new Options({a: true, b: false}); 77 | option.value.b = true; 78 | assert.strictEqual(false, option.value.b); 79 | }); 80 | it('can not be used to add values', function() { 81 | var option = new Options({a: true, b: false}); 82 | option.value.c = 3; 83 | assert.strictEqual('undefined', typeof option.value.c); 84 | }); 85 | }); 86 | 87 | describe('#isDefined', function() { 88 | it('returns true if the named value is defined', function() { 89 | var option = new Options({a: undefined}); 90 | assert.strictEqual(false, option.isDefined('a')); 91 | option.merge({a: false}); 92 | assert.strictEqual(true, option.isDefined('a')); 93 | }); 94 | }); 95 | 96 | describe('#isDefinedAndNonNull', function() { 97 | it('returns true if the named value is defined and non-null', function() { 98 | var option = new Options({a: undefined}); 99 | assert.strictEqual(false, option.isDefinedAndNonNull('a')); 100 | option.merge({a: null}); 101 | assert.strictEqual(false, option.isDefinedAndNonNull('a')); 102 | option.merge({a: 2}); 103 | assert.strictEqual(true, option.isDefinedAndNonNull('a')); 104 | }); 105 | }); 106 | 107 | describe('#read', function() { 108 | it('reads and merges config from a file', function() { 109 | var option = new Options({a: true, b: true}); 110 | option.read(__dirname + '/fixtures/test.conf'); 111 | assert.strictEqual('foobar', option.value.a); 112 | assert.strictEqual(false, option.value.b); 113 | }); 114 | 115 | it('asynchronously reads and merges config from a file when a callback is passed', function(done) { 116 | var option = new Options({a: true, b: true}); 117 | option.read(__dirname + '/fixtures/test.conf', function(error) { 118 | assert.strictEqual('foobar', option.value.a); 119 | assert.strictEqual(false, option.value.b); 120 | done(); 121 | }); 122 | }); 123 | }); 124 | 125 | describe('#reset', function() { 126 | it('resets options to defaults', function() { 127 | var option = new Options({a: true, b: false}); 128 | option.merge({b: true}); 129 | assert.strictEqual(true, option.value.b); 130 | option.reset(); 131 | assert.strictEqual(false, option.value.b); 132 | }); 133 | }); 134 | 135 | it('is immutable', function() { 136 | var option = new Options({a: true, b: false}); 137 | option.foo = 2; 138 | assert.strictEqual('undefined', typeof option.foo); 139 | }); 140 | }); 141 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/tinycolor/.npmignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | node_modules 3 | .*.swp 4 | .lock-* 5 | build/ 6 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/tinycolor/README.md: -------------------------------------------------------------------------------- 1 | # tinycolor # 2 | 3 | This is a no-fuzz, barebone, zero muppetry color module for node.js. -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/tinycolor/example.js: -------------------------------------------------------------------------------- 1 | require('./tinycolor'); 2 | console.log('this should be red and have an underline!'.grey.underline); 3 | console.log('this should have a blue background!'.bgBlue); -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/tinycolor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": { 3 | "name": "Einar Otto Stangvik", 4 | "email": "einaros@gmail.com", 5 | "url": "http://2x.io" 6 | }, 7 | "name": "tinycolor", 8 | "description": "a to-the-point color module for node", 9 | "version": "0.0.1", 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/einaros/tinycolor.git" 13 | }, 14 | "engines": { 15 | "node": ">=0.4.0" 16 | }, 17 | "dependencies": {}, 18 | "devDependencies": {}, 19 | "main": "tinycolor", 20 | "readme": "# tinycolor #\n\nThis is a no-fuzz, barebone, zero muppetry color module for node.js.", 21 | "readmeFilename": "README.md", 22 | "bugs": { 23 | "url": "https://github.com/einaros/tinycolor/issues" 24 | }, 25 | "_id": "tinycolor@0.0.1", 26 | "dist": { 27 | "shasum": "875d47e599aeabb0caa64275c7b839d4ae6f796c" 28 | }, 29 | "_from": "tinycolor@0.x", 30 | "_resolved": "https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz" 31 | } 32 | -------------------------------------------------------------------------------- /server/node_modules/ws/node_modules/tinycolor/tinycolor.js: -------------------------------------------------------------------------------- 1 | var styles = { 2 | 'bold': ['\033[1m', '\033[22m'], 3 | 'italic': ['\033[3m', '\033[23m'], 4 | 'underline': ['\033[4m', '\033[24m'], 5 | 'inverse': ['\033[7m', '\033[27m'], 6 | 'black': ['\033[30m', '\033[39m'], 7 | 'red': ['\033[31m', '\033[39m'], 8 | 'green': ['\033[32m', '\033[39m'], 9 | 'yellow': ['\033[33m', '\033[39m'], 10 | 'blue': ['\033[34m', '\033[39m'], 11 | 'magenta': ['\033[35m', '\033[39m'], 12 | 'cyan': ['\033[36m', '\033[39m'], 13 | 'white': ['\033[37m', '\033[39m'], 14 | 'default': ['\033[39m', '\033[39m'], 15 | 'grey': ['\033[90m', '\033[39m'], 16 | 'bgBlack': ['\033[40m', '\033[49m'], 17 | 'bgRed': ['\033[41m', '\033[49m'], 18 | 'bgGreen': ['\033[42m', '\033[49m'], 19 | 'bgYellow': ['\033[43m', '\033[49m'], 20 | 'bgBlue': ['\033[44m', '\033[49m'], 21 | 'bgMagenta': ['\033[45m', '\033[49m'], 22 | 'bgCyan': ['\033[46m', '\033[49m'], 23 | 'bgWhite': ['\033[47m', '\033[49m'], 24 | 'bgDefault': ['\033[49m', '\033[49m'] 25 | } 26 | Object.keys(styles).forEach(function(style) { 27 | Object.defineProperty(String.prototype, style, { 28 | get: function() { return styles[style][0] + this + styles[style][1]; }, 29 | enumerable: false 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /server/node_modules/ws/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": { 3 | "name": "Einar Otto Stangvik", 4 | "email": "einaros@gmail.com", 5 | "url": "http://2x.io" 6 | }, 7 | "name": "ws", 8 | "description": "simple to use, blazing fast and thoroughly tested websocket client, server and console for node.js, up-to-date against RFC-6455", 9 | "version": "0.4.25", 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/einaros/ws.git" 13 | }, 14 | "bin": { 15 | "wscat": "./bin/wscat" 16 | }, 17 | "scripts": { 18 | "test": "make test", 19 | "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)" 20 | }, 21 | "engines": { 22 | "node": ">=0.4.0" 23 | }, 24 | "dependencies": { 25 | "commander": "~0.6.1", 26 | "tinycolor": "0.x", 27 | "options": "latest" 28 | }, 29 | "devDependencies": { 30 | "mocha": "~1.2.1", 31 | "should": "0.6.x", 32 | "expect.js": "0.1.x", 33 | "benchmark": "0.3.x", 34 | "ansi": "latest" 35 | }, 36 | "browser": { 37 | "./index.js": "./lib/browser.js" 38 | }, 39 | "readme": "[![Build Status](https://secure.travis-ci.org/einaros/ws.png)](http://travis-ci.org/einaros/ws)\n\n# ws: a node.js websocket library #\n\n`ws` is a simple to use websocket implementation, up-to-date against RFC-6455, and [probably the fastest WebSocket library for node.js](http://hobbycoding.posterous.com/the-fastest-websocket-module-for-nodejs).\n\nPasses the quite extensive Autobahn test suite. See http://einaros.github.com/ws for the full reports.\n\nComes with a command line utility, `wscat`, which can either act as a server (--listen), or client (--connect); Use it to debug simple websocket services.\n\n## Protocol support ##\n\n* **Hixie draft 76** (Old and deprecated, but still in use by Safari and Opera. Added to ws version 0.4.2, but server only. Can be disabled by setting the `disableHixie` option to true.)\n* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`, or argument `-p 8` for wscat)\n* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`, or argument `-p 13` for wscat)\n\n_See the echo.websocket.org example below for how to use the `protocolVersion` option._\n\n## Usage ##\n\n### Installing ###\n\n`npm install ws`\n\n### Sending and receiving text data ###\n\n```js\nvar WebSocket = require('ws');\nvar ws = new WebSocket('ws://www.host.com/path');\nws.on('open', function() {\n ws.send('something');\n});\nws.on('message', function(data, flags) {\n // flags.binary will be set if a binary data is received\n // flags.masked will be set if the data was masked\n});\n```\n\n### Sending binary data ###\n\n```js\nvar WebSocket = require('ws');\nvar ws = new WebSocket('ws://www.host.com/path');\nws.on('open', function() {\n var array = new Float32Array(5);\n for (var i = 0; i < array.length; ++i) array[i] = i / 2;\n ws.send(array, {binary: true, mask: true});\n});\n```\n\nSetting `mask`, as done for the send options above, will cause the data to be masked according to the websocket protocol. The same option applies for text data.\n\n### Server example ###\n\n```js\nvar WebSocketServer = require('ws').Server\n , wss = new WebSocketServer({port: 8080});\nwss.on('connection', function(ws) {\n ws.on('message', function(message) {\n console.log('received: %s', message);\n });\n ws.send('something');\n});\n```\n\n### Error handling best practices ###\n\n```js\n// If the WebSocket is closed before the following send is attempted\nws.send('something');\n\n// Errors (both immediate and async write errors) can be detected in an optional callback.\n// The callback is also the only way of being notified that data has actually been sent.\nws.send('something', function(error) {\n // if error is null, the send has been completed,\n // otherwise the error object will indicate what failed.\n});\n\n// Immediate errors can also be handled with try/catch-blocks, but **note**\n// that since sends are inherently asynchronous, socket write failures will *not*\n// be captured when this technique is used.\ntry {\n ws.send('something');\n}\ncatch (e) {\n // handle error\n}\n```\n\n### echo.websocket.org demo ###\n\n```js\nvar WebSocket = require('ws');\nvar ws = new WebSocket('ws://echo.websocket.org/', {protocolVersion: 8, origin: 'http://websocket.org'});\nws.on('open', function() {\n console.log('connected');\n ws.send(Date.now().toString(), {mask: true});\n});\nws.on('close', function() {\n console.log('disconnected');\n});\nws.on('message', function(data, flags) {\n console.log('Roundtrip time: ' + (Date.now() - parseInt(data)) + 'ms', flags);\n setTimeout(function() {\n ws.send(Date.now().toString(), {mask: true});\n }, 500);\n});\n```\n\n### wscat against echo.websocket.org ###\n\n $ npm install -g ws\n $ wscat -c ws://echo.websocket.org -p 8\n connected (press CTRL+C to quit)\n > hi there\n < hi there\n > are you a happy parrot?\n < are you a happy parrot?\n\n### Other examples ###\n\nFor a full example with a browser client communicating with a ws server, see the examples folder.\n\nNote that the usage together with Express 3.0 is quite different from Express 2.x. The difference is expressed in the two different serverstats-examples.\n\nOtherwise, see the test cases.\n\n### Running the tests ###\n\n`make test`\n\n## API Docs ##\n\nSee the doc/ directory for Node.js-like docs for the ws classes.\n\n## License ##\n\n(The MIT License)\n\nCopyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", 40 | "readmeFilename": "README.md", 41 | "bugs": { 42 | "url": "https://github.com/einaros/ws/issues" 43 | }, 44 | "_id": "ws@0.4.25", 45 | "dist": { 46 | "shasum": "775cd59e7ec763e27581cd44bd7fe5c8ceb7d5d5" 47 | }, 48 | "_from": "ws@", 49 | "_resolved": "https://registry.npmjs.org/ws/-/ws-0.4.25.tgz" 50 | } 51 | -------------------------------------------------------------------------------- /server/node_modules/ws/src/bufferutil.cc: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace v8; 17 | using namespace node; 18 | 19 | class BufferUtil : public ObjectWrap 20 | { 21 | public: 22 | 23 | static void Initialize(v8::Handle target) 24 | { 25 | HandleScope scope; 26 | Local t = FunctionTemplate::New(New); 27 | t->InstanceTemplate()->SetInternalFieldCount(1); 28 | NODE_SET_METHOD(t->GetFunction(), "unmask", BufferUtil::Unmask); 29 | NODE_SET_METHOD(t->GetFunction(), "mask", BufferUtil::Mask); 30 | NODE_SET_METHOD(t->GetFunction(), "merge", BufferUtil::Merge); 31 | target->Set(String::NewSymbol("BufferUtil"), t->GetFunction()); 32 | } 33 | 34 | protected: 35 | 36 | static Handle New(const Arguments& args) 37 | { 38 | HandleScope scope; 39 | BufferUtil* bufferUtil = new BufferUtil(); 40 | bufferUtil->Wrap(args.This()); 41 | return args.This(); 42 | } 43 | 44 | static Handle Merge(const Arguments& args) 45 | { 46 | HandleScope scope; 47 | Local bufferObj = args[0]->ToObject(); 48 | char* buffer = Buffer::Data(bufferObj); 49 | Local array = Local::Cast(args[1]); 50 | unsigned int arrayLength = array->Length(); 51 | unsigned int offset = 0; 52 | unsigned int i; 53 | for (i = 0; i < arrayLength; ++i) { 54 | Local src = array->Get(i)->ToObject(); 55 | unsigned int length = Buffer::Length(src); 56 | memcpy(buffer + offset, Buffer::Data(src), length); 57 | offset += length; 58 | } 59 | return scope.Close(True()); 60 | } 61 | 62 | static Handle Unmask(const Arguments& args) 63 | { 64 | HandleScope scope; 65 | Local buffer_obj = args[0]->ToObject(); 66 | unsigned int length = Buffer::Length(buffer_obj); 67 | Local mask_obj = args[1]->ToObject(); 68 | unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj); 69 | unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj); 70 | unsigned int len32 = length / 4; 71 | unsigned int i; 72 | for (i = 0; i < len32; ++i) *(from + i) ^= *mask; 73 | from += i; 74 | switch (length % 4) { 75 | case 3: *((unsigned char*)from+2) = *((unsigned char*)from+2) ^ ((unsigned char*)mask)[2]; 76 | case 2: *((unsigned char*)from+1) = *((unsigned char*)from+1) ^ ((unsigned char*)mask)[1]; 77 | case 1: *((unsigned char*)from ) = *((unsigned char*)from ) ^ ((unsigned char*)mask)[0]; 78 | case 0:; 79 | } 80 | return True(); 81 | } 82 | 83 | static Handle Mask(const Arguments& args) 84 | { 85 | HandleScope scope; 86 | Local buffer_obj = args[0]->ToObject(); 87 | Local mask_obj = args[1]->ToObject(); 88 | unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj); 89 | Local output_obj = args[2]->ToObject(); 90 | unsigned int dataOffset = args[3]->Int32Value(); 91 | unsigned int length = args[4]->Int32Value(); 92 | unsigned int* to = (unsigned int*)(Buffer::Data(output_obj) + dataOffset); 93 | unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj); 94 | unsigned int len32 = length / 4; 95 | unsigned int i; 96 | for (i = 0; i < len32; ++i) *(to + i) = *(from + i) ^ *mask; 97 | to += i; 98 | from += i; 99 | switch (length % 4) { 100 | case 3: *((unsigned char*)to+2) = *((unsigned char*)from+2) ^ *((unsigned char*)mask+2); 101 | case 2: *((unsigned char*)to+1) = *((unsigned char*)from+1) ^ *((unsigned char*)mask+1); 102 | case 1: *((unsigned char*)to ) = *((unsigned char*)from ) ^ *((unsigned char*)mask); 103 | case 0:; 104 | } 105 | return True(); 106 | } 107 | }; 108 | 109 | extern "C" void init (Handle target) 110 | { 111 | HandleScope scope; 112 | BufferUtil::Initialize(target); 113 | } 114 | 115 | NODE_MODULE(bufferutil, init) 116 | -------------------------------------------------------------------------------- /server/node_modules/ws/src/validation.cc: -------------------------------------------------------------------------------- 1 | /*! 2 | * ws: a node.js websocket client 3 | * Copyright(c) 2011 Einar Otto Stangvik 4 | * MIT Licensed 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace v8; 16 | using namespace node; 17 | 18 | #define UNI_SUR_HIGH_START (uint32_t) 0xD800 19 | #define UNI_SUR_LOW_END (uint32_t) 0xDFFF 20 | #define UNI_REPLACEMENT_CHAR (uint32_t) 0x0000FFFD 21 | #define UNI_MAX_LEGAL_UTF32 (uint32_t) 0x0010FFFF 22 | 23 | static const uint8_t trailingBytesForUTF8[256] = { 24 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 25 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 26 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 27 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 28 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 29 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 30 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 31 | 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 32 | }; 33 | 34 | static const uint32_t offsetsFromUTF8[6] = { 35 | 0x00000000, 0x00003080, 0x000E2080, 36 | 0x03C82080, 0xFA082080, 0x82082080 37 | }; 38 | 39 | static int isLegalUTF8(const uint8_t *source, const int length) 40 | { 41 | uint8_t a; 42 | const uint8_t *srcptr = source+length; 43 | switch (length) { 44 | default: return 0; 45 | /* Everything else falls through when "true"... */ 46 | /* RFC3629 makes 5 & 6 bytes UTF-8 illegal 47 | case 6: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; 48 | case 5: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; */ 49 | case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; 50 | case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; 51 | case 2: if ((a = (*--srcptr)) > 0xBF) return 0; 52 | switch (*source) { 53 | /* no fall-through in this inner switch */ 54 | case 0xE0: if (a < 0xA0) return 0; break; 55 | case 0xED: if (a > 0x9F) return 0; break; 56 | case 0xF0: if (a < 0x90) return 0; break; 57 | case 0xF4: if (a > 0x8F) return 0; break; 58 | default: if (a < 0x80) return 0; 59 | } 60 | 61 | case 1: if (*source >= 0x80 && *source < 0xC2) return 0; 62 | } 63 | if (*source > 0xF4) return 0; 64 | return 1; 65 | } 66 | 67 | int is_valid_utf8 (size_t len, char *value) 68 | { 69 | /* is the string valid UTF-8? */ 70 | for (unsigned int i = 0; i < len; i++) { 71 | uint32_t ch = 0; 72 | uint8_t extrabytes = trailingBytesForUTF8[(uint8_t) value[i]]; 73 | 74 | if (extrabytes + i >= len) 75 | return 0; 76 | 77 | if (isLegalUTF8 ((uint8_t *) (value + i), extrabytes + 1) == 0) return 0; 78 | 79 | switch (extrabytes) { 80 | case 5 : ch += (uint8_t) value[i++]; ch <<= 6; 81 | case 4 : ch += (uint8_t) value[i++]; ch <<= 6; 82 | case 3 : ch += (uint8_t) value[i++]; ch <<= 6; 83 | case 2 : ch += (uint8_t) value[i++]; ch <<= 6; 84 | case 1 : ch += (uint8_t) value[i++]; ch <<= 6; 85 | case 0 : ch += (uint8_t) value[i]; 86 | } 87 | 88 | ch -= offsetsFromUTF8[extrabytes]; 89 | 90 | if (ch <= UNI_MAX_LEGAL_UTF32) { 91 | if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) 92 | return 0; 93 | } else { 94 | return 0; 95 | } 96 | } 97 | 98 | return 1; 99 | } 100 | 101 | class Validation : public ObjectWrap 102 | { 103 | public: 104 | 105 | static void Initialize(v8::Handle target) 106 | { 107 | HandleScope scope; 108 | Local t = FunctionTemplate::New(New); 109 | t->InstanceTemplate()->SetInternalFieldCount(1); 110 | NODE_SET_METHOD(t->GetFunction(), "isValidUTF8", Validation::IsValidUTF8); 111 | target->Set(String::NewSymbol("Validation"), t->GetFunction()); 112 | } 113 | 114 | protected: 115 | 116 | static Handle New(const Arguments& args) 117 | { 118 | HandleScope scope; 119 | Validation* validation = new Validation(); 120 | validation->Wrap(args.This()); 121 | return args.This(); 122 | } 123 | 124 | static Handle IsValidUTF8(const Arguments& args) 125 | { 126 | HandleScope scope; 127 | if (!Buffer::HasInstance(args[0])) { 128 | return ThrowException(Exception::Error(String::New("First argument needs to be a buffer"))); 129 | } 130 | Local buffer_obj = args[0]->ToObject(); 131 | char *buffer_data = Buffer::Data(buffer_obj); 132 | size_t buffer_length = Buffer::Length(buffer_obj); 133 | return is_valid_utf8(buffer_length, buffer_data) == 1 ? scope.Close(True()) : scope.Close(False()); 134 | } 135 | }; 136 | 137 | extern "C" void init (Handle target) 138 | { 139 | HandleScope scope; 140 | Validation::Initialize(target); 141 | } 142 | 143 | NODE_MODULE(validation, init) 144 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | //Websocket Server <<<<<<<<<<<<<< 2 | var wsPort = 8081; 3 | var webPort = 8080; 4 | var subscribers = []; 5 | var WebSocketServer = require('ws').Server; 6 | var wss = new WebSocketServer({port: wsPort}); 7 | var http = require('http'); 8 | var url = require('url'); 9 | var path = require('path'); 10 | var fs = require('fs'); 11 | var baseDirectory = '../web/' 12 | 13 | http.createServer(function (request, response) { 14 | try { 15 | var rurl = request.url; 16 | if(rurl=="/") { 17 | rurl = "/index.html"; 18 | } 19 | var requestUrl = url.parse(rurl) 20 | 21 | // need to use path.normalize so people can't access directories underneath baseDirectory 22 | var fsPath = baseDirectory+path.normalize(requestUrl.pathname); 23 | 24 | var fileStream = fs.createReadStream(fsPath) 25 | fileStream.pipe(response) 26 | fileStream.on('open', function() { 27 | response.writeHead(200) 28 | }) 29 | fileStream.on('error',function(e) { 30 | response.writeHead(404) // assume the file doesn't exist 31 | response.end() 32 | }) 33 | } catch(e) { 34 | response.writeHead(500) 35 | response.end() // end the response so browsers don't hang 36 | console.log(e.stack) 37 | } 38 | }).listen(webPort) 39 | 40 | wss.on('connection', function(ws) { 41 | subscribers.push(ws); 42 | ws.send(subscribers.length-1 + '###thatsYou'); 43 | 44 | for(var i=0;i= 1) { 152 | // this single interface has multiple ipv4 addresses 153 | console.log(" http://"+iface.address+":"+webPort); 154 | } else { 155 | // this interface has only one ipv4 adress 156 | console.log(" "+ifname+": ", "http://"+iface.address+":"+webPort); 157 | } 158 | ++alias; 159 | }); 160 | }); 161 | } 162 | -------------------------------------------------------------------------------- /server/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #Benötigte Module: asyncio websockets 3 | 4 | import asyncio 5 | import datetime 6 | import websockets 7 | import pprint 8 | 9 | #server config 10 | ip = "0.0.0.0" 11 | port = 8080 12 | 13 | #global vars 14 | clients = set() 15 | 16 | @asyncio.coroutine 17 | def sendMsg(socket, msg): 18 | print ("info>send>begin:\n" + msg + "\ninfo>send>end") 19 | yield from socket.send(msg) 20 | 21 | @asyncio.coroutine 22 | def broadcast(msg): 23 | 24 | command = msg.split("###"); 25 | print("info>broadcasting msg(" + str(len(msg)) + ") command=" + command[0]) 26 | 27 | for client in clients: 28 | 29 | print("info>broadcast>send to" + str(client.remote_address)) 30 | yield from client.send(msg) 31 | 32 | @asyncio.coroutine 33 | def client_connect(websocket, path): 34 | print("info>Client connected:" + str(websocket.remote_address)); 35 | clients.add(websocket) 36 | 37 | try: 38 | while True: 39 | msg = yield from websocket.recv() 40 | 41 | command = msg.split("###"); 42 | 43 | pprint.pprint(command) 44 | 45 | if command[0] == "fileOp": 46 | print("info>got filop"); 47 | 48 | if command[1] == "read": 49 | print("info>fileop> got read") 50 | print("info>fileop>read:" + command[2]) 51 | 52 | try: 53 | f = open(command[2], "r", encoding='utf8') 54 | content = f.read() 55 | f.close() 56 | 57 | print("reading done") 58 | except: 59 | print("Error reading file:"+ command[2]) 60 | 61 | #send content 62 | #yield from sendMsg(websocket, "file###" + command[2] + "###" + content) 63 | yield from broadcast("file###" + command[2] + "###" + content); 64 | 65 | elif command[1] == "write": 66 | f = open(command[2], "w", encoding='utf8') 67 | f.write(command[3]) 68 | f.close() 69 | 70 | yield from broadcast("file###" + command[2] + "###" + command[3]) 71 | 72 | else: 73 | yield from broadcast(msg) 74 | 75 | except: 76 | print("info>client disconnected:" + path); 77 | clients.remove(websocket) 78 | #raise 79 | 80 | print("info>starting server " + ip + ":" + str(port)) 81 | server = websockets.serve(client_connect, ip, port) 82 | 83 | print ("info>go into loop") 84 | asyncio.get_event_loop().run_until_complete(server) 85 | asyncio.get_event_loop().run_forever() 86 | -------------------------------------------------------------------------------- /web/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.0.3');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857142858em;text-align:center}.fa-ul{padding-left:0;margin-left:2.142857142857143em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;top:.14285714285714285em;text-align:center}.fa-li.fa-lg{left:-1.8571428571428572em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0,mirror=1);-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);-ms-transform:scale(-1,1);-o-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2,mirror=1);-webkit-transform:scale(1,-1);-moz-transform:scale(1,-1);-ms-transform:scale(1,-1);-o-transform:scale(1,-1);transform:scale(1,-1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-asc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-desc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-reply-all:before{content:"\f122"}.fa-mail-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"} -------------------------------------------------------------------------------- /web/css/jquery.dataTables.css: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Table 4 | */ 5 | table.dataTable { 6 | margin: 0 auto; 7 | clear: both; 8 | width: 100%; 9 | } 10 | 11 | table.dataTable thead th { 12 | padding: 3px 18px 3px 10px; 13 | border-bottom: 1px solid black; 14 | font-weight: bold; 15 | cursor: pointer; 16 | *cursor: hand; 17 | } 18 | 19 | table.dataTable tfoot th { 20 | padding: 3px 18px 3px 10px; 21 | border-top: 1px solid black; 22 | font-weight: bold; 23 | } 24 | 25 | table.dataTable td { 26 | padding: 3px 10px; 27 | } 28 | 29 | table.dataTable td.center, 30 | table.dataTable td.dataTables_empty { 31 | text-align: center; 32 | } 33 | 34 | table.dataTable tr.odd { background-color: #E2E4FF; } 35 | table.dataTable tr.even { background-color: white; } 36 | 37 | table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; } 38 | table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; } 39 | table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; } 40 | table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; } 41 | table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; } 42 | table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } 43 | 44 | 45 | /* 46 | * Table wrapper 47 | */ 48 | .dataTables_wrapper { 49 | position: relative; 50 | clear: both; 51 | *zoom: 1; 52 | } 53 | 54 | 55 | /* 56 | * Page length menu 57 | */ 58 | .dataTables_length { 59 | float: left; 60 | } 61 | 62 | 63 | /* 64 | * Filter 65 | */ 66 | .dataTables_filter { 67 | float: right; 68 | text-align: right; 69 | } 70 | 71 | 72 | /* 73 | * Table information 74 | */ 75 | .dataTables_info { 76 | clear: both; 77 | float: left; 78 | } 79 | 80 | 81 | /* 82 | * Pagination 83 | */ 84 | .dataTables_paginate { 85 | float: right; 86 | text-align: right; 87 | } 88 | 89 | /* Two button pagination - previous / next */ 90 | .paginate_disabled_previous, 91 | .paginate_enabled_previous, 92 | .paginate_disabled_next, 93 | .paginate_enabled_next { 94 | height: 19px; 95 | float: left; 96 | cursor: pointer; 97 | *cursor: hand; 98 | color: #111 !important; 99 | } 100 | .paginate_disabled_previous:hover, 101 | .paginate_enabled_previous:hover, 102 | .paginate_disabled_next:hover, 103 | .paginate_enabled_next:hover { 104 | text-decoration: none !important; 105 | } 106 | .paginate_disabled_previous:active, 107 | .paginate_enabled_previous:active, 108 | .paginate_disabled_next:active, 109 | .paginate_enabled_next:active { 110 | outline: none; 111 | } 112 | 113 | .paginate_disabled_previous, 114 | .paginate_disabled_next { 115 | color: #666 !important; 116 | } 117 | .paginate_disabled_previous, 118 | .paginate_enabled_previous { 119 | padding-left: 23px; 120 | } 121 | .paginate_disabled_next, 122 | .paginate_enabled_next { 123 | padding-right: 23px; 124 | margin-left: 10px; 125 | } 126 | 127 | .paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; } 128 | .paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; } 129 | .paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; } 130 | 131 | .paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; } 132 | .paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; } 133 | .paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; } 134 | 135 | /* Full number pagination */ 136 | .paging_full_numbers { 137 | height: 22px; 138 | line-height: 22px; 139 | } 140 | .paging_full_numbers a:active { 141 | outline: none 142 | } 143 | .paging_full_numbers a:hover { 144 | text-decoration: none; 145 | } 146 | 147 | .paging_full_numbers a.paginate_button, 148 | .paging_full_numbers a.paginate_active { 149 | border: 1px solid #aaa; 150 | -webkit-border-radius: 5px; 151 | -moz-border-radius: 5px; 152 | border-radius: 5px; 153 | padding: 2px 5px; 154 | margin: 0 3px; 155 | cursor: pointer; 156 | *cursor: hand; 157 | color: #333 !important; 158 | } 159 | 160 | .paging_full_numbers a.paginate_button { 161 | background-color: #ddd; 162 | } 163 | 164 | .paging_full_numbers a.paginate_button:hover { 165 | background-color: #ccc; 166 | text-decoration: none !important; 167 | } 168 | 169 | .paging_full_numbers a.paginate_active { 170 | background-color: #99B3FF; 171 | } 172 | 173 | 174 | /* 175 | * Processing indicator 176 | */ 177 | .dataTables_processing { 178 | position: absolute; 179 | top: 50%; 180 | left: 50%; 181 | width: 250px; 182 | height: 30px; 183 | margin-left: -125px; 184 | margin-top: -15px; 185 | padding: 14px 0 2px 0; 186 | border: 1px solid #ddd; 187 | text-align: center; 188 | color: #999; 189 | font-size: 14px; 190 | background-color: white; 191 | } 192 | 193 | 194 | /* 195 | * Sorting 196 | */ 197 | .sorting { background: url('../images/sort_both.png') no-repeat center right; } 198 | .sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; } 199 | .sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; } 200 | 201 | .sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; } 202 | .sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; } 203 | 204 | table.dataTable thead th:active, 205 | table.dataTable thead td:active { 206 | outline: none; 207 | } 208 | 209 | 210 | /* 211 | * Scrolling 212 | */ 213 | .dataTables_scroll { 214 | clear: both; 215 | } 216 | 217 | .dataTables_scrollBody { 218 | *margin-top: -1px; 219 | -webkit-overflow-scrolling: touch; 220 | } 221 | 222 | -------------------------------------------------------------------------------- /web/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: monospace; 3 | background: url(../img/background.jpg) no-repeat; 4 | background-position: center center; 5 | background-attachment: fixed; 6 | background-size: cover; 7 | display: flex; 8 | align-items: center; /* Vertikale Zentrierung */ 9 | justify-content: center; /* Horizontale Zentrierung */ 10 | } 11 | 12 | #allContent { 13 | position: relative; 14 | 15 | } 16 | 17 | .textColor { 18 | color:#ddff06; 19 | font-weight:bold; 20 | font-size: 1.5em; 21 | } 22 | 23 | .bgColor{ 24 | background:#000000; 25 | } 26 | 27 | .antwortInp, .questionIn, .questionKIn { 28 | width:400px; 29 | } 30 | 31 | .upDownArrow:hover { 32 | color:blue; 33 | cursor:pointer; 34 | } 35 | 36 | .markOnHover:hover{ 37 | color:blue; 38 | cursor:pointer; 39 | } 40 | 41 | .markOnHover{ 42 | color:gray; 43 | } 44 | 45 | .xmarker { 46 | font-family: Verdana, Helvetica, sans-serif; 47 | font-weight: bold; 48 | z-index: 3; 49 | box-shadow: 3px 5px 35px rgba(0, 0, 0, 0.65); 50 | border: 2px #595959 solid; 51 | border-radius: 2px; 52 | text-shadow: -1px -1px 1px rgba(0, 0, 0, 0.15), 1px 1px 1px rgba(255, 255, 255, 0.20); 53 | font-size: 2em; 54 | background: #595959; 55 | height: 56px; 56 | padding-left: 12px; 57 | padding-right: 12px; 58 | color: rgb(66, 66, 66); 59 | /* box-shadow: 5px 5px 5px -1px rgba(0, 0, 0, 0.65), 0 5px 5px -5px rgba(0, 0, 0, 0.65); */ 60 | } 61 | 62 | .noIntro { 63 | display:none; 64 | } 65 | 66 | .footer { 67 | background:#ddff06; 68 | color: #000000; 69 | } 70 | 71 | #buttonsDownUnder { 72 | background: #ffffff; 73 | padding: 20px; 74 | margin-top: 70px; 75 | box-shadow: 3px 5px 35px rgba(0, 0, 0, 0.65); 76 | } 77 | 78 | #buttonsDownUnder td{ 79 | padding: 5px; 80 | } 81 | 82 | .mainHeight { 83 | position: relative; 84 | width: 80vw; 85 | height: 40vw; 86 | min-height: 520px; 87 | min-width: 1020px; 88 | margin: auto; 89 | margin-bottom: 50px; 90 | z-index: 5; 91 | border: 10px #c0c0c0 ridge; 92 | border-radius: 2px; 93 | box-shadow: 3px 5px 35px rgba(0, 0, 0, 0.65); 94 | } 95 | 96 | #timer { 97 | background: #000000; 98 | z-index: 5; 99 | border: 10px #c0c0c0 ridge; 100 | border-radius: 2px; 101 | box-shadow: 3px 5px 35px rgba(0, 0, 0, 0.65); 102 | } 103 | 104 | #blackScreen { 105 | z-index: 6; 106 | } 107 | 108 | #editQuestionsDiv { 109 | border-radius: 2px; 110 | z-index: 7; 111 | } 112 | 113 | #answers { 114 | overflow: hidden; 115 | font-family: monospace; 116 | font-size: 2.5vw; 117 | white-space: nowrap; 118 | } 119 | 120 | .answer { 121 | overflow: hidden; 122 | white-space: nowrap; 123 | } 124 | 125 | #displayQuestions { 126 | overflow: hidden; 127 | font-size: 2.5vw; 128 | white-space: unset; 129 | text-overflow: unset; 130 | } 131 | 132 | #resultFinal { 133 | font-size: 2.5vw; 134 | } 135 | 136 | .questionAnswerContainer { 137 | padding-top: 20px; 138 | padding-left: 20px; 139 | width: calc(100% - 20px); 140 | } 141 | 142 | @media (max-width: 1275px) { 143 | #answers { 144 | font-size: 1.5em; 145 | } 146 | 147 | #resultFinal { 148 | font-size: 1.5em; 149 | } 150 | 151 | #displayQuestions { 152 | white-space: nowrap; 153 | text-overflow: ellipsis; 154 | font-size: 1.5em; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /web/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /web/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /web/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /web/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /web/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /web/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /web/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /web/img/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/img/background.jpg -------------------------------------------------------------------------------- /web/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/img/logo.png -------------------------------------------------------------------------------- /web/img/noSound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/img/noSound.png -------------------------------------------------------------------------------- /web/img/notConnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/img/notConnected.png -------------------------------------------------------------------------------- /web/img/schweinchen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/img/schweinchen1.png -------------------------------------------------------------------------------- /web/img/schweinchen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/img/schweinchen2.png -------------------------------------------------------------------------------- /web/img/schweinchen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/img/schweinchen3.png -------------------------------------------------------------------------------- /web/img/soundOn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/img/soundOn.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Familien Duell 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 |

Familienduell

21 |
22 | 23 |
24 | 25 | 60 | 61 | 143 | 157 | 158 |
159 | 162 | 163 |
164 | 165 | -------------------------------------------------------------------------------- /web/js/components.js: -------------------------------------------------------------------------------- 1 | function init_xmarker() { 2 | var c =0; 3 | $.each($(".xmarker"), function() { 4 | for(var i=0; i<3;i++) { 5 | var span = $('X'); 6 | var span = $('X'); 7 | 8 | console.log("sow"+i); 9 | (function() { 10 | var cc = c; 11 | span.click(function() { 12 | if(!display) { 13 | console.log("click"+cc); 14 | wsSend("setFail",cc); 15 | } 16 | }); 17 | })(); 18 | $(this).append(span); 19 | c++; 20 | } 21 | }); 22 | } -------------------------------------------------------------------------------- /web/js/websocket.js: -------------------------------------------------------------------------------- 1 | var retrys = 0; 2 | 3 | var WSPort = 8081; 4 | var IP = (location.host +"").split(":")[0]; 5 | var isWebsocketConnected = false; 6 | var connTimer = null; 7 | var sounds = true; 8 | var ws; 9 | var display = true; 10 | var audio = null; 11 | var serverSound = true; 12 | var isFinalMode = false; 13 | var player2 = false; 14 | var runde = 1; 15 | 16 | var viewOnly = false; 17 | if(window.location.href.indexOf("viewonly")!==-1) { 18 | ip = window.location.href.split("ip=")[1]; 19 | viewOnly = true; 20 | } 21 | 22 | $(document).ready(function() { 23 | $("#displayBtn").click(function() { 24 | if (this.requestFullScreen) { 25 | this.requestFullScreen(); 26 | } else if (this.mozRequestFullScreen) { 27 | this.mozRequestFullScreen(); 28 | } else if (this.webkitRequestFullScreen) { 29 | this.webkitRequestFullScreen(); 30 | } 31 | $("#startDiv").hide(); 32 | $("#display").show(); 33 | $(".controller").hide(); 34 | $("#blackScreen").show(); 35 | $("#connected").hide(); 36 | }); 37 | 38 | $("#controllerBtn").click(function() { 39 | $("#startDiv").hide(); 40 | $("#display").show(); 41 | $(".controller").show(); 42 | display = false; 43 | 44 | // nice css manipulation 🤢#hack 45 | $(".mainHeight").css("width", 1020); 46 | $(".mainHeight").css("height", 520); 47 | $(".mainHeight").css("padding-top", ""); 48 | $("#answers").css("font-size", "1.5em"); 49 | $("#displayQuestions").css("font-size", "1.5em"); 50 | }); 51 | 52 | $("#clearAllFailsBtn").click(function() { 53 | wsSend("clearAllFailsBtn", ""); 54 | }); 55 | 56 | $("#showFinalScores").click(function() { 57 | wsSend("showFinalScores", ""); 58 | }); 59 | 60 | $("#toggleSoundImg").click(function() { 61 | wsSend("toggleSound", ""); 62 | }); 63 | 64 | $("#serverSoundImg").click(function() { 65 | if(serverSound) { 66 | serverSound = false; 67 | $("#serverSoundImg").attr("src", "./img/noSound.png"); 68 | if(audio != null) 69 | audio.pause(); 70 | if(intro != null) 71 | intro.pause(); 72 | } else { 73 | serverSound = true; 74 | $("#serverSoundImg").attr("src", "./img/SoundOn.png"); 75 | } 76 | }); 77 | init_xmarker(); 78 | connectWs(); 79 | 80 | if(viewOnly) { 81 | $("#displayBtn").click(); 82 | } 83 | }); 84 | 85 | 86 | var connectWs = function() { 87 | ws = new WebSocket('ws://'+IP+':'+WSPort); 88 | 89 | ws.onopen = function() 90 | { 91 | $("#notConnected").hide(); 92 | $("#connected").text("Verbunden mit: "+'ws://'+IP+':'+WSPort); 93 | $("#connected").show(); 94 | isWebsocketConnected = true; 95 | loadQuestions(); 96 | //console.log("connected to Websocket Server!!!"); 97 | } 98 | 99 | ws.onclose = function() 100 | { 101 | $("#notConnected").show(); 102 | isWebsocketConnected = false; 103 | //console.log("disconnected from Websocket Server!!!"); 104 | return null; 105 | } 106 | 107 | ws.onmessage = async function (event) { 108 | let tempSt = event.data.toString(); 109 | if(typeof(event.data) != "string") { 110 | tempSt = await new Response(event.data).text() 111 | } 112 | console.log("msg: "+tempSt) 113 | messageParts_a = tempSt.split("###"); 114 | var key = messageParts_a[0]; 115 | var value = messageParts_a[1]; 116 | if(key =="setFail") { 117 | if($(".marker"+value).css("color") == "rgb(66, 66, 66)") { 118 | $(".marker"+value).css("color","rgb(211, 16, 16)"); 119 | if(sounds && (display || serverSound)) { 120 | audio = new Audio('./sounds/fail.ogg'); 121 | audio.play(); 122 | } 123 | } else { 124 | $(".marker"+value).css("color","rgb(66, 66, 66)"); 125 | } 126 | } else if(key == "clearAllFailsBtn") { 127 | $.each($(".xmarker").find("span"), function() { 128 | $(this).css("color","rgb(66, 66, 66)"); 129 | }); 130 | } else if(key == "toggleSound") { 131 | if(sounds) { 132 | $("#toggleSoundImg").attr("src", "./img/noSound.png"); 133 | if(audio != null) 134 | audio.pause(); 135 | sounds = false; 136 | } else { 137 | $("#toggleSoundImg").attr("src", "./img/soundOn.png"); 138 | sounds = true; 139 | } 140 | } else if(key == "showFinalScores") { 141 | showFinalScores() 142 | } else if(key == "file") { 143 | if(value == "fragen.txt") { 144 | try { 145 | var base64 = decodeURIComponent(atob(messageParts_a[2])); 146 | fragen = JSON.parse(base64); 147 | fillFragenEditor(); 148 | fillFragenSelect(); 149 | } catch(e) { 150 | console.log("Datei "+value+" konnte nicht geparsed werden!"); 151 | } 152 | } 153 | } else if(key == "loadQuestion") { 154 | if(!(display && isFinalMode)) 155 | loadQuestionToGui(value); 156 | } else if(key == "setAnswer") { 157 | setAnswer(value, messageParts_a[2]); 158 | } else if(key == "setAnz") { 159 | setAnz(value, messageParts_a[2]); 160 | } else if(key == "showIntro") { 161 | showIntro(); 162 | } else if(key == "hideIntro") { 163 | hideIntro(); 164 | } else if(key == "setIntroVolume") { 165 | introVolume = value; 166 | if(intro != null) 167 | intro.volume = introVolume; 168 | } else if(key == "setLeftPoints") { 169 | setLeftPoints(value); 170 | } else if(key == "setRightPoints") { 171 | setRightPoints(value); 172 | } else if(key == "setSumRes") { 173 | setSumRes(value); 174 | } else if(key == "startAnswerFail") { 175 | startAnswerFail(); 176 | } else if(key == "startAnswerDuplicate") { 177 | startAnswerDuplicate(); 178 | } else if(key == "showTimer") { 179 | showTimer(); 180 | } else if(key == "startTimer") { 181 | startTimer(); 182 | } else if(key == "stopTimer") { 183 | stopTimer(); 184 | } else if(key == "setAnswerFailVolume") { 185 | answerFailVolume = value; 186 | if(answerFail != null) 187 | answerFail.volume = answerFailVolume; 188 | } else if(key == "startSchweinchen") { 189 | startSchweinchen(); 190 | } else if(key == "stopSchweinchen") { 191 | stopSchweinchen(); 192 | } else if(key == "setSchweinchenVolume") { 193 | schweinchenVolume = value; 194 | if(schweinchen != null) 195 | schweinchen.volume = schweinchenVolume; 196 | } else if(key == "toggleBlackScreen") { 197 | if (display) { 198 | if ($("#blackScreen").css("display") === "none") { 199 | $("#blackScreen").fadeIn(500); 200 | } else { 201 | $("#blackScreen").fadeOut(6000); 202 | } 203 | // $("#blackScreen").toggle(); 204 | } 205 | } else if (key == "toggleFinalMode"){ 206 | setFinalMode(value); 207 | } 208 | else if (key == "setPlayer2ForFinalMode"){ 209 | setPlayer2(value); 210 | } 211 | else if (key == "setRunde"){ 212 | console.log('Set Runde to ' + value); 213 | setRunde(value); 214 | } 215 | } 216 | } 217 | 218 | function wsSend(key, msg) 219 | { 220 | console.log("send", key, msg); 221 | if(isWebsocketConnected) 222 | ws.send(key+"###"+msg); 223 | } 224 | 225 | -------------------------------------------------------------------------------- /web/sounds/fail.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/sounds/fail.ogg -------------------------------------------------------------------------------- /web/sounds/failOrginal.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/sounds/failOrginal.ogg -------------------------------------------------------------------------------- /web/sounds/failOriginal.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/sounds/failOriginal.ogg -------------------------------------------------------------------------------- /web/sounds/failfinal.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/sounds/failfinal.ogg -------------------------------------------------------------------------------- /web/sounds/intro.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/sounds/intro.ogg -------------------------------------------------------------------------------- /web/sounds/schweinchen.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/sounds/schweinchen.ogg -------------------------------------------------------------------------------- /web/sounds/textRichtig.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/sounds/textRichtig.ogg -------------------------------------------------------------------------------- /web/sounds/zahlRichtig.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cracker0dks/Familienduell/2e9a01ac3c4a0857dc41eb10e3ebb96f291b29a6/web/sounds/zahlRichtig.ogg --------------------------------------------------------------------------------