├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── client ├── .babelrc ├── android │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets │ │ │ └── fonts │ │ │ │ ├── Entypo.ttf │ │ │ │ ├── EvilIcons.ttf │ │ │ │ ├── FontAwesome.ttf │ │ │ │ ├── Foundation.ttf │ │ │ │ ├── Ionicons.ttf │ │ │ │ ├── MaterialCommunityIcons.ttf │ │ │ │ ├── MaterialIcons.ttf │ │ │ │ ├── Octicons.ttf │ │ │ │ ├── SimpleLineIcons.ttf │ │ │ │ └── Zocial.ttf │ │ │ ├── java │ │ │ └── com │ │ │ │ └── hackpi │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── keystores │ │ ├── BUCK │ │ └── debug.keystore.properties │ └── settings.gradle ├── app.json ├── components │ ├── settingsCard │ │ └── index.js │ └── statusCard │ │ └── index.js ├── index.android.js ├── index.ios.js ├── ios │ ├── HackPi-tvOS │ │ └── Info.plist │ ├── HackPi-tvOSTests │ │ └── Info.plist │ ├── HackPi.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── HackPi-tvOS.xcscheme │ │ │ └── HackPi.xcscheme │ ├── HackPi │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ └── HackPiTests │ │ ├── HackPiTests.m │ │ └── Info.plist ├── package.json ├── screens │ ├── app │ │ └── index.js │ └── socketLoader │ │ └── index.js └── webView │ ├── index.html │ └── index.js ├── config ├── config.json └── tty-config.json ├── server ├── .babelrc ├── LICENSE ├── README.md ├── functions │ ├── bluetooth.js │ ├── fn.js │ ├── network.js │ ├── sniff.js │ ├── system.js │ └── wifi.js ├── main.js ├── package.json ├── parse.sed ├── scripts │ ├── genCerts.sh │ ├── genConfig.sh │ ├── getTools.sh │ └── onBoot.sh ├── sniff.js ├── ssl │ ├── new.ssl.csr │ ├── privkey.pem │ ├── server.cert │ └── server.key ├── web │ ├── css │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.min.css │ │ ├── bootstrap.min.css-alpha │ │ ├── ionicons.min.css │ │ └── vis.min.css │ ├── index.html │ └── js │ │ ├── bootstrap.min.js │ │ ├── bootstrap.min.js-alpha │ │ ├── index.js │ │ ├── jquery.min.js │ │ ├── socket.io.min.js │ │ ├── underscore-min.js │ │ └── vis.min.js └── yarn.lock └── ssl ├── new.ssl.csr ├── privkey.pem ├── server.cert └── server.key /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | server/node_modules 33 | 34 | # Optional npm cache directory 35 | .npm 36 | 37 | # Optional REPL history 38 | .node_repl_history 39 | 40 | # SSL certificates 41 | server/ssl/* 42 | ssl/* 43 | 44 | # Ignore config file 45 | server/config/* 46 | config/* 47 | 48 | # OSX 49 | # 50 | .DS_Store 51 | 52 | # Xcode 53 | # 54 | build/ 55 | 56 | *.pbxuser 57 | !default.pbxuser 58 | *.mode1v3 59 | !default.mode1v3 60 | *.mode2v3 61 | !default.mode2v3 62 | *.perspectivev3 63 | !default.perspectivev3 64 | xcuserdata 65 | *.xccheckout 66 | *.moved-aside 67 | DerivedData 68 | *.hmap 69 | *.ipa 70 | *.xcuserstate 71 | project.xcworkspace 72 | 73 | # Android/IntelliJ 74 | # 75 | 76 | build/ 77 | .idea 78 | .gradle 79 | local.properties 80 | *.iml 81 | 82 | # node.js 83 | # 84 | node_modules/ 85 | npm-debug.log 86 | yarn-error.log 87 | yarn.lock 88 | 89 | # BUCK 90 | buck-out/ 91 | .buckd/ 92 | *.keystore 93 | 94 | # fastlane 95 | # 96 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 97 | # screenshots whenever they are needed. 98 | # For more information about the recommended setup visit: 99 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 100 | 101 | fastlane/report.xml 102 | fastlane/Preview.html 103 | fastlane/screenshots 104 | 105 | .ftpconfig 106 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "server/tools/bluemaho"] 2 | path = server/tools/bluemaho 3 | url = https://github.com/zenware/bluemaho 4 | [submodule "server/tools/BT-Device-DOS"] 5 | path = server/tools/BT-Device-DOS 6 | url = https://github.com/DeadPackets/BT-Device-DOS/ 7 | [submodule "server/functions/node-wireless"] 8 | path = server/functions/node-wireless 9 | url = https://github.com/elijahparker/node-wireless/ 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Youssef Awad 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 | # Note: This is unfinished! (Full rewrite of server backend in progress) 2 | # HackPi - Portable Hacking Mothership 3 | 4 | ### Overview 5 | --- 6 | HackPi is a NodeJS project to turn a raspberry pi running kali into a fully portable hacking device. 7 | 8 | 9 | ### Features 10 | --- 11 | - Realtime updates using Socket.io 12 | - Online terminal with https (auto starts on boot) 13 | - Access point for connectivity that starts on boot 14 | - System stats 15 | - Map out surrounding network in a network graph 16 | - Listing available network interfaces 17 | - Nmap scans (all kinds of them) 18 | 19 | ### Todo 20 | --- 21 | - Work on at least inital client side 22 | - Client side system information (Done, just needs to be inserted into client) 23 | - Listing available WiFi points (90% done) 24 | - Running WPSPixie against WiFi points 25 | - Mass WiFi Jamming 26 | - Ability to track down running processes (If I run a mass wifi jamming attack, I want to be able to stop it even if I refresh the page) 27 | - Listing available bluetooth devices + attacks + functionality (turning bluetooth on/off) 28 | - WiFi interface functionality (bringing interfaces up or down, randomizing mac, etc) 29 | - Bluetooth attacks 30 | - Network attacks (Everything from ping flood to MiTM) 31 | - KarmaAP attack with Captive Portal (Credits to mana-toolkit by SensePost) 32 | 33 | -------------------------------------------------------------------------------- /client/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } 4 | -------------------------------------------------------------------------------- /client/android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | lib_deps = [] 12 | 13 | for jarfile in glob(['libs/*.jar']): 14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')] 15 | lib_deps.append(':' + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | 21 | for aarfile in glob(['libs/*.aar']): 22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')] 23 | lib_deps.append(':' + name) 24 | android_prebuilt_aar( 25 | name = name, 26 | aar = aarfile, 27 | ) 28 | 29 | android_library( 30 | name = "all-libs", 31 | exported_deps = lib_deps, 32 | ) 33 | 34 | android_library( 35 | name = "app-code", 36 | srcs = glob([ 37 | "src/main/java/**/*.java", 38 | ]), 39 | deps = [ 40 | ":all-libs", 41 | ":build_config", 42 | ":res", 43 | ], 44 | ) 45 | 46 | android_build_config( 47 | name = "build_config", 48 | package = "com.hackpi", 49 | ) 50 | 51 | android_resource( 52 | name = "res", 53 | package = "com.hackpi", 54 | res = "src/main/res", 55 | ) 56 | 57 | android_binary( 58 | name = "app", 59 | keystore = "//android/keystores:debug", 60 | manifest = "src/main/AndroidManifest.xml", 61 | package_type = "debug", 62 | deps = [ 63 | ":app-code", 64 | ], 65 | ) 66 | -------------------------------------------------------------------------------- /client/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // the root of your project, i.e. where "package.json" lives 37 | * root: "../../", 38 | * 39 | * // where to put the JS bundle asset in debug mode 40 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 41 | * 42 | * // where to put the JS bundle asset in release mode 43 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 44 | * 45 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 46 | * // require('./image.png')), in debug mode 47 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 48 | * 49 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 50 | * // require('./image.png')), in release mode 51 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 52 | * 53 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 54 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 55 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 56 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 57 | * // for example, you might want to remove it from here. 58 | * inputExcludes: ["android/**", "ios/**"], 59 | * 60 | * // override which node gets called and with what additional arguments 61 | * nodeExecutableAndArgs: ["node"] 62 | * 63 | * // supply additional arguments to the packager 64 | * extraPackagerArgs: [] 65 | * ] 66 | */ 67 | 68 | apply from: "../../node_modules/react-native/react.gradle" 69 | 70 | /** 71 | * Set this to true to create two separate APKs instead of one: 72 | * - An APK that only works on ARM devices 73 | * - An APK that only works on x86 devices 74 | * The advantage is the size of the APK is reduced by about 4MB. 75 | * Upload all the APKs to the Play Store and people will download 76 | * the correct one based on the CPU architecture of their device. 77 | */ 78 | def enableSeparateBuildPerCPUArchitecture = false 79 | 80 | /** 81 | * Run Proguard to shrink the Java bytecode in release builds. 82 | */ 83 | def enableProguardInReleaseBuilds = false 84 | 85 | android { 86 | compileSdkVersion 23 87 | buildToolsVersion "23.0.1" 88 | 89 | defaultConfig { 90 | applicationId "com.hackpi" 91 | minSdkVersion 16 92 | targetSdkVersion 22 93 | versionCode 1 94 | versionName "1.0" 95 | ndk { 96 | abiFilters "armeabi-v7a", "x86" 97 | } 98 | } 99 | splits { 100 | abi { 101 | reset() 102 | enable enableSeparateBuildPerCPUArchitecture 103 | universalApk false // If true, also generate a universal APK 104 | include "armeabi-v7a", "x86" 105 | } 106 | } 107 | buildTypes { 108 | release { 109 | minifyEnabled enableProguardInReleaseBuilds 110 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 111 | } 112 | } 113 | // applicationVariants are e.g. debug, release 114 | applicationVariants.all { variant -> 115 | variant.outputs.each { output -> 116 | // For each separate APK per architecture, set a unique version code as described here: 117 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 118 | def versionCodes = ["armeabi-v7a":1, "x86":2] 119 | def abi = output.getFilter(OutputFile.ABI) 120 | if (abi != null) { // null for the universal-debug, universal-release variants 121 | output.versionCodeOverride = 122 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 123 | } 124 | } 125 | } 126 | } 127 | 128 | dependencies { 129 | compile project(':react-native-svg') 130 | compile project(':react-native-vector-icons') 131 | compile project(':react-native-socketio') 132 | compile fileTree(dir: "libs", include: ["*.jar"]) 133 | compile "com.android.support:appcompat-v7:23.0.1" 134 | compile "com.facebook.react:react-native:+" // From node_modules 135 | } 136 | 137 | // Run this once to be able to run the application with BUCK 138 | // puts all compile dependencies into folder libs for BUCK to use 139 | task copyDownloadableDepsToLibs(type: Copy) { 140 | from configurations.compile 141 | into 'libs' 142 | } 143 | -------------------------------------------------------------------------------- /client/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Disabling obfuscation is useful if you collect stack traces from production crashes 20 | # (unless you are using a system that supports de-obfuscate the stack traces). 21 | -dontobfuscate 22 | 23 | # React Native 24 | 25 | # Keep our interfaces so they can be used by other ProGuard rules. 26 | # See http://sourceforge.net/p/proguard/bugs/466/ 27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip 28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters 29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 30 | 31 | # Do not strip any method/class that is annotated with @DoNotStrip 32 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 33 | -keep @com.facebook.common.internal.DoNotStrip class * 34 | -keepclassmembers class * { 35 | @com.facebook.proguard.annotations.DoNotStrip *; 36 | @com.facebook.common.internal.DoNotStrip *; 37 | } 38 | 39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 40 | void set*(***); 41 | *** get*(); 42 | } 43 | 44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 46 | -keepclassmembers,includedescriptorclasses class * { native ; } 47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 50 | 51 | -dontwarn com.facebook.react.** 52 | 53 | # okhttp 54 | 55 | -keepattributes Signature 56 | -keepattributes *Annotation* 57 | -keep class okhttp3.** { *; } 58 | -keep interface okhttp3.** { *; } 59 | -dontwarn okhttp3.** 60 | 61 | # okio 62 | 63 | -keep class sun.misc.Unsafe { *; } 64 | -dontwarn java.nio.file.* 65 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 66 | -dontwarn okio.** 67 | -------------------------------------------------------------------------------- /client/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/Entypo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/Entypo.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/EvilIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/EvilIcons.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/FontAwesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/FontAwesome.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/Foundation.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/Foundation.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/Ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/Ionicons.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/MaterialIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/MaterialIcons.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/Octicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/Octicons.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/SimpleLineIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/SimpleLineIcons.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/assets/fonts/Zocial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/assets/fonts/Zocial.ttf -------------------------------------------------------------------------------- /client/android/app/src/main/java/com/hackpi/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.hackpi; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "HackPi"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /client/android/app/src/main/java/com/hackpi/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.hackpi; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import com.horcrux.svg.RNSvgPackage; 7 | import com.oblador.vectoricons.VectorIconsPackage; 8 | import com.gcrabtree.rctsocketio.SocketIoPackage; 9 | import com.facebook.react.ReactNativeHost; 10 | import com.facebook.react.ReactPackage; 11 | import com.facebook.react.shell.MainReactPackage; 12 | import com.facebook.soloader.SoLoader; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | public class MainApplication extends Application implements ReactApplication { 18 | 19 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 20 | @Override 21 | public boolean getUseDeveloperSupport() { 22 | return BuildConfig.DEBUG; 23 | } 24 | 25 | @Override 26 | protected List getPackages() { 27 | return Arrays.asList( 28 | new MainReactPackage(), 29 | new RNSvgPackage(), 30 | new VectorIconsPackage(), 31 | new SocketIoPackage() 32 | ); 33 | } 34 | }; 35 | 36 | @Override 37 | public ReactNativeHost getReactNativeHost() { 38 | return mReactNativeHost; 39 | } 40 | 41 | @Override 42 | public void onCreate() { 43 | super.onCreate(); 44 | SoLoader.init(this, /* native exopackage */ false); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /client/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /client/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /client/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /client/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /client/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | HackPi 3 | 4 | -------------------------------------------------------------------------------- /client/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /client/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.3' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /client/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/client/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /client/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 6 | -------------------------------------------------------------------------------- /client/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /client/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /client/android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /client/android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /client/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'HackPi' 2 | include ':react-native-svg' 3 | project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android') 4 | include ':react-native-vector-icons' 5 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') 6 | include ':react-native-socketio' 7 | project(':react-native-socketio').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-socketio/android') 8 | 9 | include ':app' 10 | -------------------------------------------------------------------------------- /client/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HackPi", 3 | "displayName": "HackPi" 4 | } 5 | -------------------------------------------------------------------------------- /client/components/settingsCard/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | Dimensions, 7 | Switch, 8 | TextInput 9 | } from 'react-native' 10 | 11 | const {width, height} = Dimensions.get('window') 12 | 13 | export class SwitchSetting extends Component { 14 | constructor() { 15 | super() 16 | this.state = { 17 | value: true 18 | } 19 | } 20 | render() { 21 | return( 22 | 23 | {this.props.setting.title} 24 | {this.setState({value: !this.state.value})}}/> 25 | 26 | ) 27 | } 28 | } 29 | 30 | export class TextSetting extends Component { 31 | constructor() { 32 | super() 33 | this.state = { 34 | value: '' 35 | } 36 | } 37 | render() { 38 | return( 39 | 40 | {this.props.setting.title} 41 | {this.setState({value: t})}} /> 42 | 43 | ) 44 | } 45 | } 46 | 47 | const styles = StyleSheet.create({ 48 | card: { 49 | paddingLeft: 15, 50 | paddingRight: 15, 51 | paddingTop: 10, 52 | paddingBottom: 15, 53 | backgroundColor: '#01223E', 54 | justifyContent: 'space-between', 55 | alignItems: 'center', 56 | flexDirection: 'row', 57 | borderBottomWidth: 1, 58 | borderBottomColor: '#00111F', 59 | width: width-30, 60 | height: 65 61 | }, 62 | textInput: { 63 | height: 40, 64 | borderColor: '#094B81', 65 | borderWidth: 1, 66 | width: width-150, 67 | backgroundColor: '#094B81' 68 | }, 69 | setting: { 70 | fontSize: 20, 71 | color: '#094B81' 72 | }, 73 | switch: {} 74 | }) -------------------------------------------------------------------------------- /client/components/statusCard/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | View, 4 | Dimensions, 5 | StyleSheet, 6 | Text 7 | } from 'react-native'; 8 | import Icon from 'react-native-vector-icons/Ionicons'; 9 | import { StockLine, Bar } from 'react-native-pathjs-charts'; 10 | 11 | const {width, height} = Dimensions.get('window') 12 | const add = (a,b)=>{return a+b} 13 | 14 | export default class StatusCard extends Component { 15 | constructor() { 16 | super() 17 | this.format = this.format.bind(this) 18 | } 19 | format(number) { 20 | if(this.props.status.type == 'bar' && this.props.status.data.length > 0){ 21 | var number = (this.props.status.data.reduce(add, 0)) / this.props.status.data.length; 22 | } 23 | if(number / 1e+9 > 1) { 24 | return parseInt(number / 1e+9) + 'G' 25 | } else if (number / 1000000 > 1) { 26 | return parseInt(number / 1000000) + 'M' 27 | } else if (number / 1000 > 1) { 28 | return parseInt(number / 1000) + 'K' 29 | } else { 30 | return parseInt(number) 31 | } 32 | } 33 | getLineGraphData() { 34 | if(this.props.status.data.length > 0){ 35 | if(this.props.status.data.length > 30){ 36 | var reverse=this.props.status.data.slice(0).reverse(); 37 | reverse.length = 30; 38 | var complete = reverse.slice(0).reverse(); 39 | } else { 40 | var complete = this.props.status.data 41 | } 42 | var graphData = complete.map((i, j) => { 43 | return { "x":j, "y":i } 44 | }) 45 | } else { 46 | var graphData = [{"x": 0, "y": 0}] 47 | } 48 | 49 | var data = [ 50 | graphData 51 | ] 52 | var options = { 53 | width: width - 70, 54 | height: 80, 55 | max: 100, 56 | min: 0, 57 | color: '#094B81', 58 | margin: { 59 | top: 0, 60 | left: 0, 61 | bottom: 0, 62 | right: 0 63 | }, 64 | gutter: 20, 65 | animate: { 66 | type: 'oneByOne', 67 | duration: 200, 68 | fillTransition: 3 69 | }, 70 | axisX: { 71 | showAxis: false, 72 | showLines: false, 73 | showLabels: false, 74 | showTicks: false, 75 | zeroAxis: false, 76 | orient: 'bottom', 77 | label: { 78 | fontFamily: 'Arial', 79 | fontSize: 8, 80 | fontWeight: true, 81 | fill: '#34495E' 82 | } 83 | }, 84 | axisY: { 85 | showAxis: false, 86 | showLines: false, 87 | showLabels: false, 88 | showTicks: false, 89 | zeroAxis: false, 90 | orient: 'left', 91 | label: { 92 | fontFamily: 'Arial', 93 | fontSize: 8, 94 | fontWeight: true, 95 | fill: '#34495E' 96 | } 97 | } 98 | } 99 | 100 | return [options, data] 101 | } 102 | getBarGraphData() { 103 | if(this.props.status.data.length > 0) 104 | var graphData = this.props.status.data.map((i, j) => { 105 | return {"name": "cpu"+(j+1), "v": i} 106 | }) 107 | else 108 | var graphData = [{"name": "cpu1", "v": 0},{"name": "cpu2", "v": 0},{"name": "cpu3", "v": 0},{"name": "cpu4", "v": 0}] 109 | var data = [ 110 | graphData 111 | ] 112 | var options = { 113 | width: width - 70, 114 | height: 80, 115 | color: '#094B81', 116 | margin: { 117 | top: 0, 118 | left: 0, 119 | bottom: 0, 120 | right: 0 121 | }, 122 | gutter: 20, 123 | animate: { 124 | type: 'oneByOne', 125 | duration: 200, 126 | fillTransition: 3 127 | }, 128 | axisX: { 129 | showAxis: false, 130 | showLines: false, 131 | showLabels: false, 132 | showTicks: false, 133 | zeroAxis: false, 134 | orient: 'bottom', 135 | label: { 136 | fontFamily: 'Arial', 137 | fontSize: 8, 138 | fontWeight: true, 139 | fill: '#34495E' 140 | } 141 | }, 142 | axisY: { 143 | min: 0, 144 | max: 100, 145 | showAxis: false, 146 | showLines: false, 147 | showLabels: false, 148 | showTicks: false, 149 | zeroAxis: false, 150 | orient: 'left', 151 | label: { 152 | fontFamily: 'Arial', 153 | fontSize: 8, 154 | fontWeight: true, 155 | fill: '#34495E' 156 | } 157 | } 158 | } 159 | return [options, data] 160 | } 161 | render() { 162 | if(this.props.status.type == 'bar') { 163 | var timeline = "Live" 164 | } else { 165 | var timeline = "30s" 166 | } 167 | if(this.props.status.type == 'line') 168 | var graphData = this.getLineGraphData() 169 | else if (this.props.status.type == 'bar') 170 | var graphData = this.getBarGraphData() 171 | else 172 | var graphData = null; 173 | 174 | if(this.props.status.type == 'line'){ 175 | var graph = 176 | } else if (this.props.status.type == 'bar'){ 177 | var graph = 178 | } 179 | return ( 180 | 181 | 182 | {timeline} 183 | {this.props.status.title} 184 | {this.format(this.props.status.data[this.props.status.data.length-1] || 0)}{this.props.status.unit} 185 | 186 | 187 | {graph} 188 | 189 | 190 | ) 191 | } 192 | } 193 | 194 | const styles = StyleSheet.create({ 195 | card: { 196 | marginBottom: 5, 197 | marginTop: 5, 198 | paddingLeft: 15, 199 | paddingRight: 15, 200 | paddingTop: 10, 201 | paddingBottom: 15, 202 | backgroundColor: '#01223E', 203 | justifyContent: 'space-around', 204 | alignItems: 'center', 205 | flexDirection: 'column', 206 | borderRadius: 5 207 | }, 208 | statusBar: { 209 | flexDirection: 'row', 210 | justifyContent: 'space-between', 211 | width: width-70, 212 | marginBottom: 2 213 | }, 214 | chart: { 215 | borderWidth: 1, 216 | borderColor: '#094B81' 217 | }, 218 | status: { 219 | fontSize: 10, 220 | color: '#094B81' 221 | } 222 | }) 223 | -------------------------------------------------------------------------------- /client/index.android.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View 13 | } from 'react-native'; 14 | 15 | export default class oo extends Component { 16 | render() { 17 | return ( 18 | 19 | 20 | Welcome to React Native! 21 | 22 | 23 | To get started, edit index.android.js 24 | 25 | 26 | Double tap R on your keyboard to reload,{'\n'} 27 | Shake or press menu button for dev menu 28 | 29 | 30 | ); 31 | } 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | container: { 36 | flex: 1, 37 | justifyContent: 'center', 38 | alignItems: 'center', 39 | backgroundColor: '#F5FCFF', 40 | }, 41 | welcome: { 42 | fontSize: 20, 43 | textAlign: 'center', 44 | margin: 10, 45 | }, 46 | instructions: { 47 | textAlign: 'center', 48 | color: '#333333', 49 | marginBottom: 5, 50 | }, 51 | }); 52 | 53 | AppRegistry.registerComponent('oo', () => oo); 54 | -------------------------------------------------------------------------------- /client/index.ios.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Children } from 'react'; 2 | import { 3 | AppRegistry, 4 | View, 5 | StatusBar, 6 | AsyncStorage 7 | } from 'react-native'; 8 | 9 | import io from 'socket.io-client'; 10 | 11 | import App from './screens/app'; 12 | import SocketLoader from './screens/socketLoader'; 13 | 14 | export default class HackPi extends Component { 15 | constructor() { 16 | super() 17 | this.state = { 18 | connected: false 19 | } 20 | this.socket = null; 21 | } 22 | componentWillMount() { 23 | AsyncStorage.getItem('@HackPi:IP', (err, result)=>{ 24 | if(err) { 25 | //console.log(err) 26 | this.setState({ 27 | error: true 28 | }) 29 | } else { 30 | //console.log(result) 31 | if(result){ 32 | this.socket = io.connect(result, { secure: false, jsonp: false, reconnectionDelay: 5000, transports: ['websocket'], upgrade: false, debug: true }) 33 | } else { 34 | this.socket = io.connect("192.168.69.1:1337", { secure: false, jsonp: false, reconnectionDelay: 5000, transports: ['websocket'], upgrade: false, debug: true }) 35 | } 36 | this.setState(this.state) 37 | } 38 | }) 39 | 40 | } 41 | render() { 42 | //console.log(!this.state.error && this.socket) 43 | if(!this.state.error && this.socket){ 44 | //will implement Navigator soon 45 | var appropriateScreen; 46 | if(this.socket.connected == true) { 47 | appropriateScreen = 48 | } else { 49 | appropriateScreen = 50 | } 51 | return ( 52 | 53 | 56 | {appropriateScreen} 57 | 58 | ) 59 | } else { 60 | return null 61 | } 62 | } 63 | } 64 | 65 | AppRegistry.registerComponent('HackPi', () => HackPi); 66 | -------------------------------------------------------------------------------- /client/ios/HackPi-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSExceptionDomains 28 | 29 | localhost 30 | 31 | NSExceptionAllowsInsecureHTTPLoads 32 | 33 | 34 | 35 | 36 | NSLocationWhenInUseUsageDescription 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /client/ios/HackPi-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /client/ios/HackPi.xcodeproj/xcshareddata/xcschemes/HackPi-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /client/ios/HackPi.xcodeproj/xcshareddata/xcschemes/HackPi.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /client/ios/HackPi/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /client/ios/HackPi/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import 13 | #import 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 18 | { 19 | NSURL *jsCodeLocation; 20 | 21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; 22 | 23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 24 | moduleName:@"HackPi" 25 | initialProperties:nil 26 | launchOptions:launchOptions]; 27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 28 | 29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 30 | UIViewController *rootViewController = [UIViewController new]; 31 | rootViewController.view = rootView; 32 | self.window.rootViewController = rootViewController; 33 | [self.window makeKeyAndVisible]; 34 | return YES; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /client/ios/HackPi/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /client/ios/HackPi/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /client/ios/HackPi/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | HackPi 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UIViewControllerBasedStatusBarAppearance 40 | 41 | NSLocationWhenInUseUsageDescription 42 | 43 | NSAppTransportSecurity 44 | 45 | NSExceptionDomains 46 | 47 | localhost 48 | 49 | NSExceptionAllowsInsecureHTTPLoads 50 | 51 | 52 | 53 | 54 | UIAppFonts 55 | 56 | Entypo.ttf 57 | EvilIcons.ttf 58 | FontAwesome.ttf 59 | Foundation.ttf 60 | Ionicons.ttf 61 | MaterialCommunityIcons.ttf 62 | MaterialIcons.ttf 63 | Octicons.ttf 64 | SimpleLineIcons.ttf 65 | Zocial.ttf 66 | 67 | 68 | -------------------------------------------------------------------------------- /client/ios/HackPi/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /client/ios/HackPiTests/HackPiTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import 12 | 13 | #import 14 | #import 15 | 16 | #define TIMEOUT_SECONDS 600 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface HackPiTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation HackPiTests 24 | 25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 26 | { 27 | if (test(view)) { 28 | return YES; 29 | } 30 | for (UIView *subview in [view subviews]) { 31 | if ([self findSubviewInView:subview matching:test]) { 32 | return YES; 33 | } 34 | } 35 | return NO; 36 | } 37 | 38 | - (void)testRendersWelcomeScreen 39 | { 40 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; 41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 42 | BOOL foundElement = NO; 43 | 44 | __block NSString *redboxError = nil; 45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 46 | if (level >= RCTLogLevelError) { 47 | redboxError = message; 48 | } 49 | }); 50 | 51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 54 | 55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 57 | return YES; 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | RCTSetLogFunction(RCTDefaultLogFunction); 64 | 65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /client/ios/HackPiTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HackPi", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start", 7 | "test": "jest", 8 | "android": "react-native run-android", 9 | "ios": "react-native run-ios", 10 | "reset": "react-native eject" 11 | }, 12 | "dependencies": { 13 | "react": "16.0.0-alpha.6", 14 | "react-native": "^0.43.1", 15 | "react-native-chart": "^1.0.8-beta", 16 | "react-native-pathjs-charts": "^0.0.26", 17 | "react-native-socketio": "^0.3.0", 18 | "react-native-vector-icons": "^4.0.1", 19 | "react-native-webview-bridge": "^0.33.0", 20 | "socket.io-client": "1.5.x", 21 | "socket.io-react": "^1.1.2", 22 | "undefined": "^0.1.0" 23 | }, 24 | "devDependencies": { 25 | "babel-jest": "19.0.0", 26 | "babel-preset-react-native": "1.9.1", 27 | "jest": "19.0.2", 28 | "react-native-cli": "*", 29 | "react-test-renderer": "16.0.0-alpha.6" 30 | }, 31 | "jest": { 32 | "preset": "react-native" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /client/screens/app/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | View, 4 | Text, 5 | StyleSheet, 6 | TabBarIOS, 7 | ScrollView, 8 | WebView 9 | } from 'react-native'; 10 | 11 | import Icon from 'react-native-vector-icons/Ionicons'; 12 | import StatusCard from '../../components/statusCard'; 13 | import { 14 | SwitchSetting, 15 | TextSetting 16 | } from '../../components/settingsCard'; 17 | 18 | export default class App extends Component { 19 | constructor() { 20 | super() 21 | this.state = { 22 | currentTab: 'status', 23 | status: { 24 | temp: { 25 | title: 'Temperature', 26 | unit: 'deg', 27 | data: [], 28 | type: 'line' 29 | }, 30 | memory: { 31 | title: 'Memory Usage', 32 | unit: '%', 33 | data: [], 34 | type: 'line' 35 | }, 36 | cpu: { 37 | title: 'CPU Usage', 38 | unit: '%', 39 | data: [], 40 | type: 'line' 41 | } 42 | } 43 | } 44 | this.getSystemUpdates = this.getSystemUpdates.bind(this) 45 | } 46 | componentDidMount() { 47 | setInterval(this.getSystemUpdates, 1000) 48 | } 49 | getSystemUpdates() { 50 | var socket = this.props.socket; 51 | var that = this; 52 | socket.emit('get system info', (data)=>{ 53 | if(data && typeof data === 'object') { 54 | that.setState({ 55 | status: { 56 | ...this.state.status, 57 | temp: { 58 | ...this.state.status.temp, 59 | data: [...this.state.status.temp.data, data.cpu.temp.max] 60 | }, 61 | memory: { 62 | ...this.state.status.memory, 63 | data: [...this.state.status.memory.data, (data.mem.used / data.mem.total) * 100] 64 | }, 65 | cpu: { 66 | ...this.state.status.cpu, 67 | data: [...this.state.status.cpu.data, data.cpu.load.currentload] 68 | } 69 | } 70 | }) 71 | } 72 | }) 73 | Object.keys(this.state.status).every((i)=>{ 74 | if(this.state.status[i].data.length > 30) { 75 | console.log(this.state.status[i].data.length) 76 | var reverse=this.state.status[i].data.slice(0).reverse(); 77 | reverse.length = 30; 78 | var complete = reverse.slice(0).reverse(); 79 | var newStatus = { 80 | ...this.state.status 81 | } 82 | newStatus[i] = { 83 | ...this.state.status[i], 84 | data: complete 85 | } 86 | this.setState({ 87 | status: { 88 | ...this.state.status, 89 | ...newStatus 90 | } 91 | }) 92 | } 93 | }) 94 | } 95 | render() { 96 | var data = Object.keys(this.state.status).map((i)=>{ 97 | return 98 | }) 99 | return ( 100 | 101 | 105 | { this.setState({ currentTab: 'status' }) }}> 111 | 112 | 113 | 114 | {data} 115 | 116 | 117 | 118 | 119 | { this.setState({ currentTab: 'node map' }) }}> 125 | { 130 | console.log(JSON.parse(e.nativeEvent.data)) 131 | }} 132 | /> 133 | 134 | { this.setState({ currentTab: 'settings' }) }}> 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | ) 154 | } 155 | } 156 | 157 | const styles = StyleSheet.create({ 158 | container: { 159 | flex: 1, 160 | backgroundColor: '#00111F' 161 | }, 162 | text: { 163 | color: '#4D6C47', 164 | fontSize: 20 165 | }, 166 | tab: { 167 | marginTop: 10, 168 | flex: 1, 169 | alignItems: 'center' 170 | }, 171 | web: { 172 | flex: 1 173 | } 174 | }) 175 | -------------------------------------------------------------------------------- /client/screens/socketLoader/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | AppRegistry, 4 | StyleSheet, 5 | Text, 6 | View, 7 | Image, 8 | TouchableOpacity, 9 | AlertIOS, 10 | AsyncStorage 11 | } from 'react-native'; 12 | import Icon from 'react-native-vector-icons/Ionicons' 13 | 14 | export default class SocketLoader extends Component { 15 | constructor() { 16 | super() 17 | this.state = { 18 | status: 'CONNECTING', 19 | red: false 20 | } 21 | } 22 | 23 | componentDidMount() { 24 | var socket = this.props.socket; 25 | // console.log(socket) 26 | socket.on('connect_error', (data)=>{ 27 | this.setState({ status: data.toString().toUpperCase(), red: true }) 28 | }) 29 | socket.on('reconnect_attempt', ()=>{ 30 | this.setState({ status: 'RETRYING', red: false }) 31 | }) 32 | 33 | } 34 | formatIP(uri) { 35 | return uri.replace('http://', '') 36 | } 37 | getNewIP() { 38 | AlertIOS.prompt( 39 | 'New IP', 40 | 'This will be used to make the socket connection.', 41 | [ 42 | {text: 'Cancel', onPress: () => /*console.log('Cancel Pressed')*/, style: 'cancel'}, 43 | {text: 'OK', onPress: ip => { 44 | AsyncStorage.setItem('@HackPi:IP', ip) 45 | }}, 46 | ], 47 | 'plain-text' 48 | ); 49 | } 50 | render() { 51 | let status = this.state.red ? styles.red : styles.green; 52 | return ( 53 | 54 | HackPi 55 | 56 | {this.formatIP(this.props.socket.io.uri)} 57 | 58 | 59 | {this.state.status} 60 | 61 | ); 62 | } 63 | } 64 | 65 | const styles = StyleSheet.create({ 66 | container: { 67 | flex: 1, 68 | justifyContent: 'center', 69 | alignItems: 'center', 70 | backgroundColor: '#1D211D', 71 | }, 72 | ip: { 73 | flexDirection: 'row', 74 | justifyContent: 'center', 75 | alignItems: 'center' 76 | }, 77 | edit: { 78 | color: '#4D6C47', 79 | fontSize: 25, 80 | marginLeft: 5 81 | }, 82 | text: { 83 | fontSize: 100, 84 | textAlign: 'center', 85 | color: '#4D6C47', 86 | fontWeight: "100" 87 | }, 88 | info: { 89 | textAlign: 'center', 90 | fontSize: 30, 91 | color: '#4D6C47', 92 | fontWeight: "100" 93 | }, 94 | status: { 95 | textAlign: 'center', 96 | fontSize: 30, 97 | color: '#4D6C47', 98 | fontWeight: "100" 99 | }, 100 | red: { 101 | color: '#AB5042' 102 | }, 103 | image: { 104 | height: 100, 105 | width: 100, 106 | margin: 20 107 | } 108 | }); 109 | -------------------------------------------------------------------------------- /client/webView/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Network Graph 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /client/webView/index.js: -------------------------------------------------------------------------------- 1 | var options = { 2 | autoResize: true, 3 | height: '100%', 4 | width: '100%', 5 | clickToUse: true, 6 | configure: { 7 | enabled: false 8 | }, 9 | edges: { 10 | smooth: { 11 | forceDirection: 'none', 12 | roundness: 1 13 | } 14 | }, 15 | physics: { 16 | forceAtlas2Based: { 17 | springLength: 60, 18 | springConstant: 0.1, 19 | damping: 1, 20 | avoidOverlap: 1 21 | }, 22 | minVelocity: 0.3, 23 | solver: "forceAtlas2Based", 24 | timestep: 0.11 25 | } 26 | } 27 | 28 | var nodes = []; 29 | var oldNodes = []; 30 | var edges = []; 31 | var oldEdges = []; 32 | var container = document.getElementById('map'); 33 | var network = new vis.Network(container, { nodes, edges }, options) 34 | 35 | if(webViewBridge) { 36 | //injected webview bridge variable is available by react native 37 | 38 | webViewBridge.onMessage = (raw) => { 39 | //new data from react native, in this case the graph data 40 | 41 | //convert text data to native object 42 | var data = JSON.parse(raw) 43 | 44 | if(data.type == 'graph update') { 45 | graphUpdate(data.payload) 46 | } 47 | 48 | } 49 | 50 | //click listeners for functions.. I dont want to trigger any type of meny in the webView 51 | //it will have a lack of performence etc.. I will use IOS default menu for now. 52 | network.on('click', (e) => { 53 | var stringData = JSON.stringify({ 54 | event: 'click', 55 | eventData: e 56 | }) 57 | webViewBridge.sendMessage(stringData) 58 | }) 59 | } 60 | 61 | 62 | //load new data, redraw 63 | function graphUpdate (nodes) { 64 | 65 | nodes = new vis.DataSet(nodes) 66 | network.redraw() 67 | } 68 | -------------------------------------------------------------------------------- /config/config.json: -------------------------------------------------------------------------------- 1 | { "test": "hello" } 2 | -------------------------------------------------------------------------------- /config/tty-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "shell": "bash", 3 | "users": { 4 | "HackPi": "d7a231cb234e47ab599039e36eb07e143ab75318" 5 | }, 6 | "cwd": "~/", 7 | "localOnly": false, 8 | "https": { 9 | "key": "/home/pi/HackPi/ssl/server.key", 10 | "cert": "/home/pi/HackPi/ssl/server.cert" 11 | }, 12 | "port": 13370 13 | } 14 | -------------------------------------------------------------------------------- /server/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env"] 3 | } 4 | -------------------------------------------------------------------------------- /server/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Youssef Awad 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 | -------------------------------------------------------------------------------- /server/README.md: -------------------------------------------------------------------------------- 1 | # HackPi - Portable Hacking Mothership 2 | 3 | ### Overview 4 | --- 5 | HackPi is a NodeJS project to turn a raspberry pi running kali into a fully portable hacking device. 6 | 7 | 8 | ### Features 9 | --- 10 | - Realtime updates using Socket.io 11 | - Online terminal with https (auto starts on boot) 12 | - Ad-hoc style access point for connectivity that starts on boot 13 | - System stats 14 | 15 | 16 | ### Todo 17 | --- 18 | - Update the Features (xD) 19 | - Work on at least inital client side 20 | - Client side system information 21 | - Listing available network interfaces 22 | - Listing available WiFi points 23 | - Running WPSPixie against WiFi points 24 | - Mass WiFi Jamming 25 | - Ability to track down running processes (If I run a mass wifi jamming attack, I want to be able to stop it even if I refresh the page) 26 | - Listing available bluetooth devices + attacks + functionality (turning bluetooth on/off) 27 | - WiFi interface functionality (bringing interfaces up or down, randomizing mac, etc) 28 | - And waaay more. 29 | 30 | 31 | -------------------------------------------------------------------------------- /server/functions/bluetooth.js: -------------------------------------------------------------------------------- 1 | import Scanner from 'bluetooth-scanner'; 2 | import bluetooth from 'bluetooth'; 3 | import { 4 | exec, 5 | spawn 6 | } from 'child_process'; 7 | 8 | export const ListBluetoothIfaces = (cb) => { 9 | //exec hciconfig here 10 | const listbluetooth = exec('hciconfig') 11 | 12 | listbluetooth.stderr.on('data', (data) => { 13 | cb('fail', data) 14 | }) 15 | 16 | //catch stdout here 17 | } 18 | 19 | export const BluetoothState = (iface, cb) => { 20 | //todo using bluetooth package 21 | 22 | } 23 | 24 | export const BluetoothToggle = (iface, cb) => { 25 | //todo using bluetooth package 26 | } 27 | 28 | export const DoSBluetooth = (iface, device, cb) => { 29 | //Denial of service for bluetooth here 30 | } 31 | 32 | export const BluetoothPingFlood = (iface, device, cb) => { 33 | //Ping flood 34 | } 35 | 36 | export const BlueoothPing = (iface, device, cb) => { 37 | //Ping certain bluetooth device (maybe find approx distance?) 38 | } 39 | 40 | export const ScanBluetooth = (iface, cb) => { 41 | bleScanner = new Scanner(iface, cb, (mac, name) => { 42 | cb(mac, name) //callback gets executed each time a new device is found 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /server/functions/fn.js: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import fs from 'fs'; 3 | import si from 'systeminformation'; 4 | import os from 'os'; 5 | import ifconfig from 'wireless-tools/ifconfig' 6 | import { 7 | CheckIfaceState 8 | } from './wifi'; 9 | import SYSINFO from '../main'; 10 | import _ from 'underscore'; 11 | import { 12 | exec, 13 | spawn 14 | } from 'child_process'; 15 | import nmap from 'node-nmap'; 16 | import xml2js from 'xml2js'; 17 | import ip from 'ip'; 18 | import prettyBytes from 'pretty-bytes'; 19 | import oui from 'oui'; 20 | 21 | export var IFCONFIG_IFACES = []; 22 | export var TRACK_IFACES = []; 23 | var IFACES_STATE = []; 24 | export default IFACES_STATE; 25 | /* 26 | 27 | Global object method 28 | 29 | var IFACES_STATE = { 30 | ifaces: [], 31 | state: [{}, {}] 32 | } 33 | */ 34 | 35 | setInterval(() => { 36 | UpdateCPUInfo() 37 | UpdateFSInfo() 38 | UpdateRAMInfo() 39 | UpdateSwapInfo() 40 | }, 300) 41 | 42 | setInterval(() => { 43 | UpdateInterfaceInfo() 44 | }, 100) 45 | 46 | setInterval(() => { 47 | UpdateUptime() 48 | }, 1000) 49 | 50 | setInterval(() => { 51 | UpdateInterfaceState() 52 | }, 500) 53 | 54 | var firstrun = true; 55 | export const UpdateInterfaceState = () => { 56 | if (firstrun == true) { 57 | //running for the first time, push all interfaces to global array 58 | IFCONFIG_IFACES.forEach((data, index) => { 59 | TRACK_IFACES.push(data) 60 | var obj = { 61 | interface: data, 62 | state: { 63 | busy: false, 64 | process: 'none' 65 | } 66 | } 67 | IFACES_STATE.push(obj) 68 | 69 | //console.log("Added interface " + data + "!") 70 | }) 71 | //not first time anymore 72 | firstrun = false 73 | } else { 74 | //this isnt the first time this function is run 75 | if (IFCONFIG_IFACES.length > TRACK_IFACES.length) { 76 | //new interface plugged in 77 | var diff = _.difference(IFCONFIG_IFACES, TRACK_IFACES) //returns new interface name 78 | diff.forEach((data, index) => { 79 | TRACK_IFACES.push(data) 80 | var obj = { 81 | interface: data, 82 | state: { 83 | busy: false, 84 | process: 'none' 85 | } 86 | } 87 | IFACES_STATE.push(obj) 88 | console.log("Interface " + data + " was added.", TRACK_IFACES) 89 | }) 90 | } else if (IFCONFIG_IFACES.length < TRACK_IFACES.length) { 91 | //interface disconnected 92 | var diff = _.difference(TRACK_IFACES, IFCONFIG_IFACES) //returns interface that was disconnected 93 | diff.forEach((data, index) => { 94 | console.log("Interface " + data + " was removed.", TRACK_IFACES) 95 | var i = TRACK_IFACES.indexOf(data) 96 | TRACK_IFACES.splice(i, 1) 97 | IFACES_STATE.splice(i, 1) 98 | //console.log(TRACK_IFACES) 99 | }) 100 | } 101 | /* 102 | 103 | //Reason this is commented out is, I expected monitor mode to rename interfaces into mon0 and such, turns out it simply just adds a new iface. 104 | //I might add this for compatability with other distros later. 105 | 106 | TRACK_IFACES.forEach((data, index) => { 107 | if (TRACK_IFACES[index] == IFACES_STATE[index].interface) { 108 | //console.log("Nothing wrong here.") 109 | } else { 110 | console.log("Interface " + IFACES_STATE[index].interface + " was renamed to " + TRACK_IFACES[index] + "!") 111 | } 112 | }) 113 | */ 114 | } 115 | } 116 | 117 | export const secondsToString = (seconds) => { 118 | var numdays = Math.floor(seconds / 86400); 119 | var numhours = Math.floor((seconds % 86400) / 3600); 120 | var numminutes = Math.floor(((seconds % 86400) % 3600) / 60); 121 | var numseconds = Math.floor(((seconds % 86400) % 3600) % 60); 122 | if (numdays < 1) { 123 | if (numhours < 1) { 124 | if (numminutes < 1) { 125 | return numseconds + " seconds"; 126 | } else { 127 | return numminutes + " minutes " + numseconds + " seconds"; 128 | } 129 | } else { 130 | return numhours + " hours " + numminutes + " minutes " + numseconds + " seconds"; 131 | } 132 | } else { 133 | return numdays + " days " + numhours + " hours " + numminutes + " minutes " + numseconds + " seconds"; 134 | } 135 | } 136 | 137 | export const UpdateCPUInfo = () => { 138 | si.cpuCurrentspeed(function(speed) { 139 | si.cpuTemperature(function(temp) { 140 | si.currentLoad(function(load) { 141 | SYSINFO.cpu = { 142 | speed, 143 | temp, 144 | load 145 | } 146 | }) 147 | }) 148 | }) 149 | } 150 | 151 | export const UpdateFSInfo = () => { 152 | var fssize = si.fsSize(function(fssize) { 153 | var ioinfo = si.disksIO(function(ioinfo) { 154 | var rwinfo = si.fsStats(function(rwinfo) { 155 | SYSINFO.fs = { 156 | fssize, 157 | ioinfo, 158 | rwinfo 159 | } 160 | }) 161 | }) 162 | }) 163 | } 164 | 165 | export const UpdateInterfaceInfo = () => { 166 | 167 | ifconfig.status((error, interfaces) => { 168 | if (error) { 169 | console.log("Error!") 170 | } 171 | if (interfaces) { 172 | SYSINFO.interfaces = interfaces 173 | IFCONFIG_IFACES = [] 174 | interfaces.forEach((data, index) => { 175 | var mac = SYSINFO.interfaces[index].address 176 | var ifacename = SYSINFO.interfaces[index].interface 177 | IFCONFIG_IFACES.push(data.interface) 178 | if (mac !== undefined) { 179 | SYSINFO.interfaces[index].vendor = oui(mac).split(/\r?\n/)[0] 180 | } 181 | if (ifacename.indexOf('wlan') < 0) {} else if (ifacename.indexOf('mon') < 0) { 182 | CheckIfaceState(ifacename, function(status, data) { 183 | if (status == 'fail') { 184 | console.logo("Error!", data) 185 | } else { 186 | SYSINFO.interfaces[index].wirelessdata = data 187 | } 188 | }) 189 | } 190 | 191 | }) 192 | } 193 | }) 194 | 195 | } 196 | 197 | export const UpdateRAMInfo = () => { 198 | var usedmem = os.totalmem() - os.freemem() 199 | SYSINFO.mem = { 200 | free: prettyBytes(os.freemem()), 201 | total: prettyBytes(os.totalmem()), 202 | used: prettyBytes(usedmem) 203 | } 204 | } 205 | 206 | export const UpdateSwapInfo = () => { 207 | var swapinfo = si.mem(function(data) { 208 | SYSINFO.swap = data; 209 | }) 210 | } 211 | 212 | export const UpdateUptime = () => { 213 | SYSINFO.osuptime = secondsToString(os.uptime()) 214 | SYSINFO.uptime = secondsToString(process.uptime()) 215 | } 216 | 217 | export const Reboot = () => { 218 | exec('shutdown -r now') 219 | } 220 | 221 | export const Shutdown = () => { 222 | exec('shutdown -P now') 223 | } 224 | 225 | export const ScanTargetPort = (iface, target, port, cb) => { 226 | //scan target for certain ports (cuz why not?) 227 | } 228 | export const ScanNetworkPort = (iface, port, cb) => { 229 | //scan entire local network for port or array of ports 230 | } 231 | 232 | export const ScanTarget = (iface, target, cb) => { 233 | 234 | var parser = new xml2js.Parser(); 235 | const scan = exec('nmap -sS -sV -T4 -Pn --max-retries 2 -O --min-rate 300 --no-stylesheet -oX /root/' + target + '.xml -e ' + iface + ' ' + target) 236 | console.log("Scan started!") 237 | scan.stderr.on('data', (data) => { 238 | cb('fail', data) 239 | }); 240 | scan.on('exit', () => { 241 | fs.readFile('/root/' + target + '.xml', (err, data) => { 242 | if (err) 243 | cb('fail', err) 244 | parser.parseString(data, (err, result) => { 245 | if (err) 246 | cb('fail', err) 247 | cb('success', result) 248 | console.log('Done'); 249 | }); 250 | }); 251 | //delete xml scan result when done 252 | fs.unlink('/root' + target + '.xml', (err) => { 253 | if (err) 254 | console.log(err) 255 | }) 256 | }) 257 | } 258 | export const ScanLocal = (iface, cb) => { 259 | var localrange; 260 | ifconfig.status(iface, (err, status) => { 261 | if (err) 262 | cb('fail', err) 263 | var check = TRACK_IFACES.indexOf(iface) 264 | if (IFACES_STATE[check].state.busy == false) { 265 | var subnet = ip.subnet(status.ipv4_address, status.ipv4_subnet_mask).subnetMaskLength 266 | localrange = status.ipv4_address + '/' + subnet 267 | 268 | IFACES_STATE[check].state.busy = true 269 | IFACES_STATE[check].state.process = "Local nmap scan of range " + localrange 270 | 271 | var nmapscan = new nmap.nodenmap.NmapScan(localrange, '-sn', '-T4', '--max-retries 1', '-e ' + iface); 272 | console.log("Created new scan", localrange) 273 | 274 | nmapscan.on('error', (error) => { 275 | cb('fail', error) 276 | }); 277 | //Add to interface status array that this iface is now busy with a ping sweep. 278 | nmapscan.on('complete', (data) => { 279 | IFACES_STATE[check].state.busy = false 280 | IFACES_STATE[check].state.process = 'none' 281 | cb('success', data, nmapscan.scanTime) 282 | }) 283 | 284 | nmapscan.startScan() 285 | } else { 286 | cb("Cannot use specified interface, it is busy.", iface, IFACES_STATE[check].state.process) //TODO: change to normal syntax 287 | } 288 | }) 289 | 290 | } 291 | 292 | export const Log = { 293 | e: function(data) { 294 | var date = new Date(); 295 | console.log('ERROR'.red, data); 296 | }, 297 | i: function(data) { 298 | var date = new Date(); 299 | console.log('INFO'.green, data); 300 | }, 301 | w: function(data) { 302 | var date = new Date(); 303 | console.log('WARN'.yellow, data); 304 | }, 305 | d: function(data) { 306 | console.log('DEBUG'.blue, data); 307 | } 308 | } 309 | -------------------------------------------------------------------------------- /server/functions/network.js: -------------------------------------------------------------------------------- 1 | //networking functions (ping, GET, and attacks) go here 2 | -------------------------------------------------------------------------------- /server/functions/sniff.js: -------------------------------------------------------------------------------- 1 | import pcap from 'pcap2'; 2 | const INT = 'eth0'; 3 | 4 | export const ARP = new pcap.Session(INT, { filter: 'arp' } ) 5 | export const TCP = new pcap.Session(INT, { filter: 'tcp' } ) 6 | export const UDP = new pcap.Session(INT, { filter: 'udp' } ) 7 | -------------------------------------------------------------------------------- /server/functions/system.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeadPackets/HackPi/0e86557678d6cf3c682a6098f3e17ba6b523015d/server/functions/system.js -------------------------------------------------------------------------------- /server/functions/wifi.js: -------------------------------------------------------------------------------- 1 | /* 2 | TODO: 3 | 4 | - WPS Pixie attacks 5 | - Karma AP attacks 6 | - DeAuth attacks 7 | - Probe spam attacks 8 | - Implement WEP cracking (this has such a low priority though due to the time it takes) 9 | 10 | */ 11 | import hostapd from 'wireless-tools/hostapd'; 12 | import ifconfig from 'wireless-tools/ifconfig'; 13 | import iwconfig from 'wireless-tools/iwconfig'; 14 | //import iwlist from 'wireless-tools/iwlist'; 15 | //import iw from 'wireless-tools/iw'; 16 | //import udhcpc from 'wireless-tools/udhcpc'; 17 | import wpa_supplicant from 'wireless-tools/wpa_supplicant'; 18 | import SYSINFO from '../main'; 19 | import Wireless from './node-wireless/index'; 20 | import { 21 | exec, 22 | spawn 23 | } from 'child_process'; 24 | import NewWifiResult from '../main'; 25 | import { 26 | TRACK_IFACES 27 | } from './fn'; 28 | import IFACES_STATE from './fn'; 29 | var WIFI; 30 | 31 | export const ScanWifi = (iface, cb) => { 32 | //check for busy stuff 33 | console.log("Starting scan on interface " + iface) 34 | 35 | var wifi = new Wireless({ 36 | iface: iface, 37 | vanishThreshold: 3 38 | }) 39 | 40 | var wireless = { 41 | iface: iface, 42 | wifi: wifi 43 | } 44 | 45 | WIFI = wireless 46 | 47 | wifi.enable((err) => { 48 | if (err) { 49 | cb('fail', err) 50 | } 51 | }) 52 | 53 | wifi.start() 54 | 55 | //mark interface as busy 56 | 57 | var i = TRACK_IFACES.indexOf(iface) 58 | IFACES_STATE[i].state.busy = true 59 | IFACES_STATE[i].state.process = 'Scanning for WiFi' 60 | 61 | wifi.on('appear', (data, iface) => { 62 | cb("data", data) 63 | }) 64 | 65 | wifi.on('vanish', (data, iface) => { 66 | //console.log(data) 67 | }) 68 | 69 | wifi.on('signal', (data, iface) => { 70 | //signal changes 71 | }) 72 | 73 | wifi.on('change', (data, iface) => { 74 | //properties change 75 | }) 76 | 77 | wifi.on('error', (err, iface) => { 78 | console.log(err) 79 | }) 80 | 81 | wifi.on('empty', (data, iface) => { 82 | //empty network scan 83 | console.log("empty", data) 84 | }) 85 | 86 | } 87 | 88 | export const StopMainWifiIface = (cb) => { 89 | WIFI.wifi.stop(function(data) { 90 | cb(data) 91 | }) 92 | } 93 | 94 | //i dont think we need this anymore 95 | export const CheckIfaceState = (iface, cb) => { 96 | //needs to check if interface is up and so on 97 | iwconfig.status(iface, (err, status) => { 98 | if (err) 99 | cb('fail', err) 100 | cb('success', status) 101 | }); 102 | } 103 | 104 | export const DisconnectWifi = (iface, cb) => { 105 | //I think this purely depends on the security of the connected router 106 | } 107 | 108 | //this is useless at this point 109 | export const CheckAllIfaces = (cb) => { 110 | iwconfig.status((err, status) => { 111 | if (err) { 112 | cb('fail', err) 113 | } else { 114 | cb('success', status) 115 | } 116 | }) 117 | } 118 | 119 | export const WPSPixie = (iface, options, cb) => { 120 | //run wps pixie command on wifi 121 | //needs also output processing 122 | //needs error handling (timeout and stuff) 123 | } 124 | export const EnableMonitorMode = (iface, cb) => { 125 | //Add the "busy" tag to the interfaces 126 | } 127 | 128 | export const DisableMonitorMode = (iface, cb) => { 129 | //Remove the busy tag from the interface 130 | } 131 | 132 | export const ConnectToWifi = (iface, options, cb) => { 133 | /* 134 | var options = { 135 | bssid: xx:xx:xx:xx //optional 136 | essid: "FreeWifi" 137 | security: { 138 | passphrase: "secretpass" 139 | type: WPA2 140 | } 141 | } 142 | */ 143 | if (options.security !== 'open') { 144 | //OPEN goes here 145 | //native commands are the only way 146 | } else { 147 | //encrypted wifi 148 | if (options.security == 'wep') { 149 | //WEP goes here 150 | //I think we will have to use native comamnds here 151 | } else { 152 | //WPA or WPA2 goes here 153 | //we can use wpa_supplicant for this one 154 | } 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /server/main.js: -------------------------------------------------------------------------------- 1 | require("babel-core").transform("code"); 2 | 3 | import IO from 'socket.io'; 4 | import express from 'express'; 5 | import https from 'https'; 6 | var app = express() 7 | var port = 1337 //change this to 1337 once dev is done (its 443 because I dev at school) (Should we turn this into a config controlled port?) 8 | import fs from 'fs'; 9 | var options = { 10 | key: fs.readFileSync(__dirname + '/ssl/server.key'), 11 | cert: fs.readFileSync(__dirname + '/ssl/server.cert') 12 | }; 13 | 14 | /* 15 | 16 | EXAMPLE OF GLOBAL TRACKING OBJECT 17 | --------------------------------- 18 | 19 | var obj = { 20 | interface: 'wlan0', 21 | mac: 'mac of card', 22 | type: 'wireless', 23 | status: { 24 | busy: false, 25 | process: null //due to busy being false 26 | }, 27 | isup: true, //interface is up 28 | connected: false //not connected to wifi, not neccessarily busy yknow? 29 | } 30 | 31 | var ob2 = { 32 | interface: 'wlan1', 33 | type: 'wireless', 34 | status: { 35 | busy: true, 36 | process: { 37 | type: 'WIFI_DOS', ///could be anything, MiTM, MASS_JAM, WPS_ATTACK, SCANNING and so on 38 | bssid: 'mac address of attacked wifi point', 39 | essid: 'ssid of attacked wifi point' 40 | } 41 | }, 42 | isup: true, 43 | connected: false //not connected 44 | } 45 | 46 | var obj3 = { 47 | interface: 'wlan2', 48 | type: 'wireless', 49 | status: { 50 | busy: false, 51 | process: null 52 | }, 53 | isup: true, 54 | connected: { 55 | bssid: 'mac of connected access point', 56 | essid: 'name of connected access point', 57 | ip: 'ip of interface related to that access point (private ip)', 58 | router: 'ip of router/gateway' 59 | } 60 | } 61 | 62 | */ 63 | var SYSINFO = { 64 | cpu: {}, 65 | mem: {}, 66 | fs: {}, 67 | interfaces: {}, 68 | swap: {} 69 | } 70 | export default SYSINFO; 71 | 72 | import { 73 | Log, 74 | ScanLocal, 75 | ScanTarget, 76 | UpdateInterfaceState 77 | } from './functions/fn'; 78 | 79 | import IFACES_STATE from './functions/fn'; 80 | 81 | import { 82 | ScanWifi, 83 | CheckIfaceState, 84 | DisconnectWifi, 85 | CheckAllIfaces, 86 | ConnectToWifi, 87 | } from './functions/wifi'; 88 | 89 | import bluetooth from './functions/bluetooth'; 90 | import wifi from './functions/wifi'; 91 | 92 | 93 | //export default INTERFACE_STATE 94 | 95 | //HTTP SERVER INIT 96 | var server = https.createServer(options, app).listen(port, () => { 97 | Log.i("HTTPS server listening on port " + port); 98 | }); 99 | 100 | //STATIC WEB 101 | app.use(express.static(__dirname + '/web')); 102 | 103 | //SOCKET.IO INIT 104 | const io = IO(server); 105 | 106 | //HTTP GET RULES 107 | app.get("/", (req, res) => { 108 | Log.d(req.connection.remoteAddress + " GET " + req.params[0]); 109 | res.sendFile(__dirname + '/web/index.html') 110 | }) 111 | 112 | 113 | app.get(/^(.+)$/, (req, res) => { 114 | Log.d(req.connection.remoteAddress + " GET " + req.params[0]); 115 | res.sendFile(__dirname + "/web" + req.params[0]); 116 | }); 117 | 118 | 119 | io.on('connection', (socket) => { 120 | 121 | socket.on('get system info', (callback) => { 122 | callback(SYSINFO) 123 | UpdateInterfaceState() 124 | }) 125 | 126 | socket.on('get interface state', (callback) => { 127 | callback(IFACES_STATE) 128 | }) 129 | 130 | socket.on('scan local', (iface, cb) => { 131 | ScanLocal(iface, cb) 132 | }) 133 | 134 | socket.on('scan target', (iface, target, cb) => { 135 | ScanTarget(iface, target, cb) 136 | }) 137 | 138 | socket.on('scan wifi', (iface) => { 139 | ScanWifi(iface, function(state, data) { 140 | socket.emit('new wifi', state, data) 141 | }) 142 | }) 143 | 144 | socket.on('list wireless', (cb) => { 145 | CheckAllIfaces(cb) 146 | }) 147 | 148 | socket.on('check wireless', (iface, cb) => { 149 | CheckIfaceState(iface, cb) 150 | }) 151 | 152 | socket.on('connect wifi', (iface, options, cb) => { 153 | ConnectToWifi(iface, options, cb) 154 | }) 155 | 156 | socket.on('disconnect wifi', (iface, cb) => { 157 | DisconnectWifi(iface, cb) 158 | }) 159 | 160 | 161 | socket.on('scan bluetooth', (iface) => { 162 | //bluetooth scanning here 163 | }) 164 | 165 | socket.on('stop bluetooth', (iface) => { 166 | //stop bluetooth here 167 | }) 168 | 169 | socket.on('dos bluetooth', (iface, options) => { 170 | //options 171 | /* 172 | { 173 | type: "dos", 174 | target_mac: "XX:XX:XX:XX", 175 | other: "blah blah" 176 | } 177 | */ 178 | //run funtion here 179 | }) 180 | 181 | //evades captive portal 182 | socket.on('evade portal', (iface) => { 183 | 184 | }) 185 | 186 | //tests internet connectivity 187 | socket.on('test upstream', (iface) => { 188 | 189 | }) 190 | }) 191 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HackPi", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "main.js", 6 | "dependencies": { 7 | "auth": "0.0.9", 8 | "bluetooth": "^3.0.0", 9 | "bluetooth-scanner": "^1.0.1", 10 | "colors": "^1.1.2", 11 | "express": "^4.14.1", 12 | "fs": "0.0.2", 13 | "https": "^1.0.0", 14 | "ip": "^1.1.5", 15 | "mysql": "^2.13.0", 16 | "node-http-server": "^6.2.1", 17 | "node-nmap": "^3.0.3", 18 | "os": "^0.1.1", 19 | "pcap2": "^3.0.4", 20 | "pretty-bytes": "^4.0.2", 21 | "socket.io": "^1.7.2", 22 | "systeminformation": "^3.16.0", 23 | "underscore": "^1.8.3", 24 | "wifi": "0.0.2", 25 | "wifi-control": "^2.0.0", 26 | "wireless-tools": "^0.19.0", 27 | "xml2js": "^0.4.17" 28 | }, 29 | "devDependencies": { 30 | "babel-cli": "^6.24.1", 31 | "babel-core": "^6.24.1", 32 | "babel-preset-env": "^1.3.3", 33 | "babel-preset-es2015": "^6.24.1", 34 | "babel-preset-stage-2": "^6.24.1", 35 | "nodemon": "^1.11.0" 36 | }, 37 | "scripts": { 38 | "start": "babel-node functions/phishing.js --presets es2015,stage-2", 39 | "dev": "nodemon main.js --exec babel-node --presets es2015,stage-2" 40 | }, 41 | "author": "Infirmos", 42 | "license": "ISC" 43 | } 44 | -------------------------------------------------------------------------------- /server/parse.sed: -------------------------------------------------------------------------------- 1 | s/^([^ ]+) */\1\n/ # interface name 2 | s/Link encap:(.*)( |$).*/\1/ # link encapsulation 3 | N # append next line to PS 4 | /inet addr/! s/\n[^\n]*$/\n0.0.0.0\n/ # use 0.0.0.0 if no "inet addr" 5 | s/ *inet addr:([^ ]+).*/\1\n/ # capture ip address if present 6 | s/\n[^\n]*$// # cleanup the last line 7 | s/([^\n]+)\n([^\n]+)\n([^\n]+)/IFACE \1 \3 \2/p # print entry 8 | s/.*// # empty PS 9 | : loop # \ 10 | N # \ 11 | /^\n$/b # skip until next empty line 12 | s/.*// # / 13 | b loop # / 14 | -------------------------------------------------------------------------------- /server/scripts/genCerts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Remember the passphrase you set here!" 4 | echo "This script assumes you are inside the directory scripts/ !!" 5 | echo "WARNING: If you arent in the scripts/ directory, it wont work!" 6 | sleep 5 7 | cd ../ 8 | mkdir ssl 9 | cd ssl/ 10 | openssl req -new > new.ssl.csr 11 | sudo openssl rsa -in privkey.pem -out server.key 12 | sudo openssl x509 -in new.ssl.csr -out server.cert -req -signkey server.key -days 365 13 | -------------------------------------------------------------------------------- /server/scripts/genConfig.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "This script assumes you are inside the directory scripts/ !!" 4 | echo "WARNING: If you arent in the scripts/ directory, it wont work!" 5 | sleep 4 6 | cd ../ 7 | mkdir config 8 | cd config/ 9 | touch config.json 10 | echo '{ "test": "hello" }' > config.json 11 | sleep 2 12 | echo "Config created but you need to edit it yourself, sorry :/" -------------------------------------------------------------------------------- /server/scripts/getTools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Starting to get tools, this may take a while...." 4 | sleep 2 5 | sudo apt update 6 | sudo apt install macchanger crunch hostapd libpcap-dev libnl-3-dev -y 7 | sudo npm install -g tty.js 8 | cd ../ 9 | mkdir tools 10 | cd tools/ 11 | 12 | -------------------------------------------------------------------------------- /server/scripts/onBoot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sleep 2 4 | ifconfig wlan0 up 5 | ifconfig wlan0 192.168.69.1 6 | tty.js --config /home/pi/HackPi/config/tty-config.json --daemonize 7 | service dhcpd start 8 | sleep 2 9 | service hostapd start -------------------------------------------------------------------------------- /server/sniff.js: -------------------------------------------------------------------------------- 1 | var pcap = require('pcap2') 2 | var interface = 'eth0' 3 | var ARP_PACKETS = new pcap.Session(interface, { filter: 'arp' } ) 4 | var TCP_PACKETS = new pcap.Session(interface, { filter: 'tcp' } ) 5 | var UDP_PACKETS = new pcap.Session(interface, { filter: 'udp' } ) 6 | 7 | TCP_PACKETS.on('packet', function(rawPacket){console.log("TCP")}) 8 | 9 | ARP_PACKETS.on('packet', function(rawPacket){ 10 | //console.log(pcap.decode.packet(rawPacket).payload.payload); 11 | console.log("ARP") 12 | }) 13 | 14 | UDP_PACKETS.on('packet', function(rawPacket){console.log("UDP")}) 15 | Contact GitHub API Training Shop Blog About 16 | -------------------------------------------------------------------------------- /server/ssl/new.ssl.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx 3 | ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN 4 | AQEBBQADggEPADCCAQoCggEBAMkhv787fmc2bUXVPicTvOEc0QPyHZRwH8yUYSOd 5 | z6LN+gxbX9jGte0vvJl+OPHS6YNAhF9BJ5dOiLLeEU8HzNi2Ul1hutFw2BLoMBwg 6 | MeruxUkWRdFk/kyc90Y0u4DOAWC3ouWJp+yantb7doNmy8LUEps4PKhU2Wue0XJt 7 | VWykDMhQ0/2hJjWicdI6WJFmFs9cBwLr7XRe3eajBUS4huD7uCDyw0cmMCYkz7CX 8 | yjKZcX3Do7UEieniuGTr7NVHf1QyGwLJyMTbWg6j9AdzyexslaUCcq5AEjG5JGd/ 9 | qfe/xEy72sgfdEQJkqdrIlBDu4YYxHSBOfBniMpU8cKYHo0CAwEAAaAAMA0GCSqG 10 | SIb3DQEBCwUAA4IBAQCd2VG8abPbo6+wPnQKN3O6HZ4oa7wfWUoo3xLFWYT3jMTK 11 | XIOV0BGPVvxXWVoKV367v+zLbv015+igmWAuulaKqTzL4cepAHhVpjJRR6EUKtEX 12 | 0HcedgMbKC5nXm4rC0DsfdqIxCb8WMx1Cwt/6MPwmcW5nVxSBrYrFa3OXLRSwfX4 13 | 0uEFRCzs4bb2hEzNqf/PUTFRHPsV0AFCnK+BHRPycNXdELqUnVP/hHwnONkE1U/j 14 | cVAsV5Wu+N3d/DpwworT7Klg1UPQPXlPXI+g1/FDqpW0QwDu5EiTGqCjXf9S3oHr 15 | nRcwlldTKJaHRiCgXsfJERSfWe8XWe35hBfPXSWb 16 | -----END CERTIFICATE REQUEST----- 17 | -------------------------------------------------------------------------------- /server/ssl/privkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIyTdY5sLICasCAggA 3 | MBQGCCqGSIb3DQMHBAjKLzZl8gjb9ASCBMjtiikLsqynNB2WgQnlb06r9eywk+ip 4 | y+FneRwjZxQVUVtRsJXlO0wg7swm3SwMGx+yrkRaG+60QvqlPLhKhW2j/oa0osP3 5 | piLLd2aqtMKSWlYBEDbBZjmPqOcOxEbRkoe7IG/ekqEPpdxTfr91fdLnEq+0wWr9 6 | n13EVcLwVX26wKHrkWPws8XWHNE9ojMIBB/1zs8BK+/R1NPCQTE+t0W19O7xkX7o 7 | LoK2ltljdXEGsklfFImKMMzVZwtLo2Zyb3GJHm2gmlimJu0JecBWjLhkRGPXw939 8 | dTpqdUQD4g5nKPFwdjekvWO1p7dnyPDA/eJu8GCrRIzuB1ovZUdY0fM6t9rry3ps 9 | peNBQLrhi+vsvIPtrKCM9Cw++m/92VEWf4Sp2UrdCMYCqCYyazvF988b7bbo3KAz 10 | 8UdIgCULs40Q53fXkiz98O/ssy2PL3uV0UuWLir6Nynh42fSs4qu2Rq3kQT0e7SO 11 | v13EjvJU8N0+d43KtKQEH+wJmnwVxNaGxNLO2XtiquhFIRGbJobrKOdCZl7eVVjC 12 | 2HJubE6V45BnEcNW59Ql/rPYaQLFuQQWmul3O/lqKJQPqH6BU8MMS+1Kb74vlLPE 13 | rKcmJOedlpqwmMtNqpb7rNAlA53pbjL9K6AYJq0snjLwjxYI2LrTrCK/A28DBNqi 14 | YVNMPAXnoMb6xJX+TG5cmg24tskMMWfjXl14vHUg7vGRZXwuUdKN3JLW0smlABPa 15 | Wz1GdLhiHmO2+LRPpgTMgrDLZ1gilKyd8pLYYB5yiNmU0/H2wvbyx2KVatEfFUPh 16 | bsOrjxKS+5Z63XZ4LdkC6mfs33u6JGuPc4hn1Gdks4qiThT8YeDh19udwEQxCSfE 17 | swM/gc5laT2xmozFiOoTx+oSwB9mjdYWMH7YIdfBKytMus5K43ag8PPLzJA1P2WD 18 | /QH+sby2KpiY7WL62ulHzRnAO4zh9qIF73w6QWxSuv91Iysx0T8EXbZd6GZfU+go 19 | OgVGK7LfUoK1mbLgK7gfM2jcFRR1j9EFDrkLtlzQY6kjCCVozaMQu0Qc+qQmge6M 20 | y6L9Jvr4Zy76SfqnF91S+7vKzIfH8njJHGMFTREawirN9Nm4dZB+hHlz/xR7q0qw 21 | 7aTdQbgSVTsrDfhrkoE+kbw6E22VdrWzwNldT4e3BXeEidYgv8ek9yWG+bRI17Bf 22 | 7/Xvsjn7tV1B9DdUefbQeKXN+RrylZZRRYW6JjW6r6ytL5FGVgQG6Kl5JUmMbZyx 23 | A/2mMcyjWosL1gmR3tbHTomlpgCnO87JGSZUxrAF/0j1SY3IkGBqzYat2ZCw150H 24 | XEH00hk8turnUdF2GMQW/WgSQmZIjDB3yIrM6aLYmolFF1IfSSvvZEqlxe54J3vc 25 | +PpECySP6CRi4e55eH0/AuILqOOcVUstXHC6xPURAjMxXec+ex7uYZ3Dp/LWU198 26 | HoVp0m/Up6JMmiaVuBCM/ASyd1nPLNT3cJINuBNRz6t66qkOmo+YMVlXK68ejs66 27 | eDqLf8lVbv/OyNjdMXDDtOX4ghbn55YC0gNRkCutrEnKwawgi1vg6KUiluuRpeq5 28 | yrd258cx1laPDyXwZJTYPu3uwqTWTgHcmdqhmeupjqq5Qi03/SfG/NPwZfD9/hzC 29 | pmc= 30 | -----END ENCRYPTED PRIVATE KEY----- 31 | -------------------------------------------------------------------------------- /server/ssl/server.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDBjCCAe4CCQDxhUDWiAId1TANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMB4XDTE3MDQwOTAzMDAxMVoXDTE4MDQwOTAzMDAxMVowRTELMAkG 5 | A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 6 | IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 7 | AMkhv787fmc2bUXVPicTvOEc0QPyHZRwH8yUYSOdz6LN+gxbX9jGte0vvJl+OPHS 8 | 6YNAhF9BJ5dOiLLeEU8HzNi2Ul1hutFw2BLoMBwgMeruxUkWRdFk/kyc90Y0u4DO 9 | AWC3ouWJp+yantb7doNmy8LUEps4PKhU2Wue0XJtVWykDMhQ0/2hJjWicdI6WJFm 10 | Fs9cBwLr7XRe3eajBUS4huD7uCDyw0cmMCYkz7CXyjKZcX3Do7UEieniuGTr7NVH 11 | f1QyGwLJyMTbWg6j9AdzyexslaUCcq5AEjG5JGd/qfe/xEy72sgfdEQJkqdrIlBD 12 | u4YYxHSBOfBniMpU8cKYHo0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAal0JTe0n 13 | NKmSRzmG9/3wWkqcDsBGq6abx2ty8BCdMdBkS8w11v3dM0YUxyQjVGjBKqngoF5C 14 | qIFdUU2hvrjudaf+iES5UcacW4dZJQPX2oxDFWacisxWmY7I2YQXKKWO8a7hjqGS 15 | 6FjiFI8dPq8wmil4ZDLTkXuvVJvK34VPSS7Y+qDtz/JVwsoo+1PBcagHp0nfBZvC 16 | LFp0JdO+1nqKNBet6KiK+8+9x6f0xFiU1XuoAkkVoNJUIcfw379kJNAoALR1dDcU 17 | 4VR252WzzM1aRtHq5vv8z+4pwXTufrLIza6pUa8DIgTt2krMaAc8Y+A8bKOokAXO 18 | ph0IuJXg8UY1pQ== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /server/ssl/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEAySG/vzt+ZzZtRdU+JxO84RzRA/IdlHAfzJRhI53Pos36DFtf 3 | 2Ma17S+8mX448dLpg0CEX0Enl06Ist4RTwfM2LZSXWG60XDYEugwHCAx6u7FSRZF 4 | 0WT+TJz3RjS7gM4BYLei5Ymn7Jqe1vt2g2bLwtQSmzg8qFTZa57Rcm1VbKQMyFDT 5 | /aEmNaJx0jpYkWYWz1wHAuvtdF7d5qMFRLiG4Pu4IPLDRyYwJiTPsJfKMplxfcOj 6 | tQSJ6eK4ZOvs1Ud/VDIbAsnIxNtaDqP0B3PJ7GyVpQJyrkASMbkkZ3+p97/ETLva 7 | yB90RAmSp2siUEO7hhjEdIE58GeIylTxwpgejQIDAQABAoIBAEFbZiOOAZUoanm2 8 | wWuRTl8YLhNKKbKCfNLNpIMeVMpihE5fotWePJ/GU1LNYVOzZY3w+RK66VKRgnod 9 | DyLPNhF1rW4Kw9orAQujx35cN9xPmmwVgLp6Rug+WVvG5ucECg6TnatY/+gylkrl 10 | i61HSg8VOraVn6BTchM2mHjGbmvOjxI11S8IdOnW/dRbWzZXsDOMA5fIbyhXIkp5 11 | k/VRPU2xgDJMTzsvk4cu7A1IdImOHI9ZzFjcopcP+NOUxyNNoQy9mC5j3B71DDLa 12 | yAvWInY8ss8AxwIDqi5PnL30ufenLBnF29exg9Y4cs1xZghbHSm4oi8KHlkXKZTh 13 | FOPYkUECgYEA93Q6P6snMiL16wu63OQZ1sETs8afA5ClFZK0LXYeSGwYX+QSFF0r 14 | pLlEXicTBAvBnZDI7mX798VJJYef+2muKnKMi+8XEq8sKRMcibPRy++vHUY0l00h 15 | 2ZlKgIYe73mVMM3244oTOdawwbY927MpEW0QbfWVJrE4u+E0LmCVodMCgYEA0BP7 16 | Lb+PQV1ZiYYlqsdrtvoh9t5LrRoU0oCaz4zCy6T8kO5yQ4AD/A2kAswDT0N4Kb0C 17 | 1o0M22D2eT2vowrL3R+Ya7w7h1Aj/3UAdNNdu6y8+g6OgYZNlOSsDhRUUt3vrRCJ 18 | d14zIkrFYL0yCt9BEL9Vg5pHRi1r7mzAF8Jmoh8CgYA36XMf37RDh9K5ATV/o6qS 19 | 851YCZD0ZUJn1XYQr5e4FXSMdiP/pe2uko34GCwbxexBhe1gsHp2SYV1jWeAjyhj 20 | Pu6yz5sPBbWcskzIcHD++3E91Bcd+LelSxWiZKuowHgNRvx5/UDK2M+ndV4Uvi6R 21 | WWtU7SB+VZzUFtaLhBdLMQKBgAREZKJLi2SLxYpMdflKnari9k9Zv7ONFWA7wvD+ 22 | sf/7IjLWsQExXuOMZBCqnmbBu3Ufqy87NUhKdMOHwFJXplaijz2mXpIn0pUqkRfU 23 | PdfbcwStx75gQrcK+XxQbmpEouWpsSgBhortfZ6+Qoh2i58MTXSldVC7HbuF/2p9 24 | Uh2BAoGAH+fGSOUHXQPqzQ6rt/T2K0yANIFhpkaRvQKyblzT0dkDSp34uh5Eb4v+ 25 | pvxXdWBjj3OzgX19z1EjqEu8yjdcQDROa9rDWoiJ0C+vpZys8RaJgvid1E2V6nwa 26 | FUYSQbGRp13tmTmp32JFXMZrFhTIeSjmjQVSp/rXN+/0WXs938c= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /server/web/css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} 6 | /*# sourceMappingURL=bootstrap-theme.min.css.map */ -------------------------------------------------------------------------------- /server/web/css/vis.min.css: -------------------------------------------------------------------------------- 1 | .vis .overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}.vis-active{box-shadow:0 0 10px #86d5f8}.vis [class*=span]{min-height:0;width:auto}div.vis-configuration{position:relative;display:block;float:left;font-size:12px}div.vis-configuration-wrapper{display:block;width:700px}div.vis-configuration-wrapper::after{clear:both;content:"";display:block}div.vis-configuration.vis-config-option-container{display:block;width:495px;background-color:#fff;border:2px solid #f7f8fa;border-radius:4px;margin-top:20px;left:10px;padding-left:5px}div.vis-configuration.vis-config-button{display:block;width:495px;height:25px;vertical-align:middle;line-height:25px;background-color:#f7f8fa;border:2px solid #ceced0;border-radius:4px;margin-top:20px;left:10px;padding-left:5px;cursor:pointer;margin-bottom:30px}div.vis-configuration.vis-config-button.hover{background-color:#4588e6;border:2px solid #214373;color:#fff}div.vis-configuration.vis-config-item{display:block;float:left;width:495px;height:25px;vertical-align:middle;line-height:25px}div.vis-configuration.vis-config-item.vis-config-s2{left:10px;background-color:#f7f8fa;padding-left:5px;border-radius:3px}div.vis-configuration.vis-config-item.vis-config-s3{left:20px;background-color:#e4e9f0;padding-left:5px;border-radius:3px}div.vis-configuration.vis-config-item.vis-config-s4{left:30px;background-color:#cfd8e6;padding-left:5px;border-radius:3px}div.vis-configuration.vis-config-header{font-size:18px;font-weight:700}div.vis-configuration.vis-config-label{width:120px;height:25px;line-height:25px}div.vis-configuration.vis-config-label.vis-config-s3{width:110px}div.vis-configuration.vis-config-label.vis-config-s4{width:100px}div.vis-configuration.vis-config-colorBlock{top:1px;width:30px;height:19px;border:1px solid #444;border-radius:2px;padding:0;margin:0;cursor:pointer}input.vis-configuration.vis-config-checkbox{left:-5px}input.vis-configuration.vis-config-rangeinput{position:relative;top:-5px;width:60px;padding:1px;margin:0;pointer-events:none}input.vis-configuration.vis-config-range{-webkit-appearance:none;border:0 solid #fff;background-color:rgba(0,0,0,0);width:300px;height:20px}input.vis-configuration.vis-config-range::-webkit-slider-runnable-track{width:300px;height:5px;background:#dedede;background:-moz-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#dedede),color-stop(99%,#c8c8c8));background:-webkit-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-o-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-ms-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:linear-gradient(to bottom,#dedede 0,#c8c8c8 99%);border:1px solid #999;box-shadow:#aaa 0 0 3px 0;border-radius:3px}input.vis-configuration.vis-config-range::-webkit-slider-thumb{-webkit-appearance:none;border:1px solid #14334b;height:17px;width:17px;border-radius:50%;background:#3876c2;background:-moz-linear-gradient(top,#3876c2 0,#385380 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#3876c2),color-stop(100%,#385380));background:-webkit-linear-gradient(top,#3876c2 0,#385380 100%);background:-o-linear-gradient(top,#3876c2 0,#385380 100%);background:-ms-linear-gradient(top,#3876c2 0,#385380 100%);background:linear-gradient(to bottom,#3876c2 0,#385380 100%);box-shadow:#111927 0 0 1px 0;margin-top:-7px}input.vis-configuration.vis-config-range:focus{outline:0}input.vis-configuration.vis-config-range:focus::-webkit-slider-runnable-track{background:#9d9d9d;background:-moz-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#9d9d9d),color-stop(99%,#c8c8c8));background:-webkit-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:-o-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:-ms-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:linear-gradient(to bottom,#9d9d9d 0,#c8c8c8 99%)}input.vis-configuration.vis-config-range::-moz-range-track{width:300px;height:10px;background:#dedede;background:-moz-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#dedede),color-stop(99%,#c8c8c8));background:-webkit-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-o-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-ms-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:linear-gradient(to bottom,#dedede 0,#c8c8c8 99%);border:1px solid #999;box-shadow:#aaa 0 0 3px 0;border-radius:3px}input.vis-configuration.vis-config-range::-moz-range-thumb{border:none;height:16px;width:16px;border-radius:50%;background:#385380}input.vis-configuration.vis-config-range:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}input.vis-configuration.vis-config-range::-ms-track{width:300px;height:5px;background:0 0;border-color:transparent;border-width:6px 0;color:transparent}input.vis-configuration.vis-config-range::-ms-fill-lower{background:#777;border-radius:10px}input.vis-configuration.vis-config-range::-ms-fill-upper{background:#ddd;border-radius:10px}input.vis-configuration.vis-config-range::-ms-thumb{border:none;height:16px;width:16px;border-radius:50%;background:#385380}input.vis-configuration.vis-config-range:focus::-ms-fill-lower{background:#888}input.vis-configuration.vis-config-range:focus::-ms-fill-upper{background:#ccc}.vis-configuration-popup{position:absolute;background:rgba(57,76,89,.85);border:2px solid #f2faff;line-height:30px;height:30px;width:150px;text-align:center;color:#fff;font-size:14px;border-radius:4px;-webkit-transition:opacity .3s ease-in-out;-moz-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out}.vis-configuration-popup:after,.vis-configuration-popup:before{left:100%;top:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}.vis-configuration-popup:after{border-color:rgba(136,183,213,0);border-left-color:rgba(57,76,89,.85);border-width:8px;margin-top:-8px}.vis-configuration-popup:before{border-color:rgba(194,225,245,0);border-left-color:#f2faff;border-width:12px;margin-top:-12px}div.vis-tooltip{position:absolute;visibility:hidden;padding:5px;white-space:nowrap;font-family:verdana;font-size:14px;color:#000;background-color:#f5f4ed;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;border:1px solid #808074;box-shadow:3px 3px 10px rgba(0,0,0,.2);pointer-events:none;z-index:5}div.vis-color-picker{position:absolute;top:0;left:30px;margin-top:-140px;margin-left:30px;width:310px;height:444px;z-index:1;padding:10px;border-radius:15px;background-color:#fff;display:none;box-shadow:rgba(0,0,0,.5) 0 0 10px 0}div.vis-color-picker div.vis-arrow{position:absolute;top:147px;left:5px}div.vis-color-picker div.vis-arrow::after,div.vis-color-picker div.vis-arrow::before{right:100%;top:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}div.vis-color-picker div.vis-arrow:after{border-color:rgba(255,255,255,0);border-right-color:#fff;border-width:30px;margin-top:-30px}div.vis-color-picker div.vis-color{position:absolute;width:289px;height:289px;cursor:pointer}div.vis-color-picker div.vis-brightness{position:absolute;top:313px}div.vis-color-picker div.vis-opacity{position:absolute;top:350px}div.vis-color-picker div.vis-selector{position:absolute;top:137px;left:137px;width:15px;height:15px;border-radius:15px;border:1px solid #fff;background:#4c4c4c;background:-moz-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#4c4c4c),color-stop(12%,#595959),color-stop(25%,#666),color-stop(39%,#474747),color-stop(50%,#2c2c2c),color-stop(51%,#000),color-stop(60%,#111),color-stop(76%,#2b2b2b),color-stop(91%,#1c1c1c),color-stop(100%,#131313));background:-webkit-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:-o-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:-ms-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:linear-gradient(to bottom,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%)}div.vis-color-picker div.vis-new-color{position:absolute;width:140px;height:20px;border:1px solid rgba(0,0,0,.1);border-radius:5px;top:380px;left:159px;text-align:right;padding-right:2px;font-size:10px;color:rgba(0,0,0,.4);vertical-align:middle;line-height:20px}div.vis-color-picker div.vis-initial-color{position:absolute;width:140px;height:20px;border:1px solid rgba(0,0,0,.1);border-radius:5px;top:380px;left:10px;text-align:left;padding-left:2px;font-size:10px;color:rgba(0,0,0,.4);vertical-align:middle;line-height:20px}div.vis-color-picker div.vis-label{position:absolute;width:300px;left:10px}div.vis-color-picker div.vis-label.vis-brightness{top:300px}div.vis-color-picker div.vis-label.vis-opacity{top:338px}div.vis-color-picker div.vis-button{position:absolute;width:68px;height:25px;border-radius:10px;vertical-align:middle;text-align:center;line-height:25px;top:410px;border:2px solid #d9d9d9;background-color:#f7f7f7;cursor:pointer}div.vis-color-picker div.vis-button.vis-cancel{left:5px}div.vis-color-picker div.vis-button.vis-load{left:82px}div.vis-color-picker div.vis-button.vis-apply{left:159px}div.vis-color-picker div.vis-button.vis-save{left:236px}div.vis-color-picker input.vis-range{width:290px;height:20px}div.vis-network div.vis-manipulation{box-sizing:content-box;border-width:0;border-bottom:1px;border-style:solid;border-color:#d6d9d8;background:#fff;background:-moz-linear-gradient(top,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(48%,#fcfcfc),color-stop(50%,#fafafa),color-stop(100%,#fcfcfc));background:-webkit-linear-gradient(top,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);background:-o-linear-gradient(top,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);background:-ms-linear-gradient(top,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);background:linear-gradient(to bottom,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);padding-top:4px;position:absolute;left:0;top:0;width:100%;height:28px}div.vis-network div.vis-edit-mode{position:absolute;left:0;top:5px;height:30px}div.vis-network div.vis-close{position:absolute;right:0;top:0;width:30px;height:30px;background-position:20px 3px;background-repeat:no-repeat;background-image:url(img/network/cross.png);cursor:pointer;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}div.vis-network div.vis-close:hover{opacity:.6}div.vis-network div.vis-edit-mode div.vis-button,div.vis-network div.vis-manipulation div.vis-button{float:left;font-family:verdana;font-size:12px;-moz-border-radius:15px;border-radius:15px;display:inline-block;background-position:0 0;background-repeat:no-repeat;height:24px;margin-left:10px;cursor:pointer;padding:0 8px 0 8px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}div.vis-network div.vis-manipulation div.vis-button:hover{box-shadow:1px 1px 8px rgba(0,0,0,.2)}div.vis-network div.vis-manipulation div.vis-button:active{box-shadow:1px 1px 8px rgba(0,0,0,.5)}div.vis-network div.vis-manipulation div.vis-button.vis-back{background-image:url(img/network/backIcon.png)}div.vis-network div.vis-manipulation div.vis-button.vis-none:hover{box-shadow:1px 1px 8px transparent;cursor:default}div.vis-network div.vis-manipulation div.vis-button.vis-none:active{box-shadow:1px 1px 8px transparent}div.vis-network div.vis-manipulation div.vis-button.vis-none{padding:0}div.vis-network div.vis-manipulation div.notification{margin:2px;font-weight:700}div.vis-network div.vis-manipulation div.vis-button.vis-add{background-image:url(img/network/addNodeIcon.png)}div.vis-network div.vis-edit-mode div.vis-button.vis-edit,div.vis-network div.vis-manipulation div.vis-button.vis-edit{background-image:url(img/network/editIcon.png)}div.vis-network div.vis-edit-mode div.vis-button.vis-edit.vis-edit-mode{background-color:#fcfcfc;border:1px solid #ccc}div.vis-network div.vis-manipulation div.vis-button.vis-connect{background-image:url(img/network/connectIcon.png)}div.vis-network div.vis-manipulation div.vis-button.vis-delete{background-image:url(img/network/deleteIcon.png)}div.vis-network div.vis-edit-mode div.vis-label,div.vis-network div.vis-manipulation div.vis-label{margin:0 0 0 23px;line-height:25px}div.vis-network div.vis-manipulation div.vis-separator-line{float:left;display:inline-block;width:1px;height:21px;background-color:#bdbdbd;margin:0 7px 0 15px}div.vis-network div.vis-navigation div.vis-button{width:34px;height:34px;-moz-border-radius:17px;border-radius:17px;position:absolute;display:inline-block;background-position:2px 2px;background-repeat:no-repeat;cursor:pointer;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}div.vis-network div.vis-navigation div.vis-button:hover{box-shadow:0 0 3px 3px rgba(56,207,21,.3)}div.vis-network div.vis-navigation div.vis-button:active{box-shadow:0 0 1px 3px rgba(56,207,21,.95)}div.vis-network div.vis-navigation div.vis-button.vis-up{background-image:url(img/network/upArrow.png);bottom:50px;left:55px}div.vis-network div.vis-navigation div.vis-button.vis-down{background-image:url(img/network/downArrow.png);bottom:10px;left:55px}div.vis-network div.vis-navigation div.vis-button.vis-left{background-image:url(img/network/leftArrow.png);bottom:10px;left:15px}div.vis-network div.vis-navigation div.vis-button.vis-right{background-image:url(img/network/rightArrow.png);bottom:10px;left:95px}div.vis-network div.vis-navigation div.vis-button.vis-zoomIn{background-image:url(img/network/plus.png);bottom:10px;right:15px}div.vis-network div.vis-navigation div.vis-button.vis-zoomOut{background-image:url(img/network/minus.png);bottom:10px;right:55px}div.vis-network div.vis-navigation div.vis-button.vis-zoomExtends{background-image:url(img/network/zoomExtends.png);bottom:50px;right:15px}.vis-current-time{background-color:#ff7f6e;width:2px;z-index:1;pointer-events:none}.vis-rolling-mode-btn{height:40px;width:40px;position:absolute;top:7px;right:20px;border-radius:50%;font-size:28px;cursor:pointer;opacity:.8;color:#fff;font-weight:700;text-align:center;background:#3876c2}.vis-rolling-mode-btn:before{content:"\26F6"}.vis-rolling-mode-btn:hover{opacity:1}.vis-custom-time{background-color:#6e94ff;width:2px;cursor:move;z-index:1}.vis-panel.vis-background.vis-horizontal .vis-grid.vis-horizontal{position:absolute;width:100%;height:0;border-bottom:1px solid}.vis-panel.vis-background.vis-horizontal .vis-grid.vis-minor{border-color:#e5e5e5}.vis-panel.vis-background.vis-horizontal .vis-grid.vis-major{border-color:#bfbfbf}.vis-data-axis .vis-y-axis.vis-major{width:100%;position:absolute;color:#4d4d4d;white-space:nowrap}.vis-data-axis .vis-y-axis.vis-major.vis-measure{padding:0;margin:0;border:0;visibility:hidden;width:auto}.vis-data-axis .vis-y-axis.vis-minor{position:absolute;width:100%;color:#bebebe;white-space:nowrap}.vis-data-axis .vis-y-axis.vis-minor.vis-measure{padding:0;margin:0;border:0;visibility:hidden;width:auto}.vis-data-axis .vis-y-axis.vis-title{position:absolute;color:#4d4d4d;white-space:nowrap;bottom:20px;text-align:center}.vis-data-axis .vis-y-axis.vis-title.vis-measure{padding:0;margin:0;visibility:hidden;width:auto}.vis-data-axis .vis-y-axis.vis-title.vis-left{bottom:0;-webkit-transform-origin:left top;-moz-transform-origin:left top;-ms-transform-origin:left top;-o-transform-origin:left top;transform-origin:left bottom;-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.vis-data-axis .vis-y-axis.vis-title.vis-right{bottom:0;-webkit-transform-origin:right bottom;-moz-transform-origin:right bottom;-ms-transform-origin:right bottom;-o-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.vis-legend{background-color:rgba(247,252,255,.65);padding:5px;border:1px solid #b3b3b3;box-shadow:2px 2px 10px rgba(154,154,154,.55)}.vis-legend-text{white-space:nowrap;display:inline-block}.vis-item{position:absolute;color:#1a1a1a;border-color:#97b0f8;border-width:1px;background-color:#d5ddf6;display:inline-block;z-index:1}.vis-item.vis-selected{border-color:#ffc200;background-color:#fff785;z-index:2}.vis-editable.vis-selected{cursor:move}.vis-item.vis-point.vis-selected{background-color:#fff785}.vis-item.vis-box{text-align:center;border-style:solid;border-radius:2px}.vis-item.vis-point{background:0 0}.vis-item.vis-dot{position:absolute;padding:0;border-width:4px;border-style:solid;border-radius:4px}.vis-item.vis-range{border-style:solid;border-radius:2px;box-sizing:border-box}.vis-item.vis-background{border:none;background-color:rgba(213,221,246,.4);box-sizing:border-box;padding:0;margin:0}.vis-item .vis-item-overflow{position:relative;width:100%;height:100%;padding:0;margin:0;overflow:hidden}.vis-item-visible-frame{white-space:nowrap}.vis-item.vis-range .vis-item-content{position:relative;display:inline-block}.vis-item.vis-background .vis-item-content{position:absolute;display:inline-block}.vis-item.vis-line{padding:0;position:absolute;width:0;border-left-width:1px;border-left-style:solid}.vis-item .vis-item-content{white-space:nowrap;box-sizing:border-box;padding:5px}.vis-item .vis-onUpdateTime-tooltip{position:absolute;background:#4f81bd;color:#fff;width:200px;text-align:center;white-space:nowrap;padding:5px;border-radius:1px;transition:.4s;-o-transition:.4s;-moz-transition:.4s;-webkit-transition:.4s}.vis-item .vis-delete,.vis-item .vis-delete-rtl{position:absolute;top:0;width:24px;height:24px;box-sizing:border-box;padding:0 5px;cursor:pointer;-webkit-transition:background .2s linear;-moz-transition:background .2s linear;-ms-transition:background .2s linear;-o-transition:background .2s linear;transition:background .2s linear}.vis-item .vis-delete{right:-24px}.vis-item .vis-delete-rtl{left:-24px}.vis-item .vis-delete-rtl:after,.vis-item .vis-delete:after{content:"\00D7";color:red;font-family:arial,sans-serif;font-size:22px;font-weight:700;-webkit-transition:color .2s linear;-moz-transition:color .2s linear;-ms-transition:color .2s linear;-o-transition:color .2s linear;transition:color .2s linear}.vis-item .vis-delete-rtl:hover,.vis-item .vis-delete:hover{background:red}.vis-item .vis-delete-rtl:hover:after,.vis-item .vis-delete:hover:after{color:#fff}.vis-item .vis-drag-center{position:absolute;width:100%;height:100%;top:0;left:0;cursor:move}.vis-item.vis-range .vis-drag-left{position:absolute;width:24px;max-width:20%;min-width:2px;height:100%;top:0;left:-4px;cursor:w-resize}.vis-item.vis-range .vis-drag-right{position:absolute;width:24px;max-width:20%;min-width:2px;height:100%;top:0;right:-4px;cursor:e-resize}.vis-range.vis-item.vis-readonly .vis-drag-left,.vis-range.vis-item.vis-readonly .vis-drag-right{cursor:auto}.vis-itemset{position:relative;padding:0;margin:0;box-sizing:border-box}.vis-itemset .vis-background,.vis-itemset .vis-foreground{position:absolute;width:100%;height:100%;overflow:visible}.vis-axis{position:absolute;width:100%;height:0;left:0;z-index:1}.vis-foreground .vis-group{position:relative;box-sizing:border-box;border-bottom:1px solid #bfbfbf}.vis-foreground .vis-group:last-child{border-bottom:none}.vis-nesting-group{cursor:pointer}.vis-nested-group{background:#f5f5f5}.vis-label.vis-nesting-group.expanded:before{content:"\25BC"}.vis-label.vis-nesting-group.collapsed-rtl:before{content:"\25C0"}.vis-label.vis-nesting-group.collapsed:before{content:"\25B6"}.vis-overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}.vis-labelset{position:relative;overflow:hidden;box-sizing:border-box}.vis-labelset .vis-label{position:relative;left:0;top:0;width:100%;color:#4d4d4d;box-sizing:border-box}.vis-labelset .vis-label{border-bottom:1px solid #bfbfbf}.vis-labelset .vis-label.draggable{cursor:pointer}.vis-labelset .vis-label:last-child{border-bottom:none}.vis-labelset .vis-label .vis-inner{display:inline-block;padding:5px}.vis-labelset .vis-label .vis-inner.vis-hidden{padding:0}.vis-panel{position:absolute;padding:0;margin:0;box-sizing:border-box}.vis-panel.vis-bottom,.vis-panel.vis-center,.vis-panel.vis-left,.vis-panel.vis-right,.vis-panel.vis-top{border:1px #bfbfbf}.vis-panel.vis-center,.vis-panel.vis-left,.vis-panel.vis-right{border-top-style:solid;border-bottom-style:solid;overflow:hidden}.vis-left.vis-panel.vis-vertical-scroll,.vis-right.vis-panel.vis-vertical-scroll{height:100%;overflow-x:hidden;overflow-y:scroll}.vis-left.vis-panel.vis-vertical-scroll{direction:rtl}.vis-left.vis-panel.vis-vertical-scroll .vis-content{direction:ltr}.vis-right.vis-panel.vis-vertical-scroll{direction:ltr}.vis-right.vis-panel.vis-vertical-scroll .vis-content{direction:rtl}.vis-panel.vis-bottom,.vis-panel.vis-center,.vis-panel.vis-top{border-left-style:solid;border-right-style:solid}.vis-background{overflow:hidden}.vis-panel>.vis-content{position:relative}.vis-panel .vis-shadow{position:absolute;width:100%;height:1px;box-shadow:0 0 10px rgba(0,0,0,.8)}.vis-panel .vis-shadow.vis-top{top:-1px;left:0}.vis-panel .vis-shadow.vis-bottom{bottom:-1px;left:0}.vis-graph-group0{fill:#4f81bd;fill-opacity:0;stroke-width:2px;stroke:#4f81bd}.vis-graph-group1{fill:#f79646;fill-opacity:0;stroke-width:2px;stroke:#f79646}.vis-graph-group2{fill:#8c51cf;fill-opacity:0;stroke-width:2px;stroke:#8c51cf}.vis-graph-group3{fill:#75c841;fill-opacity:0;stroke-width:2px;stroke:#75c841}.vis-graph-group4{fill:#ff0100;fill-opacity:0;stroke-width:2px;stroke:#ff0100}.vis-graph-group5{fill:#37d8e6;fill-opacity:0;stroke-width:2px;stroke:#37d8e6}.vis-graph-group6{fill:#042662;fill-opacity:0;stroke-width:2px;stroke:#042662}.vis-graph-group7{fill:#00ff26;fill-opacity:0;stroke-width:2px;stroke:#00ff26}.vis-graph-group8{fill:#f0f;fill-opacity:0;stroke-width:2px;stroke:#f0f}.vis-graph-group9{fill:#8f3938;fill-opacity:0;stroke-width:2px;stroke:#8f3938}.vis-timeline .vis-fill{fill-opacity:.1;stroke:none}.vis-timeline .vis-bar{fill-opacity:.5;stroke-width:1px}.vis-timeline .vis-point{stroke-width:2px;fill-opacity:1}.vis-timeline .vis-legend-background{stroke-width:1px;fill-opacity:.9;fill:#fff;stroke:#c2c2c2}.vis-timeline .vis-outline{stroke-width:1px;fill-opacity:1;fill:#fff;stroke:#e5e5e5}.vis-timeline .vis-icon-fill{fill-opacity:.3;stroke:none}.vis-time-axis{position:relative;overflow:hidden}.vis-time-axis.vis-foreground{top:0;left:0;width:100%}.vis-time-axis.vis-background{position:absolute;top:0;left:0;width:100%;height:100%}.vis-time-axis .vis-text{position:absolute;color:#4d4d4d;padding:3px;overflow:hidden;box-sizing:border-box;white-space:nowrap}.vis-time-axis .vis-text.vis-measure{position:absolute;padding-left:0;padding-right:0;margin-left:0;margin-right:0;visibility:hidden}.vis-time-axis .vis-grid.vis-vertical{position:absolute;border-left:1px solid}.vis-time-axis .vis-grid.vis-vertical-rtl{position:absolute;border-right:1px solid}.vis-time-axis .vis-grid.vis-minor{border-color:#e5e5e5}.vis-time-axis .vis-grid.vis-major{border-color:#bfbfbf}.vis-timeline{position:relative;border:1px solid #bfbfbf;overflow:hidden;padding:0;margin:0;box-sizing:border-box} -------------------------------------------------------------------------------- /server/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HackPi 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 26 | 27 | 28 | 59 | 60 | 61 |
62 |
63 |
64 |
65 | 66 |
67 |
68 | 69 |
70 |
71 | / 72 |
73 |
74 | / 75 |
76 |
77 |
78 | 79 |
80 |

List Of Interfaces

81 |
82 |
83 |
84 |
85 | 86 |
87 |

Wifi

88 |
89 |
90 |
91 | 92 | 94 |
95 | 96 |
97 |
98 |
99 |
100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
SSIDSignalSecurity
111 |
112 |
113 | 114 |
115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /server/web/js/index.js: -------------------------------------------------------------------------------- 1 | var socket = io.connect({ 2 | secure: true 3 | }) 4 | var sysdata; 5 | var firstload = true 6 | var IFACES_STATE = []; 7 | /* 8 | var options = { 9 | autoResize: true, 10 | height: '100%', 11 | width: '100%', 12 | clickToUse: true, 13 | configure: { 14 | enabled: false 15 | }, 16 | interaction: { 17 | hover: true 18 | }, 19 | edges: { 20 | smooth: { 21 | forceDirection: 'none', 22 | roundness: 1 23 | } 24 | }, 25 | physics: { 26 | forceAtlas2Based: { 27 | springLength: 60, 28 | springConstant: 0.1, 29 | damping: 1, 30 | avoidOverlap: 1 31 | }, 32 | minVelocity: 0.3, 33 | solver: "forceAtlas2Based", 34 | timestep: 0.11 35 | } 36 | } 37 | // create an array with nodes 38 | 39 | //Global vars 40 | var hosts; 41 | var nodes; 42 | var edges; 43 | var container; 44 | var network; 45 | 46 | 47 | // initialize your network! 48 | function DrawNetwork(state, data, scantime) { 49 | if (state == 'success') { 50 | console.log(data, scantime) //REMOVE THIS LATER 51 | 52 | hosts = [{ 53 | id: 1, 54 | label: 'You', 55 | title: "You" 56 | }]; 57 | 58 | for (var i = 0; i < data.length; i++) { 59 | var obj = { 60 | id: data[i].ip, 61 | label: data[i].ip, 62 | title: data[i].hostname 63 | } 64 | hosts.push(obj) 65 | } 66 | nodes = new vis.DataSet(hosts); 67 | 68 | // create an array with edges 69 | var edges_data = []; 70 | for (var i = 0; i < hosts.length; i++) { 71 | if (hosts[i].id == 1) {} else { 72 | var obj = { 73 | from: hosts[i].id, 74 | to: 1 75 | } 76 | edges_data.push(obj) 77 | } 78 | } 79 | edges = new vis.DataSet(edges_data); 80 | 81 | // create a network 82 | container = document.getElementById('mynetwork'); 83 | 84 | // provide the data in the vis format 85 | result = { 86 | nodes: nodes, 87 | edges: edges 88 | }; 89 | network = new vis.Network(container, result, options); 90 | 91 | //Zooms in on central node 92 | network.once("beforeDrawing", function() { 93 | network.focus(1, { 94 | scale: 12 95 | }); 96 | }); 97 | 98 | //Zooms out with an animation 99 | network.once("afterDrawing", function() { 100 | network.fit({ 101 | animation: { 102 | duration: 3000, 103 | easingFunction: 'easeInOutQuint' 104 | } 105 | }); 106 | }) 107 | //Stops the wiggling 108 | network.stabilize() 109 | } else { 110 | console.log("Error!", data) 111 | } 112 | } 113 | 114 | // socket.emit('scan local', 'eth0', DrawNetwork(state, data, scantime)) 115 | 116 | */ 117 | 118 | function UpdateInterfaces() { 119 | $('.interface-list').html('') 120 | for (var i = 0; i < sysdata.interfaces.length; i++) { 121 | var iface = sysdata.interfaces[i] 122 | var mac = iface.address || null 123 | var vendor = null 124 | if (mac) { 125 | vendor = iface.vendor 126 | } 127 | if (IFACES_STATE[i]) { 128 | var iface_state = IFACES_STATE[i] 129 | var isbusy; 130 | var isbusy_process; 131 | if (iface_state.state.busy == true) { 132 | isbusy = true 133 | isbusy_process = iface_state.state.process 134 | } else { 135 | isbusy = false 136 | } 137 | } 138 | if (iface.interface.indexOf('wlan') < 0) { 139 | var type = iface.link 140 | } else if (iface.interface.indexOf('mon') < 0) { 141 | var type = 'wireless' 142 | } else { 143 | var type = 'monitor-mode' 144 | } 145 | var wirelessdata = iface.wirelessdata 146 | var ifacename = iface.interface 147 | var ipv4addr = iface.ipv4_address || null 148 | var ipv6addr = iface.ipv6_address || null 149 | var isloopback = iface.loopback || false 150 | var isup = iface.up 151 | var isrunning = iface.running || false 152 | var broadcast = iface.broadcast || false 153 | var multicast = iface.multicast || false 154 | $('.interface-list').append('
' + ifacename + '

Mac: ' + mac + '

Vendor: ' + vendor + '

Type: ' + type + '

IsUP: ' + isup + '

') 155 | if (IFACES_STATE[i]) { 156 | //check if busy 157 | if (isbusy == true) { 158 | $('#' + ifacename + ' .panel-heading').append(' BUSY') 159 | } 160 | 161 | //check if connected 162 | if (isloopback !== true && ipv4addr !== null) { 163 | $('#' + ifacename + ' .panel-heading').append(' CONNECTED') 164 | $('#' + ifacename + ' .panel-body').append('

IPv4: ' + ipv4addr + '

') 165 | } else if (isloopback !== true && ipv6addr !== null) { 166 | $('#' + ifacename + ' .panel-heading').append(' CONNECTED') 167 | $('#' + ifacename + ' .panel-body').append('

IPv6: ' + ipv6addr + '

') 168 | } 169 | 170 | //if wireless 171 | if (type == 'wireless') { 172 | if (wirelessdata) { 173 | if (wirelessdata.mode == "master") { 174 | $('#' + ifacename + ' .panel-heading').append(' Master Mode') 175 | } else if (isbusy == false && isup == true) { 176 | $('#wifi-scan-interface-list').html('') 177 | $('#wifi-scan-interface-list').append('') 178 | } 179 | } 180 | } 181 | 182 | 183 | } 184 | } 185 | } 186 | 187 | socket.on('updated interfaces', function() { 188 | UpdateInterfaces() 189 | }) 190 | 191 | setInterval(function() { 192 | 193 | socket.emit('get interface state', function(data) { 194 | IFACES_STATE = data 195 | }) 196 | socket.emit('get system info', function(data) { 197 | if (sysdata) { 198 | var sysinterfaces = []; 199 | sysdata.interfaces.forEach(function(dt, index) { 200 | sysinterfaces.push(dt.interface) 201 | }) 202 | 203 | var datainterfaces = []; 204 | data.interfaces.forEach(function(dt, index) { 205 | datainterfaces.push(dt.interface) 206 | }) 207 | 208 | if (data.interfaces.length > sysdata.interfaces.length) { 209 | //new interface 210 | var diff = _.difference(datainterfaces, sysinterfaces) 211 | diff.forEach(function(data, index) { 212 | console.log(data + " was added.") //TODO: Proper alerts! 213 | }) 214 | } else if (data.interfaces.length < sysdata.interfaces.length) { 215 | //removed interface 216 | var diff = _.difference(sysinterfaces, datainterfaces) 217 | diff.forEach(function(data, index) { 218 | console.log(data + " was removed.") //TODO: Proper alerts! 219 | }) 220 | } 221 | } 222 | 223 | sysdata = data 224 | //Parsing general data 225 | var uptime = data.uptime 226 | var osuptime = data.osuptime 227 | var freemem = data.mem.free 228 | var usedmem = data.mem.used 229 | var totalmem = data.mem.total 230 | var swapfree = data.swap.swapfree 231 | var swapused = data.swap.swapused 232 | var swaptotal = data.swap.swaptotal 233 | var cpuload = data.cpu.load.avgload 234 | var cpuspeed = data.cpu.speed.avg 235 | var cputemp = data.cpu.temp.main 236 | $('.uptime').text(uptime) 237 | $('.osuptime').text(osuptime) 238 | $('.freemem').text(freemem) 239 | $('.usedmem').text(usedmem) 240 | $('.totalmem').text(totalmem) 241 | $('.swapused').text(swapused) 242 | $('.swaptotal').text(swaptotal) 243 | $('.cpuload').text(cpuload) 244 | $('.cpuspeed').text(cpuspeed) 245 | $('.cputemp').text(cputemp) 246 | 247 | //Parsing fs data 248 | for (var i = 0; i < data.fs.fssize.length; i++) { 249 | var fs = data.fs.fssize[i] 250 | var disk = fs.fs 251 | var mountpoint = fs.mount 252 | var fstype = fs.type 253 | var fssize = fs.size 254 | var fsused = fs.used 255 | var fsusedpercent = fs.use 256 | //$('.fs').append(`
${fs} ${disk} ${mountpoint} ${fstype}
`) 257 | } 258 | }) 259 | }, 600) 260 | 261 | 262 | setInterval(function() { 263 | UpdateInterfaces() 264 | }, 2000) 265 | 266 | 267 | $('.scan-wifi').click(function() { 268 | var iface = $('#wifi-scan-interface-list').val() 269 | socket.emit('scan wifi', iface) 270 | }) 271 | 272 | socket.on('new wifi', function(type, data) { 273 | console.log(type, data) 274 | }) 275 | -------------------------------------------------------------------------------- /server/web/js/underscore-min.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.8.3 2 | // http://underscorejs.org 3 | // (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 4 | // Underscore may be freely distributed under the MIT license. 5 | (function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this); 6 | //# sourceMappingURL=underscore-min.map -------------------------------------------------------------------------------- /ssl/new.ssl.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx 3 | ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN 4 | AQEBBQADggEPADCCAQoCggEBAMF3QeIkXMq3qkXLrN321y5ICI1f+ojnPNgo2EIW 5 | lDcLt6LX5AO//ZmhHTm2pVj7FfTlnxSzRtb/gFniH6PR89UaxmxtTUOJAMM5omcn 6 | 67++jYiM51XXfOP2KUE/WcDY4BOXjZa99RsMVhWSZ9lg87QZ5JUlzkMQBLMvODwr 7 | bomYysolPR77gLbzdFe7QC0c1Jah7Zxrc47mPTA93eseWK6o4JFpa32bqCiSrZWN 8 | ViLNlNEKcRVW90mHVAjKMaWsf3PE9S4jygkoaUBNf9i45oEUxLzv9PaJIQRR73dI 9 | 7ODpzGBBTcnsNX7/IeqasEY4WY4H9RuR3mkhPp2BziazwlkCAwEAAaAAMA0GCSqG 10 | SIb3DQEBCwUAA4IBAQC0Tmmg5PVmMt2zC7B0FKxyNu3VTh07vLZ08FkGmnW3/QjS 11 | 44uTbGE0dR2/pj+E/2rHhOStBclXEl5j/My3kdj5WCFUz6nUEG9hTjySQ0t4dQgb 12 | S2zWZyJEcOUqLT8+rGfKj74Ua5qn91HK2YkcT1WVWsJrMGqIdXxkANG/gmyriLXO 13 | 7jYAFb0IlJriaAffENxDnYz7hudZO0AfLmTIgqjRhHy+wkvQvDu9lP84MVGmGMvp 14 | seC/HS7J19uX+2JuQo6udNpTpA3Lq+HCaSc3yQVIc6ozaIgPuhvmsvD5oywb4+lY 15 | dDKVKVOYfJ/f9Mgvk6UekACKUVYu9UXL88bk9G1t 16 | -----END CERTIFICATE REQUEST----- 17 | -------------------------------------------------------------------------------- /ssl/privkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIKDcWwQMf8hYCAggA 3 | MBQGCCqGSIb3DQMHBAiCdSHFYKYp1wSCBMj8v47xh70miCTGn8en13e5eahRyW4K 4 | E3oTXXEjy8LVH1jX+m8bRXDcY7r8bqjtICfPaWtW0NcNRcTA118bo4DIJlD7TxsO 5 | m7h74DIZyfoU+N5cCYM6rUrnWFmx0MRHKbQibB/65Z7a2eo925y0Wv/HcapVmH7z 6 | /k6bd2JEBrAcedDR1Lm3Xt2BPBbLfzUjanJ+LLTF9+A2S1aHmQeWTx5f1L25Dw9m 7 | XVxR5QGKsc8WQtBafH/Wa0C1pS+cHN70BDd57UdrCLyjbVKSGzxI8IU14fcc+6eV 8 | 7V8GnvSTXK8En67Uu6bczXdhLkHMb/OWssoi/IS24SCxxm43nLR9PaUwQ6B5UPYq 9 | L5AZGsP2SLfdsFgxjRKpmHYrJBvpuRa/OCjMECrB80nd+WV/IuUwglE0+gepHEwq 10 | gBImBJ9ZiyKXb1EWi5e9u32oIABvMs4Zb4KQ1ynn+bQ+Fduo7YIVisuBzx2oVrTe 11 | J8UNH2BxQaPbrH2uU2egGiVvs9S8sf+74ZJgAa9NZ/gZZqpboiw7Pmlyz+bVvGjj 12 | aV2lJBN/NDO3ZqZRq7j16Y5F9i4iRgiFrlKwOr3qqb2I8S3irl1yukA1CjY/lRIH 13 | t8uem6Fv9nWrNRWXVZoN/yKT6B0SO+/lKOBi2LJaAPQ8rDMWLXLSQqKuTyaM+2Q6 14 | XNHXalOnc6nut8q1frQKJoyxVphvBFO0u2HVWvgmBKHTnWOLYO8pyHxVyinzM4s7 15 | tDJUR1E4Kj4HEFV9cQ9pKDJgbE+pS0j2H1aJM8uQhNMAj0hBoQzBJDA9tfvDgLVt 16 | bhS+4T5Hf+bt4B9h5ri9iPWCloU+kOnGVOng0/bH/DXjoy9iOhd1DaYRjGQgAZIK 17 | r7TssezhLC2bxSdGtupIBe79lg7y7nELEJMZ+1KbkPCytn999wxgm0gUDlkzviDB 18 | koicwtAVmjuk0tcNZ9YM+OBtOI/tOnEsVBuQiXcEQAiSZu0SkxFrbXANjlQEkI11 19 | FWMaiAsbaQXLFX1l1MlxygtFL7j0Svllv79h+Hmug43LxIJOHqiWdEeMRHu4rIjH 20 | b/5ckDk+ITCx0LRxFk8oy9uUh0LgdqCibugDyunOKYtN5EAi5ks3jORnAFoPe1Yb 21 | LEin00PNIMEMkoV0+njj5XjwNpNIcdRR/FW5/8LqEwPWb6tgB9NR01BuKuNtQ0et 22 | fBkIAavtQaTeLEGm+WEvTeXDjSb6HK+17sHx1QJRY6BMJ+cc++FKQ17b0U+jfe2j 23 | sxLxb84nMnO6JzG0f5qspD10LKGvD3mk8BF8Fmwzq0AUXJ+cIFahKSSKBuUOTgFU 24 | 2BjiUwYsrp600+PmI+rZK8xbhbp2E0YbYoaVuNyTljxf3aYEGph3AlSL7yp0AujW 25 | qtteaLfr/YwDTgD6V13HSk9rdULKSZ27qG70hepHVOu64y9NAmjDDiT8qZThTNh0 26 | +0RmPZZdQwmeZLK34QC0JvIAcm0TuaZxaFQxevGoUq9fXehaDqNw4IURUlvjHZoM 27 | MN5IcNsNVzajCapqhkMpHx1jl6+BEDfIyr35UaFSBfv5PakrV6tkP+4yzWOfa7xF 28 | D+A8zwpahxIrV+o5Pq+w4T2CsLBwt6gO/XWK3nqAxEWo2lt/4C6lcc0eMXFbaDuc 29 | L6U= 30 | -----END ENCRYPTED PRIVATE KEY----- 31 | -------------------------------------------------------------------------------- /ssl/server.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDBjCCAe4CCQDsTywjD1jTCjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMB4XDTE3MDQwODA5MjUwMloXDTE4MDQwODA5MjUwMlowRTELMAkG 5 | A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 6 | IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 7 | AMF3QeIkXMq3qkXLrN321y5ICI1f+ojnPNgo2EIWlDcLt6LX5AO//ZmhHTm2pVj7 8 | FfTlnxSzRtb/gFniH6PR89UaxmxtTUOJAMM5omcn67++jYiM51XXfOP2KUE/WcDY 9 | 4BOXjZa99RsMVhWSZ9lg87QZ5JUlzkMQBLMvODwrbomYysolPR77gLbzdFe7QC0c 10 | 1Jah7Zxrc47mPTA93eseWK6o4JFpa32bqCiSrZWNViLNlNEKcRVW90mHVAjKMaWs 11 | f3PE9S4jygkoaUBNf9i45oEUxLzv9PaJIQRR73dI7ODpzGBBTcnsNX7/IeqasEY4 12 | WY4H9RuR3mkhPp2BziazwlkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQPTyNlZe 13 | Jc/0k3oZG8spa9uY+sQuY3n5GGpPxHbVOJRmvrPeQgSCPY31MJQRtcQPiDLWwbNG 14 | 66f9Vub204egTQwb+o0NOS0Lzx6/xHzP29vLbov+LQNTtZlj7VlcT0SWUf3bPDSD 15 | LmII6C8kDzUzq6ZvluJNujwcom1O5A1LM6fCy9XCgzDFH5PrB+WBJmaELxyAVq6L 16 | 4vo575zyHH0lu9bbWf3S3bOrk3KFpl1Posjc3Xbnh8uaPSQ514ME4U6WxsXYMle7 17 | vteJvIxG/08PMVDu0OpeWcahir8MSwgPG2NcL3FDZ1Ni3gx5NCgfQY5ozJP4ioSf 18 | YEPohL2fWj1IVg== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /ssl/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAwXdB4iRcyreqRcus3fbXLkgIjV/6iOc82CjYQhaUNwu3otfk 3 | A7/9maEdObalWPsV9OWfFLNG1v+AWeIfo9Hz1RrGbG1NQ4kAwzmiZyfrv76NiIzn 4 | Vdd84/YpQT9ZwNjgE5eNlr31GwxWFZJn2WDztBnklSXOQxAEsy84PCtuiZjKyiU9 5 | HvuAtvN0V7tALRzUlqHtnGtzjuY9MD3d6x5YrqjgkWlrfZuoKJKtlY1WIs2U0Qpx 6 | FVb3SYdUCMoxpax/c8T1LiPKCShpQE1/2LjmgRTEvO/09okhBFHvd0js4OnMYEFN 7 | yew1fv8h6pqwRjhZjgf1G5HeaSE+nYHOJrPCWQIDAQABAoIBAHFiPGmV2BAyrgcz 8 | xD9eMGR+cQyyKHnd0+n3ni61Xu4X3usATjDob29/Xkp5wdQxa3/Yp3ARVb4hhg6n 9 | mNWA8b9+brYTJQoknB7Og2Cjo+X/fqF9uwKzRQ2xMiJ8R1TfhgvVcXTcJW9Rvo3r 10 | /RMIYCu4VSAYRRdGpwqA7RtOdP0MWlVn6Wya8tnE1DEbMLbVw1gTZkzjMyqmJ+2m 11 | j1GMc5flw7D+NCe9gWCtMQXwrssWhqrJG6YN2+L0tDIXhxMebzyX1jVsxbQFzP6M 12 | yp9qAWWSqUOgnjuJhPOYQHgIZ69uc2zmZvmm30284xlQFsPsDBdf2qhodux28CnC 13 | VUepHZECgYEA8mb+6GmLVRUVIKO1TvM6RJVZtZmezGuvb2+J6RGt4N/fD4PIrkKy 14 | 67Wj1RsfL5evQhHQ1PDrFz1bYcEy0+uTN/qYVGzwQrR5dG3QatNbrreDAMl4tm46 15 | 343dSpGhnZL5CjlAoyjVOP66q9vOuseWsSvIuNdnW2/egipQKSjcVIUCgYEAzFGD 16 | IVnFP1l80RZsnN2fmosqMlf7mEg0CKq5j99QFNC4BgW+Z5IQdZkBxsnGDT6FXFe3 17 | q7saSbzCeg5MxOe2GZ4DCf0AL71GimsML/rcxqS0Thp4hKsV+p5aAovsDjiGSn3L 18 | 92QSX9ch6QytC7Iv83M1xwTHtLWLTTYeRoOFWMUCgYEAwsgMkUkuUwIL5hxmdrhv 19 | 2+h/G7QDrJPjdxITqZsxM3/xSBBHU+/4wftFWNrgZmfmxpp2SoYFArmlEpoic7Pa 20 | qqLNgRnAvnkzF2GelhiclXqU5C8AtudAm57tcRww1+PgBl0XGYSYQaI+8hZAuknj 21 | Rx69vfoo7YqpK8NAgrJ4ydkCgYBIGpwEMQIDETmTMC60TSH+EA6cJaCMZS63wEgs 22 | FcrVDbNjrLM9KbbVSWHvHVXfZqj5pZsT57unOg4HtPQyqPMCp1i7NaXTMyCpyI1M 23 | gWNYVteqmHzflOD0yN1K+MYdXqVFtI8+hvpVCD7XV7nZ3tA9QfNAgNdZVpgKb4bP 24 | q6prYQKBgHVVdJA2FSPFCBh0lY7UwDZ2xv6IxVjdb4DXH82p2nmd85cVoFGS9e4I 25 | djrLMiWDZ16dQy67A35lZxYbB5fr3uq0Xg9Pq5P08FEXwTqBnBaO0coVLT3mpCsg 26 | E3aAlPwUztgCMPOxjTYyi437LXF2TxfiSycCoNsHlyUndS4pHBeh 27 | -----END RSA PRIVATE KEY----- 28 | --------------------------------------------------------------------------------