├── .gitignore ├── .travis.yml ├── Dump.sql ├── Dumps ├── TestDump.sql ├── mysql.sql └── sqlite.sql ├── Images ├── AnimatedStop.gif ├── bootstrapped_logo.png ├── bootstrapped_logo_bw.png ├── bootstrapped_logo_small_bw.png ├── bootstrapped_logo_standard.png ├── logo.png └── redLogoPathNew.svg ├── Includes ├── Classes │ ├── File.class.php │ ├── FileSystemAnalysis.class.php │ ├── FileSystemItem.class.php │ ├── Folder.class.php │ ├── Role.class.php │ ├── Setting.class.php │ ├── Share.class.php │ └── User.class.php ├── Kernel │ ├── Kernel.Config.class.php │ ├── Kernel.Constants.inc.php │ ├── Kernel.FileSystem.class.php │ ├── Kernel.Installer.class.php │ ├── Kernel.Interface.class.php │ ├── Kernel.PDO.class.php │ ├── Kernel.Program.class.php │ ├── Kernel.Sharing.class.php │ ├── Kernel.System.class.php │ ├── Kernel.Updater.class.php │ └── Kernel.User.class.php ├── api.inc.php └── readme.php ├── LICENSE ├── Language ├── .htaccess ├── de.lng ├── en.lng └── fr.lng ├── Lib ├── Bootstrap-slider │ ├── bootstrap-slider.css │ └── bootstrap-slider.js ├── Bootstrap │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ └── bootstrap.min.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ └── js │ │ ├── bootstrap.js │ │ └── bootstrap.min.js ├── FontAwesome │ ├── css │ │ ├── font-awesome.css │ │ └── font-awesome.min.css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ └── fontawesome-webfont.woff │ ├── less │ │ ├── bordered-pulled.less │ │ ├── core.less │ │ ├── fixed-width.less │ │ ├── font-awesome.less │ │ ├── icons.less │ │ ├── larger.less │ │ ├── list.less │ │ ├── mixins.less │ │ ├── path.less │ │ ├── rotated-flipped.less │ │ ├── spinning.less │ │ ├── stacked.less │ │ └── variables.less │ └── scss │ │ ├── _bordered-pulled.scss │ │ ├── _core.scss │ │ ├── _fixed-width.scss │ │ ├── _icons.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _mixins.scss │ │ ├── _path.scss │ │ ├── _rotated-flipped.scss │ │ ├── _spinning.scss │ │ ├── _stacked.scss │ │ ├── _variables.scss │ │ └── font-awesome.scss ├── Lenticularis │ ├── css │ │ └── theme.min.css │ ├── fonts │ │ ├── Exo2-Regular.ttf │ │ └── Exo2-Thin.ttf │ └── img │ │ └── cubes.png ├── bootstrap-strength-meter │ ├── bootstrap-strength-meter.js │ ├── password-score-options.js │ └── password-score.js ├── formstone │ ├── core.js │ ├── jquery.fs.dropper.min.css │ ├── jquery.fs.dropper.min.js │ ├── upload.css │ └── upload.js ├── index.html ├── jQuery.Bootstrap │ └── jquery.bootstrap.min.js ├── jQuery │ ├── UI │ │ ├── images │ │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ │ ├── ui-bg_highlight-soft_75_ffe45c_1x100.png │ │ │ ├── ui-icons_222222_256x240.png │ │ │ ├── ui-icons_228ef1_256x240.png │ │ │ ├── ui-icons_ef8c08_256x240.png │ │ │ ├── ui-icons_ffd27a_256x240.png │ │ │ └── ui-icons_ffffff_256x240.png │ │ ├── jquery-ui.css │ │ ├── jquery-ui.js │ │ ├── jquery-ui.min.css │ │ ├── jquery-ui.min.js │ │ ├── jquery-ui.structure.css │ │ ├── jquery-ui.structure.min.css │ │ ├── jquery-ui.theme.css │ │ └── jquery-ui.theme.min.css │ ├── jquery-1.10.2.min.js │ ├── jquery-1.10.2.min.map │ ├── jquery.center.js │ ├── jquery.contextMenu.css │ ├── jquery.contextMenu.js │ ├── jquery.ui.position.js │ └── spin.min.js └── spin.min.js ├── README.md ├── Snapshots └── .htaccess ├── Storage ├── .gitignore └── .htaccess ├── System.log ├── Temp └── .htaccess ├── composer.json ├── index.php ├── install.php ├── nys ├── Nys.Controller.php ├── Nys.Router.php └── Views │ ├── Account.php │ ├── Admin.php │ ├── Changes.php │ ├── Detail.php │ ├── Files.php │ ├── Info.php │ ├── LogIn.php │ ├── Main.php │ ├── NewFolder.php │ ├── Partials │ ├── Banned.php │ ├── ErrorMessage.php │ ├── Image.php │ └── Message.php │ ├── Register.php │ ├── RequestPassword.php │ ├── Reset.php │ ├── Search.php │ ├── Settings.php │ ├── Share.php │ ├── Shares.php │ ├── StartPage.php │ ├── Update.php │ ├── Upload.php │ ├── css │ └── nys.css │ ├── img │ ├── favicon.png │ ├── logo.png │ ├── logoWithText.png │ ├── logoWithTextS.png │ └── logoWithTextSmall.png │ └── js │ ├── Nys.Dialogs.js │ ├── Nys.Files.js │ └── Nys.Helper.js ├── runTests.xml ├── test ├── tests ├── FileSystemKernelTest.php ├── InterfaceKernelTest.php ├── ProgramKernelTest.php ├── SharingKernelTest.php ├── SystemKernelTest.php ├── UpdateKernelTest.php └── UserKernelTest.php └── webclient ├── .bowerrc ├── .editorconfig ├── .gitignore ├── .jshintrc ├── .npmignore ├── .yo-rc.json ├── Gruntfile.js ├── app_components ├── TODOs.txt ├── app.js ├── config.js ├── i18n │ ├── de.json │ └── en.json ├── login │ └── login.js ├── main │ └── main.js ├── register │ ├── passwordRepetitionValidator.js │ ├── register.js │ └── userNameOrMailAddressAvailabilityValidator.js ├── services │ ├── authorization.js │ ├── fileSystem.js │ ├── principal.js │ └── user.js ├── start │ └── start.js ├── templates │ ├── error-messages.html │ ├── error-messages.jade │ ├── login.html │ ├── login.jade │ ├── main.html │ ├── main.jade │ ├── mainStart.html │ ├── mainStart.jade │ ├── register.html │ └── register.jade └── vendor │ └── sb-admin │ └── css │ └── sb-admin.css ├── bower.json ├── gulpfile.js ├── index.html ├── index.jade └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | Includes/Kernel/Kernel.Kernel.Config.class.php 2 | Storage/* 3 | Temp/* 4 | Snapshots/* 5 | lock 6 | 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.6 4 | - nightly 5 | - hhvm 6 | matrix: 7 | allow_failures: 8 | - php: hhvm 9 | before_script: 10 | - mysql -e 'create database Lenticularis;' 11 | - mysql -u root Lenticularis < ./Dumps/TestDump.sql 12 | - chmod 777 ./Storage 13 | script: phpunit --configuration ./runTests.xml 14 | # whitelist 15 | branches: 16 | only: 17 | - Lenticularis 18 | after_success: 19 | - bash <(curl -s https://codecov.io/bash) 20 | -------------------------------------------------------------------------------- /Dumps/sqlite.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `Bans` ( 2 | `Id` integer primary key autoincrement, 3 | `Ip` text NOT NULL, 4 | `Reason` text NOT NULL, 5 | `BanDateTime` datetime NOT NULL 6 | ) ; 7 | 8 | CREATE TABLE `FileSystem` ( 9 | `id` integer primary key autoincrement, 10 | `sizeInByte` int(11) NOT NULL DEFAULT '0', 11 | `filePath` text , 12 | `displayName` text NOT NULL, 13 | `uploadDateTime` datetime NOT NULL, 14 | `lastChangeDateTime` datetime NOT NULL, 15 | `uploadUserAgent` text NOT NULL, 16 | `hash` text NOT NULL, 17 | `ownerId` int(11) NOT NULL, 18 | `parentFolder` int(11) NOT NULL, 19 | `mimeType` text NOT NULL 20 | ) ; 21 | 22 | CREATE TABLE `Role` ( 23 | `id` integer primary key autoincrement, 24 | `description` text , 25 | `permissions` text , 26 | `IsDefault` tinyint(4) NOT NULL DEFAULT '0' 27 | ) ; 28 | 29 | INSERT INTO `Role` (`id`, `description`, `permissions`, `IsDefault`) VALUES 30 | (1, 'Root', '11111111111', 0), 31 | (2, 'Users', '11111111101', 1); 32 | 33 | CREATE TABLE `Session` ( 34 | `id` integer primary key autoincrement, 35 | `userID` int(11) NOT NULL, 36 | `token` text NOT NULL, 37 | `sessionStartedDateTime` datetime NOT NULL, 38 | `sessionEndDateTime` datetime DEFAULT NULL 39 | ) ; 40 | 41 | CREATE TABLE `Settings` ( 42 | `ID` integer primary key autoincrement, 43 | `SettingName` text NOT NULL, 44 | `SettingType` text NOT NULL, 45 | `SettingValue` text NOT NULL 46 | ) ; 47 | 48 | INSERT INTO `Settings` (`ID`, `SettingName`, `SettingType`, `SettingValue`) VALUES 49 | (1, 'Enable_Register', 'Boolean', 'false'), 50 | (2, 'Program_Storage_Dir', 'Text', 'Storage'), 51 | (3, 'Program_Temp_Dir', 'Text', 'Temp'), 52 | (4, 'Program_Snapshots_Dir', 'Text', 'Snapshots'), 53 | (5, 'Program_XSS_Timeout', 'Number', '20'), 54 | (6, 'Program_Name', 'Text', 'Redundancy'), 55 | (7, 'User_Contingent', 'Number', '5'), 56 | (8, 'User_Recover_Password_Length', 'Number', '10'), 57 | (9, 'Program_Session_Timeout', 'Number', '300'), 58 | (10, 'Program_Share_Link_Length', 'Number', '7'), 59 | (11, 'Program_Language', 'Text', 'en'), 60 | (12, 'Max_User_Storage', 'Number', '10000000'); 61 | 62 | CREATE TABLE `SharedFileSystem` ( 63 | `id` integer primary key autoincrement, 64 | `entryID` int(11) NOT NULL, 65 | `userID` int(11) NOT NULL, 66 | `targetUserID` int(11) DEFAULT NULL, 67 | `permissions` text , 68 | `shareCode` text , 69 | `shared` datetime NOT NULL 70 | ) ; 71 | 72 | CREATE TABLE `User` ( 73 | `Id` integer primary key autoincrement, 74 | `loginName` text , 75 | `displayName` text , 76 | `mailAddress` text , 77 | `registrationDateTime` datetime DEFAULT NULL, 78 | `lastLoginDateTime` datetime DEFAULT NULL, 79 | `passwordHash` text , 80 | `isEnabled` tinyint(1) DEFAULT NULL, 81 | `contingentInByte` bigint(11) DEFAULT NULL, 82 | `roleID` int(11) DEFAULT NULL, 83 | `failedLogins` int(11) NOT NULL 84 | ) ; 85 | 86 | INSERT INTO `User` (`id`, `loginName`, `displayName`, `mailAddress`, `registrationDateTime`, `lastLoginDateTime`, `passwordHash`, `isEnabled`, `contingentInByte`, `roleID`, `failedLogins`) VALUES 87 | (1, 'fury', 'Administrator', 'me@0fury.de', '2015-03-07 20:42:01', '2015-03-07 20:42:16', '$2y$11$hEF1r6lt1vDNShJe5ti0EetU9apyLJvKpe4gxhPim7/FWWUrD2RHK', 1, 5242880, 1, 0); 88 | 89 | -------------------------------------------------------------------------------- /Images/AnimatedStop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Images/AnimatedStop.gif -------------------------------------------------------------------------------- /Images/bootstrapped_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Images/bootstrapped_logo.png -------------------------------------------------------------------------------- /Images/bootstrapped_logo_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Images/bootstrapped_logo_bw.png -------------------------------------------------------------------------------- /Images/bootstrapped_logo_small_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Images/bootstrapped_logo_small_bw.png -------------------------------------------------------------------------------- /Images/bootstrapped_logo_standard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Images/bootstrapped_logo_standard.png -------------------------------------------------------------------------------- /Images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Images/logo.png -------------------------------------------------------------------------------- /Includes/Classes/File.class.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | class File extends FileSystemItem{ 24 | /** 25 | * The filesize in Bytes 26 | */ 27 | public $SizeInBytes; 28 | /** 29 | * The filesize with the Unit 30 | */ 31 | public $SizeWithUnit; 32 | /** 33 | * The used upload user agent 34 | */ 35 | public $UsedUserAgent; 36 | } 37 | ?> 38 | -------------------------------------------------------------------------------- /Includes/Classes/FileSystemAnalysis.class.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | class FileSystemAnalysis{ 24 | /** 25 | * The size of the user contingent 26 | */ 27 | public $sizeInByte = 0; 28 | /** 29 | * The amount of used storage in byte; 30 | */ 31 | public $usedStorageInByte = 0; 32 | } 33 | ?> 34 | -------------------------------------------------------------------------------- /Includes/Classes/FileSystemItem.class.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | class FileSystemItem{ 24 | /** 25 | * The item ID 26 | */ 27 | public $Id; 28 | /** 29 | * The items name to get displayed 30 | */ 31 | public $DisplayName; 32 | /** 33 | * The file owner ID (ID of Redundancy\Classes\User) 34 | */ 35 | public $OwnerID; 36 | /** 37 | * The parent items ID (ID of Redundancy\Classes\Folder) 38 | * or -1, if the file or folder is located in the root dir 39 | */ 40 | public $ParentID; 41 | /** 42 | * The items creation date and time 43 | */ 44 | public $CreateDateTime; 45 | /** 46 | * The time and date when the item was last changed 47 | */ 48 | public $LastChangeDateTime; 49 | /** 50 | * The hashcode of the item to verify integrity or to identify it 51 | */ 52 | public $Hash; 53 | /** 54 | * The mimetype of th entry 55 | */ 56 | public $MimeType; 57 | /** 58 | * The file physical path on the servers FS 59 | */ 60 | public $FilePath; 61 | /** 62 | * The preview picture of the file or folder. 63 | */ 64 | public $Thumbnail =false; 65 | } 66 | ?> 67 | -------------------------------------------------------------------------------- /Includes/Classes/Folder.class.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | class Folder extends FileSystemItem{ 24 | /** 25 | * The filesize in Bytes 26 | */ 27 | public $SizeInBytes; 28 | /** 29 | * The filesize with the Unit 30 | */ 31 | public $SizeWithUnit; 32 | } 33 | ?> 34 | -------------------------------------------------------------------------------- /Includes/Classes/Role.class.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | class Role{ 24 | /** 25 | * the role id 26 | */ 27 | public $Id; 28 | /** 29 | * The description/ name of the role, e. g. "root". 30 | */ 31 | public $Description; 32 | /** 33 | * The permissions of the role. It is an binary value describing if several actions are allowed or not. 34 | */ 35 | public $Permissions; 36 | /** 37 | * Is the role the systems default one? 38 | */ 39 | public $IsDefault; 40 | } 41 | ?> 42 | -------------------------------------------------------------------------------- /Includes/Classes/Setting.class.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | class Setting { 24 | /** 25 | * The name of the setting 26 | */ 27 | public $Name; 28 | /** 29 | * The type of the setting 30 | */ 31 | public $Type; 32 | /** 33 | * The current value 34 | */ 35 | public $Value; 36 | } 37 | ?> 38 | -------------------------------------------------------------------------------- /Includes/Classes/Share.class.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | class Share{ 24 | /** 25 | * the role id 26 | */ 27 | public $Id; 28 | /** 29 | * The entry which is shared 30 | */ 31 | public $Entry; 32 | /** 33 | * The user which shared the file 34 | */ 35 | public $UserID; 36 | /** 37 | * The target user if the file is shared to another user 38 | */ 39 | public $TargetUser; 40 | /** 41 | * The permissions if the file is shared to another user 42 | */ 43 | public $Permissions; 44 | /** 45 | * The sharecode if the file is shared by link 46 | */ 47 | public $ShareCode; 48 | /** 49 | * The date when the file was shared 50 | */ 51 | public $SharedDateTime; 52 | } 53 | ?> 54 | -------------------------------------------------------------------------------- /Includes/Classes/User.class.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | class User{ 24 | /** 25 | * The users ID 26 | */ 27 | public $ID = -1; 28 | /** 29 | * The Username 30 | */ 31 | public $LoginName = ""; 32 | /** 33 | * The display name 34 | */ 35 | public $DisplayName = ""; 36 | /** 37 | * The Email 38 | */ 39 | public $MailAddress = ""; 40 | /** 41 | * Registration date and time 42 | */ 43 | public $RegistrationDateTime = null; 44 | /** 45 | * The date and time of the last login 46 | */ 47 | public $LastLoginDateTime = null; 48 | /** 49 | * The password hash. 50 | */ 51 | public $PasswordHash = ""; 52 | /** 53 | * Determines if the user is enabled 54 | */ 55 | public $IsEnabled = false; 56 | /** 57 | * The User's storage size 58 | */ 59 | public $ContingentInByte = 0; 60 | /** 61 | * The object of the users role. 62 | * @see \Redundancy\Classes\Role 63 | */ 64 | public $Role = null; 65 | /** 66 | * Th amount of last failed login tries. Will be resetted on successfull login. 67 | */ 68 | public $FailedLogins; 69 | } 70 | ?> 71 | -------------------------------------------------------------------------------- /Includes/Kernel/Kernel.Config.class.php: -------------------------------------------------------------------------------- 1 | 22 | * 23 | */ 24 | abstract class Config{ 25 | const DBName = "Lenticularis"; 26 | const DBUser = "root"; 27 | const DBPassword = ""; 28 | const DBHost = "localhost"; 29 | const DBDriver = "pdo_mysql"; 30 | const DBPath = ""; 31 | } 32 | 33 | ?> -------------------------------------------------------------------------------- /Includes/Kernel/Kernel.Constants.inc.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | abstract class Errors{ 24 | const ModuleMissing = 1; 25 | const MethodMissing = 2; 26 | const UserOrEmailAlreadyGiven = 3; 27 | const RoleNotFound = 4; 28 | /** 29 | * @deprecated since 29.03.2015: This error cannot be thrown anymore (the only case was if the user db has multiple accounts with the same name). 30 | */ 31 | const MultipleUserAccountsFound = 5; 32 | const DataBaseError = 6; 33 | const PasswordOrUserNameWrong = 7; 34 | const TokenGenerationFailed = 8; 35 | const SystemDirectoryNotExisting = 9; 36 | const TokenNotValid = 10; 37 | const DirectoryNotFound = 11; 38 | const EntryExisting = 12; 39 | const NoSpaceLeft = 13; 40 | const TempFileCouldNotBeMoved = 14; 41 | const NotAllowed = 15; 42 | const EntryNotExisting = 16; 43 | const RootCannotbeMoved = 17; 44 | const CanNotPasteIntoItself = 18; 45 | const DisplayNameNotAllowed = 19; 46 | const CopyingFailed = 20; 47 | const TargetIsNoDirectory = 21; 48 | const EntryAlreadyShared = 22; 49 | const ArgumentMissing = 23; 50 | const NoTargetsExisting = 24; 51 | const NoPreviewPossible = 25; 52 | const NoShares = 26; 53 | const ShareWasNotDeleted=27; 54 | const UserNotExisting = 28; 55 | const CannotShareToMyself = 29; 56 | const RegistrationNotEnabled = 30; 57 | const ZipFileCreationFailed = 31; 58 | const ZipFileExisting = 32; 59 | const CannotDeleteFolder = 33; 60 | const CannotResetPassword = 34; 61 | const SystemAdminAccountNotAllowedToModify = 35; 62 | const NoSearchResults = 36; 63 | const SearchSyntaxWrong = 37; 64 | const XSSAttack = 38; 65 | const EditUserFailed = 39; 66 | const PermissionNotFound = 40; 67 | const UpdateOrCreationOfRoleFailed = 41; 68 | const CannotDeleteGroup = 42; 69 | const CannotDeleteDefaultGroup = 43; 70 | const GroupNameAlreadyGiven = 44; 71 | const Banned = 45; 72 | const CouldNotOpenZip = 46; 73 | const EmptyZip = 47; 74 | const UserDisabled = 48; 75 | const ToLarge = 49;//Client side upload limiation 76 | } 77 | /** 78 | * The permission set in a human readable form 79 | */ 80 | abstract class PermissionSet{ 81 | const AllowUpload = 0; 82 | const AllowCreatingFolder = 1; 83 | const AllowDeletingFolder = 2; 84 | const AllowDeletingFile = 3; 85 | const AllowRenaming = 4; 86 | const AllowDeletingUser = 5; 87 | const AllowChangingPassword = 6; 88 | const AllowMoving = 7; 89 | const AllowCopying = 8; 90 | const AllowAdministration = 9; 91 | const AllowSharing = 10; 92 | const AllowDeleteFromUserInterface = 11; 93 | const AllowUserSettings = 12; 94 | const CurrentPermissions = "AllowUpload,AllowCreatingFolder,AllowDeletingFolder,AllowDeletingFile,AllowRenaming,AllowDeletingUser,AllowChangingPassword,AllowMoving,AllowCopying,AllowAdministration,AllowSharing,AllowDeleteFromUserInterface,AllowUserSettings"; 95 | } 96 | /** 97 | * File system constants to use 98 | */ 99 | abstract class SystemDirectories 100 | { 101 | const Storage = 0; 102 | const Temp = 1; 103 | const Snapshots = 2; 104 | const Thumbnails = 3; 105 | } 106 | /** 107 | * This class contains contanst for the system 108 | */ 109 | abstract class SystemConstants{ 110 | const NotAllowedChars = '/;<;>'; 111 | } 112 | /** 113 | * The systems share modes 114 | */ 115 | abstract class ShareMode{ 116 | const ByCode = 0; 117 | const ToUser = 1; 118 | } 119 | /** 120 | * The share direction 121 | */ 122 | abstract class ShareDirection{ 123 | const ToMe = 0; 124 | const ByMe = 1; 125 | } 126 | ?> 127 | -------------------------------------------------------------------------------- /Includes/Kernel/Kernel.PDO.class.php: -------------------------------------------------------------------------------- 1 | 22 | **/ 23 | class DBLayer{ 24 | /** 25 | * The current class instance (singleton) 26 | */ 27 | private static $instance; 28 | /** 29 | * The currently open database connection. 30 | */ 31 | private $pdoinstance; 32 | /** 33 | * private constructor. Nothing to tell 34 | */ 35 | private function __construct(){} 36 | /** 37 | * Returns the current instance of the database layer. 38 | * @return the current database layer instance 39 | */ 40 | public static function GetInstance(){ 41 | if (!isset(self::$instance)){ 42 | self::$instance = new DBLayer(); 43 | self::$instance->Setup(); 44 | } 45 | return self::$instance; 46 | } 47 | /** 48 | * Sets up the database environment 49 | * @todo Move the settings in own file! 50 | * @todo several config settings! 51 | */ 52 | private function Setup(){ 53 | try{ 54 | if (\Redundancy\Kernel\Config::DBDriver == "pdo_mysql"){ 55 | $user = \Redundancy\Kernel\Config::DBUser; 56 | $password = \Redundancy\Kernel\Config::DBPassword; 57 | $host = \Redundancy\Kernel\Config::DBHost; 58 | $db = \Redundancy\Kernel\Config::DBName; 59 | $connectionString = "mysql:dbname=".$db.";host=".$host; 60 | $options = array( 61 | \PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'", 62 | \PDO::ATTR_PERSISTENT => true, 63 | ); 64 | $this->pdoinstance = new \PDO($connectionString,$user,$password,$options); 65 | }else{ 66 | $connectionString="sqlite:".\Redundancy\Kernel\Config::DBPath; 67 | $this->pdoinstance = new \PDO($connectionString); 68 | } 69 | }catch(PDOException $e){ 70 | die(Errors::DataBaseError); 71 | } 72 | } 73 | /** 74 | * Return the current connection 75 | * @return \Doctrine\DBAL\Connection the current connection 76 | */ 77 | public function GetConnection(){ 78 | return $this->pdoinstance; 79 | } 80 | /** 81 | * Runs an select query on the database 82 | * @param $sql the sql query to run 83 | * @return array|null containing the results 84 | */ 85 | public function RunSelect($sql){ 86 | $result = null; 87 | try{ 88 | if (!isset($this->pdoinstance)){ 89 | $this->Setup(); 90 | } 91 | $stmt = $this->GetConnection()->query($sql); 92 | while ($row = $stmt->fetch()) { 93 | $result[] = $row; 94 | } 95 | return $result; 96 | }catch(Exception $e){ 97 | return null; 98 | } 99 | } 100 | /** 101 | * Update data in the database 102 | * @param $sql the sql query to run 103 | * @return integer the amount of affected rows 104 | */ 105 | public function RunUpdate($sql){ 106 | try{ 107 | if (!isset($this->pdoinstance)){ 108 | $this->Setup(); 109 | } 110 | $count = $this->GetConnection()->exec($sql); 111 | return $count; 112 | }catch(Exception $e){ 113 | return null; 114 | } 115 | } 116 | /** 117 | * Delete data from the database 118 | * @param $sql the sql query to run 119 | * @return \Doctrine\DBAL\Query an data object containing the query 120 | */ 121 | public function RunDelete($sql){ 122 | try{ 123 | if (!isset($this->pdoinstance)){ 124 | $this->Setup(); 125 | } 126 | $result = $this->GetConnection()->query($sql); 127 | return $result; 128 | }catch(Exception $e){ 129 | return null; 130 | } 131 | } 132 | /** 133 | * Insert data to db 134 | * @param $sql the sql query to run 135 | * @return \Doctrine\DBAL\Query an data object containing the query 136 | */ 137 | function RunInsert($sql){ 138 | try{ 139 | if (!isset($this->pdoinstance)){ 140 | $this->Setup(); 141 | } 142 | $result = $this->GetConnection()->query($sql); 143 | return $result; 144 | }catch(Exception $e){ 145 | return null; 146 | } 147 | } 148 | /** 149 | * Escapes a string like mysqli_real_escape_string 150 | * @param $string the param to escape 151 | * @param $quotemarks determines if the escaped string should replace '' with nothing 152 | * @return string the escaped string 153 | * @todo improve this feature 154 | */ 155 | public function EscapeString($string,$quotemarks){ 156 | 157 | $string = addslashes($string); 158 | if (!isset($this->connection)){ 159 | $this->Setup(); 160 | } 161 | if ($quotemarks == false) 162 | return $this->GetConnection()->quote($string); 163 | else 164 | return str_replace("\"","",str_replace("'","",$this->GetConnection()->quote($string))); 165 | } 166 | } 167 | ?> 168 | -------------------------------------------------------------------------------- /Includes/api.inc.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * @section LICENSE 8 | * 9 | * This program is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU General Public License as 11 | * published by the Free Software Foundation; either version 3 of 12 | * the License, or (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details at 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | * @section DESCRIPTION 21 | * 22 | * Central api layer to send requests to. 23 | */ 24 | namespace Redundancy; 25 | 26 | //Damn Windows! 27 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') 28 | $path = str_replace("Includes\api.inc.php","", __file__); 29 | else 30 | $path = str_replace("Includes/api.inc.php","", __file__); 31 | /** 32 | * The systems root dir, ending with "/" 33 | */ 34 | define("__REDUNDANCY_ROOT__",$path); 35 | /** 36 | * A flag determining if the system is in debug mode (for later purposes) 37 | */ 38 | define("__REDUNDANCY_DEBUG__",true); 39 | /** 40 | * A flag determining if the system is in a testing mode 41 | */ 42 | include __REDUNDANCY_ROOT__."Includes/Kernel/Kernel.Program.class.php"; 43 | /** 44 | * blalbla 45 | */ 46 | $Redundancy = new \Redundancy\Kernel\Kernel(); 47 | if (__REDUNDANCY_DEBUG__ == true){ 48 | ini_set('error_reporting', E_ALL); 49 | ini_set('display_errors', '1'); 50 | ini_set('display_startup_errors', '1'); 51 | } 52 | if (isset($_POST["method"])){ 53 | $method = $_POST["method"]; 54 | 55 | if (isset($_POST["args"])){ 56 | $params = is_array($_POST["args"]) ? $_POST["args"] : json_decode($_POST["args"]); 57 | } 58 | else 59 | $params = array(); 60 | //If the regular parsing fails, try to decode the data first (for example if files are send) 61 | //Wenn maybe same solution of line 55 62 | if (is_null($params)) 63 | $params = json_decode(urldecode($_POST["args"])); 64 | $module = $_POST["module"]; 65 | 66 | if ($Redundancy->SystemKernel->IsAffectedByXSS($params)){ 67 | $ip = $Redundancy->UserKernel->GetIP(); 68 | error_log("Redundancy [Warning]: Propably XSS attack from $ip"); 69 | //The user does not get banned, but the request ist stopped here! 70 | //die($Redundancy->Output(\Redundancy\Classes\Errors::XSSAttack)); 71 | } 72 | //Clean up the parameters 73 | $cleanedArgs = array(); 74 | if (!empty($params)){ 75 | foreach ($params as $key => $value) { 76 | $cleanedArgs[] = htmlspecialchars(strip_tags($value),ENT_NOQUOTES); 77 | } 78 | $params = $cleanedArgs; 79 | } 80 | if ($Redundancy->SystemKernel->IsMyIPBanned() && $method != "GetIP") 81 | { 82 | die ($Redundancy->Output(\Redundancy\Classes\Errors::Banned)); 83 | } 84 | if (!isset($module)) 85 | die("Fatal Error :( ".\Redundancy\Classes\Errors::ModuleMissing); 86 | //RAW Date formatter set 87 | if (isset($_POST["rawDate"])){ 88 | $Redundancy->InterfaceKernel->SetRawDateFormatter(); 89 | } 90 | //TODO: A more professional solution 91 | switch($module){ 92 | case "Kernel": 93 | $Redundancy->Output(call_user_func_array(array($Redundancy,$method), $params)); 94 | break; 95 | case "Kernel.UserKernel": 96 | $Redundancy->Output(call_user_func_array(array($Redundancy->UserKernel,$method), $params)); 97 | break; 98 | case "Kernel.InterfaceKernel": 99 | $Redundancy->Output(call_user_func_array(array($Redundancy->InterfaceKernel,$method), $params)); 100 | break; 101 | case "Kernel.FileSystemKernel": 102 | $Redundancy->Output(call_user_func_array(array($Redundancy->FileSystemKernel,$method), $params)); 103 | break; 104 | case "Kernel.SharingKernel": 105 | $Redundancy->Output(call_user_func_array(array($Redundancy->SharingKernel,$method), $params)); 106 | break; 107 | case "Kernel.SystemKernel": 108 | $Redundancy->Output(call_user_func_array(array($Redundancy->SystemKernel,$method), $params)); 109 | break; 110 | case "Kernel.UpdateKernel": 111 | $Redundancy->Output(call_user_func_array(array($Redundancy->UpdateKernel,$method), $params)); 112 | break; 113 | } 114 | } 115 | ?> 116 | -------------------------------------------------------------------------------- /Includes/readme.php: -------------------------------------------------------------------------------- 1 | HTTP GET "method": The method (attention: Case sensitive!) 11 | * 12 | * -> HTTP GET "module": The name of the Kernel part, e. g. "Kernel" or "Kernel.UserKernel" 13 | * 14 | * -> HTTP POST "args": The arguments of the function call (as JSON - formatted string) 15 | * 16 | * -> The result will be printed out as JSON - formatted string. 17 | * 18 | * Example 19 | * 20 | * server/Includes/api.inc.php?module=Kernel.User&method=Authentificate (the method needs an username and a password) 21 | * 22 | * POST data: args -> ["username","password"] 23 | * 24 | * Result: true 25 | * 26 | * This file is no sourcecode file. 27 | * @license 28 | * 29 | * This program is free software; you can redistribute it and/or 30 | * modify it under the terms of the GNU General Public License as 31 | * published by the Free Software Foundation; either version 3 of 32 | * the License, or (at your option) any later version. 33 | * 34 | * This program is distributed in the hope that it will be useful, but 35 | * WITHOUT ANY WARRANTY; without even the implied warranty of 36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 37 | * General Public License for more details at 38 | * http://www.gnu.org/copyleft/gpl.html 39 | * 40 | * @author squarerootfury 41 | **/ 42 | class README{ 43 | 44 | } 45 | ?> 46 | -------------------------------------------------------------------------------- /Language/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all -------------------------------------------------------------------------------- /Lib/Bootstrap-slider/bootstrap-slider.css: -------------------------------------------------------------------------------- 1 | /*! ========================================================= 2 | * bootstrap-slider.js 3 | * 4 | * Maintainers: 5 | * Kyle Kemp 6 | * - Twitter: @seiyria 7 | * - Github: seiyria 8 | * Rohit Kalkur 9 | * - Twitter: @Rovolutionary 10 | * - Github: rovolution 11 | * 12 | * ========================================================= 13 | * 14 | * Licensed under the Apache License, Version 2.0 (the "License"); 15 | * you may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at 17 | * 18 | * http://www.apache.org/licenses/LICENSE-2.0 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * ========================================================= */ 26 | .slider { 27 | display: inline-block; 28 | vertical-align: middle; 29 | position: relative; 30 | } 31 | .slider.slider-horizontal { 32 | width: 210px; 33 | height: 20px; 34 | } 35 | .slider.slider-horizontal .slider-track { 36 | height: 10px; 37 | width: 100%; 38 | margin-top: -5px; 39 | top: 50%; 40 | left: 0; 41 | } 42 | .slider.slider-horizontal .slider-selection { 43 | height: 100%; 44 | top: 0; 45 | bottom: 0; 46 | } 47 | .slider.slider-horizontal .slider-handle { 48 | margin-left: -10px; 49 | margin-top: -5px; 50 | } 51 | .slider.slider-horizontal .slider-handle.triangle { 52 | border-width: 0 10px 10px 10px; 53 | width: 0; 54 | height: 0; 55 | border-bottom-color: #0480be; 56 | margin-top: 0; 57 | } 58 | .slider.slider-vertical { 59 | height: 210px; 60 | width: 20px; 61 | } 62 | .slider.slider-vertical .slider-track { 63 | width: 10px; 64 | height: 100%; 65 | margin-left: -5px; 66 | left: 50%; 67 | top: 0; 68 | } 69 | .slider.slider-vertical .slider-selection { 70 | width: 100%; 71 | left: 0; 72 | top: 0; 73 | bottom: 0; 74 | } 75 | .slider.slider-vertical .slider-handle { 76 | margin-left: -5px; 77 | margin-top: -10px; 78 | } 79 | .slider.slider-vertical .slider-handle.triangle { 80 | border-width: 10px 0 10px 10px; 81 | width: 1px; 82 | height: 1px; 83 | border-left-color: #0480be; 84 | margin-left: 0; 85 | } 86 | .slider.slider-disabled .slider-handle { 87 | background-image: -webkit-linear-gradient(top, #dfdfdf 0%, #bebebe 100%); 88 | background-image: linear-gradient(to bottom, #dfdfdf 0%, #bebebe 100%); 89 | background-repeat: repeat-x; 90 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdfdfdf', endColorstr='#ffbebebe', GradientType=0); 91 | } 92 | .slider.slider-disabled .slider-track { 93 | background-image: -webkit-linear-gradient(top, #e5e5e5 0%, #e9e9e9 100%); 94 | background-image: linear-gradient(to bottom, #e5e5e5 0%, #e9e9e9 100%); 95 | background-repeat: repeat-x; 96 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe5e5e5', endColorstr='#ffe9e9e9', GradientType=0); 97 | cursor: not-allowed; 98 | } 99 | .slider input { 100 | display: none; 101 | } 102 | .slider .tooltip.top { 103 | margin-top: -36px; 104 | } 105 | .slider .tooltip-inner { 106 | white-space: nowrap; 107 | } 108 | .slider .hide { 109 | display: none; 110 | } 111 | .slider-track { 112 | position: absolute; 113 | cursor: pointer; 114 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #f9f9f9 100%); 115 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #f9f9f9 100%); 116 | background-repeat: repeat-x; 117 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); 118 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); 119 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); 120 | border-radius: 4px; 121 | } 122 | .slider-selection { 123 | position: absolute; 124 | background-image: -webkit-linear-gradient(top, #f9f9f9 0%, #f5f5f5 100%); 125 | background-image: linear-gradient(to bottom, #f9f9f9 0%, #f5f5f5 100%); 126 | background-repeat: repeat-x; 127 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0); 128 | -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); 129 | box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); 130 | -webkit-box-sizing: border-box; 131 | -moz-box-sizing: border-box; 132 | box-sizing: border-box; 133 | border-radius: 4px; 134 | } 135 | .slider-handle { 136 | position: absolute; 137 | width: 20px; 138 | height: 20px; 139 | background-color: #3a94a5; 140 | background-image: -webkit-linear-gradient(top, #149bdf 0%, #0480be 100%); 141 | background-image: linear-gradient(to bottom, #149bdf 0%, #0480be 100%); 142 | background-repeat: repeat-x; 143 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); 144 | filter: none; 145 | -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); 146 | box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); 147 | opacity: 0.8; 148 | border: 0px solid transparent; 149 | } 150 | .slider-handle.round { 151 | border-radius: 50%; 152 | } 153 | .slider-handle.triangle { 154 | background: transparent none; 155 | } 156 | .slider-handle.custom { 157 | background: transparent none; 158 | } 159 | .slider-handle.custom::before { 160 | line-height: 20px; 161 | font-size: 20px; 162 | content: '\2605'; 163 | color: #726204; 164 | } 165 | -------------------------------------------------------------------------------- /Lib/Bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/Bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Lib/Bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/Bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Lib/Bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/Bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Lib/FontAwesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/FontAwesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /Lib/FontAwesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/FontAwesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /Lib/FontAwesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/FontAwesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /Lib/FontAwesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/FontAwesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /Lib/FontAwesome/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .@{fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal 14px/1 FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | } 12 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "spinning.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: (-@fa-li-width + (4em / 14)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal 14px/1 FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | } 12 | 13 | .fa-icon-rotate(@degrees, @rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); 15 | -webkit-transform: rotate(@degrees); 16 | -ms-transform: rotate(@degrees); 17 | transform: rotate(@degrees); 18 | } 19 | 20 | .fa-icon-flip(@horiz, @vert, @rotation) { 21 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); 22 | -webkit-transform: scale(@horiz, @vert); 23 | -ms-transform: scale(@horiz, @vert); 24 | transform: scale(@horiz, @vert); 25 | } 26 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 9 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 10 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 11 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .@{fa-css-prefix}-rotate-90, 15 | :root .@{fa-css-prefix}-rotate-180, 16 | :root .@{fa-css-prefix}-rotate-270, 17 | :root .@{fa-css-prefix}-flip-horizontal, 18 | :root .@{fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/spinning.less: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | @-webkit-keyframes fa-spin { 10 | 0% { 11 | -webkit-transform: rotate(0deg); 12 | transform: rotate(0deg); 13 | } 14 | 100% { 15 | -webkit-transform: rotate(359deg); 16 | transform: rotate(359deg); 17 | } 18 | } 19 | 20 | @keyframes fa-spin { 21 | 0% { 22 | -webkit-transform: rotate(0deg); 23 | transform: rotate(0deg); 24 | } 25 | 100% { 26 | -webkit-transform: rotate(359deg); 27 | transform: rotate(359deg); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Lib/FontAwesome/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal 14px/1 FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | } 12 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal 14px/1 FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | } 12 | 13 | @mixin fa-icon-rotate($degrees, $rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 15 | -webkit-transform: rotate($degrees); 16 | -ms-transform: rotate($degrees); 17 | transform: rotate($degrees); 18 | } 19 | 20 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 21 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 22 | -webkit-transform: scale($horiz, $vert); 23 | -ms-transform: scale($horiz, $vert); 24 | transform: scale($horiz, $vert); 25 | } 26 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 9 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 10 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 11 | //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .#{$fa-css-prefix}-rotate-90, 15 | :root .#{$fa-css-prefix}-rotate-180, 16 | :root .#{$fa-css-prefix}-rotate-270, 17 | :root .#{$fa-css-prefix}-flip-horizontal, 18 | :root .#{$fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_spinning.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | @-webkit-keyframes fa-spin { 10 | 0% { 11 | -webkit-transform: rotate(0deg); 12 | transform: rotate(0deg); 13 | } 14 | 100% { 15 | -webkit-transform: rotate(359deg); 16 | transform: rotate(359deg); 17 | } 18 | } 19 | 20 | @keyframes fa-spin { 21 | 0% { 22 | -webkit-transform: rotate(0deg); 23 | transform: rotate(0deg); 24 | } 25 | 100% { 26 | -webkit-transform: rotate(359deg); 27 | transform: rotate(359deg); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /Lib/FontAwesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /Lib/Lenticularis/fonts/Exo2-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/Lenticularis/fonts/Exo2-Regular.ttf -------------------------------------------------------------------------------- /Lib/Lenticularis/fonts/Exo2-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/Lenticularis/fonts/Exo2-Thin.ttf -------------------------------------------------------------------------------- /Lib/Lenticularis/img/cubes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/Lenticularis/img/cubes.png -------------------------------------------------------------------------------- /Lib/formstone/core.js: -------------------------------------------------------------------------------- 1 | /*! formstone v0.5.11 [core.js] 2015-05-08 | MIT License | formstone.it */ 2 | 3 | var Formstone=this.Formstone=function(a,b,c){"use strict";function d(a,b,c,d){var e,f={raw:{}};d=d||{};for(e in d)d.hasOwnProperty(e)&&("classes"===a?(f.raw[d[e]]=b+"-"+d[e],f[d[e]]="."+b+"-"+d[e]):(f.raw[e]=d[e],f[e]=d[e]+"."+b));for(e in c)c.hasOwnProperty(e)&&("classes"===a?(f.raw[e]=c[e].replace(/{ns}/g,b),f[e]=c[e].replace(/{ns}/g,"."+b)):(f.raw[e]=c[e].replace(/.{ns}/g,""),f[e]=c[e].replace(/{ns}/g,b)));return f}function e(){var a,b={transition:"transitionend",MozTransition:"transitionend",OTransition:"otransitionend",WebkitTransition:"webkitTransitionEnd"},d=["transition","-webkit-transition"],e={transform:"transform",MozTransform:"-moz-transform",OTransform:"-o-transform",msTransform:"-ms-transform",webkitTransform:"-webkit-transform"},f="transitionend",g="",h="",i=c.createElement("div");for(a in b)if(b.hasOwnProperty(a)&&a in i.style){f=b[a],k.support.transition=!0;break}m.transitionEnd=f+".{ns}";for(a in d)if(d.hasOwnProperty(a)&&d[a]in i.style){g=d[a];break}k.transition=g;for(a in e)if(e.hasOwnProperty(a)&&e[a]in i.style){k.support.transform=!0,h=e[a];break}k.transform=h}function f(){k.windowWidth=k.$window.width(),k.windowHeight=k.$window.height(),n=j.startTimer(n,o,g)}function g(){for(var a in k.ResizeHandlers)k.ResizeHandlers.hasOwnProperty(a)&&k.ResizeHandlers[a].callback.call(b,k.windowWidth,k.windowHeight)}function h(a,b){return parseInt(a.priority)-parseInt(b.priority)}var i=function(){this.Version="0.5.11",this.Plugins={},this.ResizeHandlers=[],this.window=b,this.$window=a(b),this.document=c,this.$document=a(c),this.$body=null,this.windowWidth=0,this.windowHeight=0,this.userAgent=b.navigator.userAgent||b.navigator.vendor||b.opera,this.isFirefox=/Firefox/i.test(this.userAgent),this.isChrome=/Chrome/i.test(this.userAgent),this.isSafari=/Safari/i.test(this.userAgent)&&!this.isChrome,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(this.userAgent),this.isFirefoxMobile=this.isFirefox&&this.isMobile,this.transform=null,this.transition=null,this.support={file:!!(b.File&&b.FileList&&b.FileReader),history:!!(b.history&&b.history.pushState&&b.history.replaceState),matchMedia:!(!b.matchMedia&&!b.msMatchMedia),raf:!(!b.requestAnimationFrame||!b.cancelAnimationFrame),touch:!!("ontouchstart"in b||b.DocumentTouch&&c instanceof b.DocumentTouch),transition:!1,transform:!1}},j={killEvent:function(a,b){try{a.preventDefault(),a.stopPropagation(),b&&a.stopImmediatePropagation()}catch(c){}},startTimer:function(a,b,c,d){return j.clearTimer(a),d?setInterval(c,b):setTimeout(c,b)},clearTimer:function(a,b){a&&(b?clearInterval(a):clearTimeout(a),a=null)},sortAsc:function(a,b){return parseInt(b)-parseInt(a)},sortDesc:function(a,b){return parseInt(b)-parseInt(a)}},k=new i,l={base:"{ns}",element:"{ns}-element"},m={namespace:".{ns}",blur:"blur.{ns}",change:"change.{ns}",click:"click.{ns}",dblClick:"dblclick.{ns}",drag:"drag.{ns}",dragEnd:"dragend.{ns}",dragEnter:"dragenter.{ns}",dragLeave:"dragleave.{ns}",dragOver:"dragover.{ns}",dragStart:"dragstart.{ns}",drop:"drop.{ns}",error:"error.{ns}",focus:"focus.{ns}",focusIn:"focusin.{ns}",focusOut:"focusout.{ns}",input:"input.{ns}",keyDown:"keydown.{ns}",keyPress:"keypress.{ns}",keyUp:"keyup.{ns}",load:"load.{ns}",mouseDown:"mousedown.{ns}",mouseEnter:"mouseenter.{ns}",mouseLeave:"mouseleave.{ns}",mouseMove:"mousemove.{ns}",mouseOut:"mouseout.{ns}",mouseOver:"mouseover.{ns}",mouseUp:"mouseup.{ns}",resize:"resize.{ns}",scroll:"scroll.{ns}",select:"select.{ns}",touchCancel:"touchcancel.{ns}",touchEnd:"touchend.{ns}",touchLeave:"touchleave.{ns}",touchMove:"touchmove.{ns}",touchStart:"touchstart.{ns}"};i.prototype.Plugin=function(c,e){return k.Plugins[c]=function(c,e){function f(b){var d="object"===a.type(b);b=a.extend(!0,{},e.defaults||{},d?b:{});for(var f=this,g=0,h=f.length;h>g;g++){var j=f.eq(g);if(!i(j)){var k=j.data(c+"-options"),l=a.extend(!0,{$el:j},b,"object"===a.type(k)?k:{});j.addClass(e.classes.raw.element).data(r,l),e.methods._construct.apply(j,[l].concat(Array.prototype.slice.call(arguments,d?1:0)))}}return f}function g(){e.functions.iterate.apply(this,[e.methods._destruct].concat(Array.prototype.slice.call(arguments,1))),this.removeClass(e.classes.raw.element).removeData(r)}function i(a){return a.data(r)}function n(b){if(this instanceof a){var c=e.methods[b];return"object"!==a.type(b)&&b?c&&0!==b.indexOf("_")?e.functions.iterate.apply(this,[c].concat(Array.prototype.slice.call(arguments,1))):this:f.apply(this,arguments)}}function o(c){var d=e.utilities[c]||e.utilities._initialize||!1;return d?d.apply(b,Array.prototype.slice.call(arguments,"object"===a.type(c)?0:1)):void 0}function p(b){e.defaults=a.extend(!0,e.defaults,b||{})}function q(b){for(var c=this,d=0,e=c.length;e>d;d++){var f=c.eq(d),g=i(f)||{};"undefined"!==a.type(g.$el)&&b.apply(f,[g].concat(Array.prototype.slice.call(arguments,1)))}return c}var r="fs-"+c;return e.initialized=!1,e.priority=e.priority||10,e.classes=d("classes",r,l,e.classes),e.events=d("events",c,m,e.events),e.functions=a.extend({getData:i,iterate:q},j,e.functions),e.methods=a.extend(!0,{_setup:a.noop,_construct:a.noop,_destruct:a.noop,_resize:!1,destroy:g},e.methods),e.utilities=a.extend(!0,{_initialize:!1,_delegate:!1,defaults:p},e.utilities),e.widget&&(a.fn[c]=n),a[c]=e.utilities._delegate||o,e.namespace=c,e.methods._resize&&(k.ResizeHandlers.push({namespace:c,priority:e.priority,callback:e.methods._resize}),k.ResizeHandlers.sort(h)),e}(c,e),k.Plugins[c]};var n=null,o=20;return k.$window.on("resize.fs",f),f(),a(function(){k.$body=a("body");for(var b in k.Plugins)k.Plugins.hasOwnProperty(b)&&!k.Plugins[b].initialized&&(k.Plugins[b].methods._setup.call(c),k.Plugins[b].initialized=!0)}),m.clickTouchStart=m.click+" "+m.touchStart,e(),k}(jQuery,this,document); -------------------------------------------------------------------------------- /Lib/formstone/jquery.fs.dropper.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Dropper v1.0.1 - 2015-04-04 3 | * A jQuery plugin for simple drag and drop uploads. Part of the Formstone Library. 4 | * http://classic.formstone.it/dropper/ 5 | * 6 | * Copyright 2015 Ben Plum; MIT Licensed 7 | */ 8 | 9 | .dropper{overflow:hidden}.dropper,.dropper *,.dropper :before,.dropper :after{box-sizing:border-box}.dropper-dropzone{background:#fff;border:3px dashed #ccc;border-radius:0;color:#666;cursor:pointer;font-size:14px;margin:0;padding:25px;text-align:center}.dropper.dropping .dropper-dropzone,.no-touch .dropper:hover .dropper-dropzone{background:#eee;border-color:#999;color:#333}.dropper-input{position:absolute;left:100%;opacity:0}.no-opacity .dropper-input{left:-999px} -------------------------------------------------------------------------------- /Lib/formstone/jquery.fs.dropper.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Dropper v1.0.1 - 2015-04-04 3 | * A jQuery plugin for simple drag and drop uploads. Part of the Formstone Library. 4 | * http://classic.formstone.it/dropper/ 5 | * 6 | * Copyright 2015 Ben Plum; MIT Licensed 7 | */ 8 | 9 | !function(a,b){"use strict";function c(b){var c=a(this);if(n){b=a.extend({},o,b);for(var e=0,f=c.length;f>e;e++)d(c.eq(e),b)}return c}function d(b,c){c=a.extend({},c,b.data("dropper-options"));var d="";d+='
',d+=c.label,d+="
",d+='1&&(d+=" multiple"),d+=">",b.addClass("dropper").append(d);var k=a.extend({$dropper:b,$input:b.find(".dropper-input"),queue:[],total:0,uploading:!1},c);b.on("click.dropper",".dropper-dropzone",k,e).on("dragenter.dropper",k,g).on("dragover.dropper",k,h).on("dragleave.dropper",k,i).on("drop.dropper",".dropper-dropzone",k,j).data("dropper",k),k.$input.on("change.dropper",k,f)}function e(a){a.stopPropagation(),a.preventDefault();var b=a.data;b.$input.trigger("click")}function f(a){a.stopPropagation(),a.preventDefault();var b=a.data,c=b.$input[0].files;c.length&&k(b,c)}function g(a){a.stopPropagation(),a.preventDefault();var b=a.data;b.$dropper.addClass("dropping")}function h(a){a.stopPropagation(),a.preventDefault();var b=a.data;b.$dropper.addClass("dropping")}function i(a){a.stopPropagation(),a.preventDefault();var b=a.data;b.$dropper.removeClass("dropping")}function j(a){a.preventDefault();var b=a.data,c=a.originalEvent.dataTransfer.files;b.$dropper.removeClass("dropping"),k(b,c)}function k(c,d){for(var e=[],f=0;f=c.maxQueue)return;f++}0===d&&(a(b).off("beforeunload.dropper"),c.uploading=!1,c.$dropper.trigger("complete.dropper"))}function m(b,c,d){c.size>=b.maxSize?(c.error=!0,b.$dropper.trigger("fileError.dropper",[c,"Too large"]),l(b)):(c.started=!0,c.transfer=a.ajax({url:b.action,data:d,type:"POST",contentType:!1,processData:!1,cache:!1,xhr:function(){var d=a.ajaxSettings.xhr();return d.upload&&d.upload.addEventListener("progress",function(a){var d=0,e=a.loaded||a.position,f=a.total;a.lengthComputable&&(d=Math.ceil(e/f*100)),b.$dropper.trigger("fileProgress.dropper",[c,d])},!1),d},beforeSend:function(a){b.$dropper.trigger("fileStart.dropper",[c])},success:function(a,d,e){c.complete=!0,b.$dropper.trigger("fileComplete.dropper",[c,a]),l(b)},error:function(a,d,e){c.error=!0,b.$dropper.trigger("fileError.dropper",[c,e]),l(b)}}))}var n=b.File&&b.FileReader&&b.FileList,o={action:"",label:"Drag and drop files or click to select",maxQueue:2,maxSize:5242880,postData:{},postKey:"file"},p={defaults:function(b){return o=a.extend(o,b||{}),"object"==typeof this?a(this):!0}};a.fn.dropper=function(a){return p[a]?p[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?this:c.apply(this,arguments)},a.dropper=function(a){"defaults"===a&&p.defaults.apply(this,Array.prototype.slice.call(arguments,1))}}(jQuery,window); -------------------------------------------------------------------------------- /Lib/formstone/upload.css: -------------------------------------------------------------------------------- 1 | /*! formstone v0.5.11 [upload.css] 2015-05-08 | MIT License | formstone.it */ 2 | 3 | /** 4 | * @class 5 | * @name .fs-upload-element 6 | * @type element 7 | * @description Target elmement 8 | */ 9 | /** 10 | * @class 11 | * @name .fs-upload 12 | * @type element 13 | * @description Base widget class 14 | */ 15 | /** 16 | * @class 17 | * @name .fs-upload.fs-upload-dropping 18 | * @type modifier 19 | * @description Indicates dropping state 20 | */ 21 | .fs-upload { 22 | overflow: hidden; 23 | /** 24 | * @class 25 | * @name .fs-upload-input 26 | * @type element 27 | * @description Masked Input 28 | */ 29 | /** 30 | * @class 31 | * @name .fs-upload-target 32 | * @type element 33 | * @description Drop target 34 | */ 35 | } 36 | .fs-upload, 37 | .fs-upload:after, 38 | .fs-upload:before, 39 | .fs-upload *, 40 | .fs-upload *:after, 41 | .fs-upload *:before { 42 | box-sizing: border-box; 43 | -webkit-transition: none; 44 | transition: none; 45 | -webkit-user-select: none !important; 46 | -moz-user-select: none !important; 47 | -ms-user-select: none !important; 48 | user-select: none !important; 49 | } 50 | .fs-upload-input { 51 | position: absolute; 52 | left: 100%; 53 | opacity: 0; 54 | } 55 | .no-opacity .fs-upload-input { 56 | left: -999px; 57 | } 58 | .fs-upload-target { 59 | background: #ffffff; 60 | border: 3px dashed #cccccc; 61 | border-radius: 3px; 62 | color: #666666; 63 | cursor: pointer; 64 | font-size: 14px; 65 | margin: 0; 66 | padding: 25px; 67 | text-align: center; 68 | -webkit-transition: background 0.15s linear, 69 | border 0.15s linear, 70 | opacity 0.15s linear; 71 | transition: background 0.15s linear, 72 | border 0.15s linear, 73 | opacity 0.15s linear; 74 | } 75 | .fs-upload.dropping .fs-upload-target, 76 | .no-touch .fs-upload:hover .fs-upload-target { 77 | background: #eeeeee; 78 | border-color: #999999; 79 | color: #333333; 80 | } 81 | -------------------------------------------------------------------------------- /Lib/formstone/upload.js: -------------------------------------------------------------------------------- 1 | /*! formstone v0.5.11 [upload.js] 2015-05-08 | MIT License | formstone.it */ 2 | 3 | !function(a,b){"use strict";function c(a){if(b.support.file){var c="";c+='
',c+=a.label,c+="
",c+='1&&(c+=" "+p.multiple),c+=">",this.addClass(p.base).append(c),a.$input=this.find(o.input),a.queue=[],a.total=0,a.uploading=!1,this.on(q.click,o.target,a,e).on(q.dragEnter,a,g).on(q.dragOver,a,h).on(q.dragLeave,a,i).on(q.drop,o.target,a,j),a.$input.on(q.change,a,f)}}function d(a){b.support.file&&(a.$input.off(q.namespace),this.off([q.click,q.dragEnter,q.dragOver,q.dragLeave,q.drop].join(" ")).removeClass(p.base).html(""))}function e(a){a.stopPropagation(),a.preventDefault();var b=a.data;b.$input.trigger(q.click)}function f(a){a.stopPropagation(),a.preventDefault();var b=a.data,c=b.$input[0].files;c.length&&k(b,c)}function g(a){a.stopPropagation(),a.preventDefault();var b=a.data;b.$el.addClass(p.dropping)}function h(a){a.stopPropagation(),a.preventDefault();var b=a.data;b.$el.addClass(p.dropping)}function i(a){a.stopPropagation(),a.preventDefault();var b=a.data;b.$el.removeClass(p.dropping)}function j(a){a.preventDefault();var b=a.data,c=a.originalEvent.dataTransfer.files;b.$el.removeClass(p.dropping),k(b,c)}function k(a,b){for(var c=[],d=0;d=a.maxQueue)return;d++}0===b&&(r.off(q.beforeUnload),a.uploading=!1,a.$el.trigger(q.complete))}function m(b,c,d){c.size>=b.maxSize?(c.error=!0,b.$el.trigger(q.fileError,[c,"Too large"]),l(b)):(c.started=!0,c.transfer=a.ajax({url:b.action,data:d,type:"POST",contentType:!1,processData:!1,cache:!1,xhr:function(){var d=a.ajaxSettings.xhr();return d.upload&&d.upload.addEventListener("progress",function(a){var d=0,e=a.loaded||a.position,f=a.total;a.lengthComputable&&(d=Math.ceil(e/f*100)),b.$el.trigger(q.fileProgress,[c,d])},!1),d},beforeSend:function(){b.$el.trigger(q.fileStart,[c])},success:function(a){c.complete=!0,b.$el.trigger(q.fileComplete,[c,a]),l(b)},error:function(a,d,e){c.error=!0,b.$el.trigger(q.fileError,[c,e]),l(b)}}))}var n=b.Plugin("upload",{widget:!0,defaults:{customClass:"",action:"",label:"Drag and drop files or click to select",leave:"You have uploads pending, are you sure you want to leave this page?",maxQueue:2,maxSize:5242880,postData:{},postKey:"file"},classes:["input","target","multiple","dropping"],methods:{_construct:c,_destruct:d}}),o=n.classes,p=o.raw,q=n.events,r=(n.functions,b.$window);q.complete="complete",q.fileStart="filestart",q.fileProgress="fileprogress",q.fileComplete="filecomplete",q.fileError="fileerror",q.start="start"}(jQuery,Formstone); -------------------------------------------------------------------------------- /Lib/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flat UI Free 101 Template 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 |
24 |

Hello, world!

25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Lib/jQuery/UI/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /Lib/jQuery/UI/jquery-ui.structure.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.1 - 2014-09-29 2 | * http://jqueryui.com 3 | * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move} -------------------------------------------------------------------------------- /Lib/jQuery/jquery.center.js: -------------------------------------------------------------------------------- 1 | jQuery.fn.center=function(absolute){return this.each(function(){var t=jQuery(this);t.css({position:absolute?'absolute':'fixed',left:'50%',top:'50%',zIndex:'99'}).css({marginLeft:'-'+(t.outerWidth()/2)+'px',marginTop:'-'+(t.outerHeight()/2)+'px'});if(absolute){t.css({marginTop:parseInt(t.css('marginTop'),10)+jQuery(window).scrollTop(),marginLeft:parseInt(t.css('marginLeft'),10)+jQuery(window).scrollLeft()})}})}; -------------------------------------------------------------------------------- /Lib/jQuery/jquery.contextMenu.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery contextMenu - Plugin for simple contextMenu handling 3 | * 4 | * Version: git-master 5 | * 6 | * Authors: Rodney Rehm, Addy Osmani (patches for FF) 7 | * Web: http://medialize.github.com/jQuery-contextMenu/ 8 | * 9 | * Licensed under 10 | * MIT License http://www.opensource.org/licenses/mit-license 11 | * GPL v3 http://opensource.org/licenses/GPL-3.0 12 | * 13 | */ 14 | 15 | .context-menu-list { 16 | margin:0; 17 | padding:0; 18 | 19 | min-width: 120px; 20 | max-width: 250px; 21 | display: inline-block; 22 | position: absolute; 23 | list-style-type: none; 24 | 25 | border: 1px solid #DDD; 26 | background: #EEE; 27 | 28 | 29 | 30 | font-family: Verdana, Arial, Helvetica, sans-serif; 31 | font-size: 11px; 32 | } 33 | 34 | .context-menu-item { 35 | padding: 2px 2px 2px 24px; 36 | background-color: #EEE; 37 | position: relative; 38 | -webkit-user-select: none; 39 | -moz-user-select: -moz-none; 40 | -ms-user-select: none; 41 | user-select: none; 42 | } 43 | 44 | .context-menu-separator { 45 | padding-bottom:0; 46 | border-bottom: 1px solid #DDD; 47 | } 48 | 49 | .context-menu-item > label > input, 50 | .context-menu-item > label > textarea { 51 | -webkit-user-select: text; 52 | -moz-user-select: text; 53 | -ms-user-select: text; 54 | user-select: text; 55 | } 56 | 57 | .context-menu-item.hover { 58 | cursor: pointer; 59 | background-color: #DEE1E2; 60 | } 61 | 62 | .context-menu-item.disabled { 63 | color: #666; 64 | } 65 | 66 | .context-menu-input.hover, 67 | .context-menu-item.disabled.hover { 68 | cursor: default; 69 | background-color: #EEE; 70 | } 71 | 72 | .context-menu-submenu:after { 73 | content: ">"; 74 | color: #666; 75 | position: absolute; 76 | top: 0; 77 | right: 3px; 78 | z-index: 1; 79 | } 80 | 81 | /* icons 82 | #protip: 83 | In case you want to use sprites for icons (which I would suggest you do) have a look at 84 | http://css-tricks.com/13224-pseudo-spriting/ to get an idea of how to implement 85 | .context-menu-item.icon:before {} 86 | */ 87 | .context-menu-item.icon { min-height: 18px; background-repeat: no-repeat; background-position: 4px 2px; } 88 | .context-menu-item.icon-edit { background-image: url(images/page_white_edit.png); } 89 | .context-menu-item.icon-cut { background-image: url(images/cut.png); } 90 | .context-menu-item.icon-copy { background-image: url(images/page_white_copy.png); } 91 | .context-menu-item.icon-paste { background-image: url(images/page_white_paste.png); } 92 | .context-menu-item.icon-delete { background-image: url(images/page_white_delete.png); } 93 | .context-menu-item.icon-add { background-image: url(images/page_white_add.png); } 94 | .context-menu-item.icon-quit { background-image: url(images/door.png); } 95 | 96 | /* vertically align inside labels */ 97 | .context-menu-input > label > * { vertical-align: top; } 98 | 99 | /* position checkboxes and radios as icons */ 100 | .context-menu-input > label > input[type="checkbox"], 101 | .context-menu-input > label > input[type="radio"] { 102 | margin-left: -17px; 103 | } 104 | .context-menu-input > label > span { 105 | margin-left: 5px; 106 | } 107 | 108 | .context-menu-input > label, 109 | .context-menu-input > label > input[type="text"], 110 | .context-menu-input > label > textarea, 111 | .context-menu-input > label > select { 112 | display: block; 113 | width: 100%; 114 | 115 | -webkit-box-sizing: border-box; 116 | -moz-box-sizing: border-box; 117 | -ms-box-sizing: border-box; 118 | -o-box-sizing: border-box; 119 | box-sizing: border-box; 120 | } 121 | 122 | .context-menu-input > label > textarea { 123 | height: 100px; 124 | } 125 | .context-menu-item > .context-menu-list { 126 | display: none; 127 | /* re-positioned by js */ 128 | right: -5px; 129 | top: 5px; 130 | } 131 | 132 | .context-menu-item.hover > .context-menu-list { 133 | display: block; 134 | } 135 | 136 | .context-menu-accesskey { 137 | text-decoration: underline; 138 | } 139 | -------------------------------------------------------------------------------- /Lib/jQuery/spin.min.js: -------------------------------------------------------------------------------- 1 | //fgnass.github.com/spin.js#v2.0.1 2 | !function(a,b){"object"==typeof exports?module.exports=b():"function"==typeof define&&define.amd?define(b):a.Spinner=b()}(this,function(){"use strict";function a(a,b){var c,d=document.createElement(a||"div");for(c in b)d[c]=b[c];return d}function b(a){for(var b=1,c=arguments.length;c>b;b++)a.appendChild(arguments[b]);return a}function c(a,b,c,d){var e=["opacity",b,~~(100*a),c,d].join("-"),f=.01+c/d*100,g=Math.max(1-(1-a)/b*(100-f),a),h=j.substring(0,j.indexOf("Animation")).toLowerCase(),i=h&&"-"+h+"-"||"";return l[e]||(m.insertRule("@"+i+"keyframes "+e+"{0%{opacity:"+g+"}"+f+"%{opacity:"+a+"}"+(f+.01)+"%{opacity:1}"+(f+b)%100+"%{opacity:"+a+"}100%{opacity:"+g+"}}",m.cssRules.length),l[e]=1),e}function d(a,b){var c,d,e=a.style;for(b=b.charAt(0).toUpperCase()+b.slice(1),d=0;d',c)}m.addRule(".spin-vml","behavior:url(#default#VML)"),h.prototype.lines=function(a,d){function f(){return e(c("group",{coordsize:k+" "+k,coordorigin:-j+" "+-j}),{width:k,height:k})}function h(a,h,i){b(m,b(e(f(),{rotation:360/d.lines*a+"deg",left:~~h}),b(e(c("roundrect",{arcsize:d.corners}),{width:j,height:d.width,left:d.radius,top:-d.width>>1,filter:i}),c("fill",{color:g(d.color,a),opacity:d.opacity}),c("stroke",{opacity:0}))))}var i,j=d.length+d.width,k=2*j,l=2*-(d.width+d.length)+"px",m=e(f(),{position:"absolute",top:l,left:l});if(d.shadow)for(i=1;i<=d.lines;i++)h(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=d.lines;i++)h(i);return b(a,m)},h.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d>1)+"px"})}for(var i,k=0,l=(f.lines-1)*(1-f.direction)/2;kb;b++)a.appendChild(arguments[b]);return a}function c(a,b,c,d){var e=["opacity",b,~~(100*a),c,d].join("-"),f=.01+c/d*100,g=Math.max(1-(1-a)/b*(100-f),a),h=j.substring(0,j.indexOf("Animation")).toLowerCase(),i=h&&"-"+h+"-"||"";return l[e]||(m.insertRule("@"+i+"keyframes "+e+"{0%{opacity:"+g+"}"+f+"%{opacity:"+a+"}"+(f+.01)+"%{opacity:1}"+(f+b)%100+"%{opacity:"+a+"}100%{opacity:"+g+"}}",m.cssRules.length),l[e]=1),e}function d(a,b){var c,d,e=a.style;for(b=b.charAt(0).toUpperCase()+b.slice(1),d=0;d',c)}m.addRule(".spin-vml","behavior:url(#default#VML)"),h.prototype.lines=function(a,d){function f(){return e(c("group",{coordsize:k+" "+k,coordorigin:-j+" "+-j}),{width:k,height:k})}function h(a,h,i){b(m,b(e(f(),{rotation:360/d.lines*a+"deg",left:~~h}),b(e(c("roundrect",{arcsize:d.corners}),{width:j,height:d.width,left:d.radius,top:-d.width>>1,filter:i}),c("fill",{color:g(d.color,a),opacity:d.opacity}),c("stroke",{opacity:0}))))}var i,j=d.length+d.width,k=2*j,l=2*-(d.width+d.length)+"px",m=e(f(),{position:"absolute",top:l,left:l});if(d.shadow)for(i=1;i<=d.lines;i++)h(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=d.lines;i++)h(i);return b(a,m)},h.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d>1)+"px"})}for(var i,k=0,l=(f.lines-1)*(1-f.direction)/2;k Please note: This branch is _only_ for developing purposes. This version is bleeding edge, instable, uncomplete and does not have all functions 9 | 10 | Redundancy is an lightweight cloud computing system. It is so lightweight that you can run it on microservers like the Raspberry Pi without having too much load. 11 | Redundancy does not require full server access. It can be installed on every server running a web server using PHP. The configuration is very easy through a central configuration file. At the moment it does not have a "bling bling" configuration wizard. The stable branch will probably get an installer and an installation wizard, too. The biggest difference between Redundancy and other programs for this purpose is that you get a very lightweight user 12 | experience. There are no unnecessary features you probably never use. Redundancy focuses on the core of the tasks to create an easy cloud, for example to use at home. 13 | 14 | Requirements 15 | ------------ 16 | 17 | for server: 18 | - PHP 5.6.x is required 19 | - PHP GD modules 20 | - PHP zip modules 21 | - cUrl enabled in PHP 22 | - MySQLi or equivalent 23 | 24 | for client: 25 | - JavaScript support 26 | 27 | License and components 28 | ---------------------- 29 | 30 | This information will be added when the branch is stable. 31 | -------------------------------------------------------------------------------- /Snapshots/.htaccess: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Snapshots/.htaccess -------------------------------------------------------------------------------- /Storage/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.htaccess 3 | !.gitignore -------------------------------------------------------------------------------- /Storage/.htaccess: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Storage/.htaccess -------------------------------------------------------------------------------- /System.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/System.log -------------------------------------------------------------------------------- /Temp/.htaccess: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/Temp/.htaccess -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | DoRequest('Kernel.UserKernel', 'GetUserSetting', json_encode(array("ui-user-scalable", $_SESSION["Token"]))); ?> 21 | Value == true) : ?> 22 | 23 | 24 | Value == false) : ?> 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Redundancy 68 | 69 | 70 | 71 |
72 |
73 | Route($_SERVER['REQUEST_URI']); ?> 74 |
75 |
76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /nys/Views/Changes.php: -------------------------------------------------------------------------------- 1 |

FileChanged;?>

2 |

FileChangesInfo;?>

3 |
4 | 5 | $value) :?> 6 |
7 |
8 |
9 |
    10 | $v): ?> 11 | DoRequest('Kernel.FileSystemKernel','GetAbsolutePathById',json_encode(array($v[4],$_SESSION['Token'])))); 15 | } 16 | else 17 | { 18 | $href = "?detail&f=".$v[5]; 19 | } 20 | echo ""; 21 | ?> 22 |
  • ">".$v[0]." - ";?> 23 | FileAddedInfo,$v[1]) : sprintf($GLOBALS["Language"]->FileChangedInfo,$v[1]) ;?> 24 |
  • 25 | 26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 | 34 |
FilesChangesNoFiles;?>
35 | -------------------------------------------------------------------------------- /nys/Views/Detail.php: -------------------------------------------------------------------------------- 1 |

2 | 3 | ' . $filenameParts[1] . ''; 5 | ?> 6 |

7 | 8 | ' . $mediaPreview . ''; 12 | } 13 | ?> 14 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
Size;?>SizeWithUnit; ?>
Source;?>UsedUserAgent,"Mozilla") !== false) ? $GLOBALS['Language']->Uploaded_Browser : $GLOBALS['Language']->Uploaded_API; ?>
FileUploaded;?>CreateDateTime; ?>
LastChangedFile;?> LastChangeDateTime; ?>
-------------------------------------------------------------------------------- /nys/Views/Info.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * @section LICENSE 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License as 10 | * published by the Free Software Foundation; either version 3 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details at 17 | * http://www.gnu.org/copyleft/gpl.html 18 | * 19 | * @section DESCRIPTION 20 | * 21 | * This file displays informations about the program 22 | */ 23 | //Include uri check 24 | ?> 25 | "; 29 | else 30 | echo ""; 31 | ?> 32 | 33 | 34 | 35 | 36 | 37 | 41 | 42 | 43 | 44 | 56 | 57 | 58 | 59 | DoRequest("Kernel","GetBranch",json_encode(array()));?> 60 | 61 | 62 |
VersionDoRequest("Kernel","GetShortenedVersion",json_encode(array())); 39 | $version = $router->DoRequest("Kernel","GetVersion",json_encode(array())); 40 | ?>
Status 45 | ".$GLOBALS["Language"]->EOL.""; 48 | else if (strpos($version,"beta") !== false) 49 | echo "".$GLOBALS["Language"]->Unstable.""; 50 | else if (strpos($version,"rc") !== false) 51 | echo "".$GLOBALS["Language"]->RC.""; 52 | else 53 | echo "".$GLOBALS["Language"]->Stable.""; 54 | ?> 55 |
Branch
63 | -------------------------------------------------------------------------------- /nys/Views/LogIn.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 11 | 14 | 15 |
16 |
17 |

Login

18 |
19 | 20 |
21 | 23 | Username;?>'> 24 |
25 |
26 | 28 | Password;?>'> 29 |
30 |
31 | 33 | 41 |
42 |
43 |
44 | 48 |
49 |
50 |
51 | 53 | 54 | 55 | Register;?> 56 | 57 | 58 |
59 |
60 |
61 | reset_pass;?> 62 |
63 |
64 |
65 |
66 |
67 |
68 | -------------------------------------------------------------------------------- /nys/Views/NewFolder.php: -------------------------------------------------------------------------------- 1 |

New_Directory." ". $absolutePathCurrentDirectory;?>

2 |
3 |
4 |
5 |
multiple_dirs; 7 | ?> 8 |
9 | 10 |
11 | New_Directory_Short;?>"> 12 |
13 |
14 |
15 |
16 | New_Directory_Button;?>"> 17 |
18 |
19 |
20 |
-------------------------------------------------------------------------------- /nys/Views/Partials/Banned.php: -------------------------------------------------------------------------------- 1 |

Banned

2 |
3 | Your IP has been blocked from this Redundancy Server. Contact the system administrator for unblocking. 4 |
5 | -------------------------------------------------------------------------------- /nys/Views/Partials/ErrorMessage.php: -------------------------------------------------------------------------------- 1 |
2 | {$ERROR})){ 7 | echo $GLOBALS["Language"]->{$ERROR}; 8 | } 9 | else{ 10 | echo $ERROR; 11 | } 12 | } 13 | else 14 | { 15 | echo "
    "; 16 | foreach($ERROR as $key=>$value){ 17 | if (isset($GLOBALS["Language"]->{$value})){ 18 | echo "
  • ".$GLOBALS["Language"]->{$value}."
  • "; 19 | } 20 | else{ 21 | echo "
  • $value
  • "; 22 | } 23 | } 24 | echo "
"; 25 | } 26 | ?> 27 |
-------------------------------------------------------------------------------- /nys/Views/Partials/Image.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * @section LICENSE 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License as 10 | * published by the Free Software Foundation; either version 3 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details at 17 | * http://www.gnu.org/copyleft/gpl.html 18 | * 19 | * @section DESCRIPTION 20 | * 21 | * the image display module is located in this file. 22 | */ 23 | //start a session if needed 24 | if (!isset($_SESSION)) 25 | session_start(); 26 | $filePath =$_SESSION["fileInject"]; 27 | displayImage($filePath); 28 | /** 29 | * create an image by a full path 30 | * @param $imagepath the path of the image 31 | */ 32 | function displayImage($imagepath) 33 | { 34 | //Display image if existing 35 | //supported are: jpeg,jpg,bmp,png (atm) 36 | if (file_exists($imagepath)){ 37 | $file = file_get_contents($imagepath); 38 | $finfo = new finfo(FILEINFO_MIME_TYPE); 39 | $mimetype = $finfo->buffer($file); 40 | header('Content-Type: ' .$mimetype); 41 | if ($mimetype == "image/jpeg"){ 42 | $im = imagecreatefromjpeg($imagepath); 43 | imagejpeg($im); 44 | imagedestroy($im); 45 | } 46 | if ($mimetype == "image/bmp"){ 47 | $im = imagecreatefromwbmp($imagepath); 48 | imagewbmp($im); 49 | imagedestroy($im); 50 | } 51 | if ($mimetype == "image/png"){ 52 | $im = imagecreatefrompng($imagepath); 53 | imagesavealpha ($im,true); 54 | imagepng($im); 55 | imagedestroy($im); 56 | } 57 | } 58 | unset($_SESSION["fileInject"]); 59 | $_SESSION["fileInject"] = ""; 60 | } 61 | ?> -------------------------------------------------------------------------------- /nys/Views/Partials/Message.php: -------------------------------------------------------------------------------- 1 |
2 | {$MESSAGE})){ 5 | echo $GLOBALS["Language"]->{$MESSAGE}; 6 | } 7 | else{ 8 | echo $MESSAGE; 9 | } 10 | else 11 | { 12 | echo "
    "; 13 | foreach($MESSAGE as $key=>$value){ 14 | if (isset($GLOBALS["Language"]->{$value})){ 15 | echo "
  • ".$GLOBALS["Language"]->{$value}."
  • "; 16 | } 17 | else{ 18 | echo "
  • $value
  • "; 19 | } 20 | } 21 | echo "
"; 22 | } 23 | ?> 24 |
-------------------------------------------------------------------------------- /nys/Views/Register.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 7 | 10 |
11 |
12 |

13 | Register;?>

14 |
15 |
16 | 18 | Name;?>'> 19 |
20 |
21 | 23 | Username;?>'> 24 |
25 |
26 | 28 | Email;?>'> 29 |
30 |
31 | 33 | Password;?>'> 34 |
35 |
36 | 38 | Repeat_Password;?>'> 39 |
40 |
41 | 43 | Abort;?> 44 |
45 |
46 |
47 |
48 |
49 |
50 | -------------------------------------------------------------------------------- /nys/Views/RequestPassword.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 7 | 11 | 14 |
15 |
16 |

17 | reset_pass;?>

18 |
19 |
20 | 22 | Email;?>'> 23 |
24 |
25 | 27 | Back;?> 28 |
29 |
30 |
31 |
32 |
33 |
34 | -------------------------------------------------------------------------------- /nys/Views/Reset.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 7 | 11 | 14 |
15 |
16 |

17 | reset_pass;?>

18 |
19 |
20 | 22 | Password;?>'> 23 |
24 |
25 | 27 | Repeat_Password;?>'> 28 |
29 |
30 | 32 | Back;?> 33 |
34 |
35 |
36 |
37 |
38 |
39 | -------------------------------------------------------------------------------- /nys/Views/Search.php: -------------------------------------------------------------------------------- 1 |

SearchResults;?> - SearchTerm,$_POST["Search"]);?>

2 | 3 |
DoRequest('Kernel.InterfaceKernel','GetErrorCodeTranslation',json_encode(array("R_ERR_".$results,$_SESSION["Language"]))); 7 | echo $error;?>
8 | 9 | 10 |
11 |
    12 | $v): ?> 13 | FilePath; 15 | if (is_null($path)){ 16 | $href = "?files&d=".($router->DoRequest('Kernel.FileSystemKernel','GetAbsolutePathById',json_encode(array($v->Id,$_SESSION['Token'])))); 17 | } 18 | else 19 | { 20 | $href = "?detail&f=".$v->Hash; 21 | } 22 | echo ""; 23 | ?> 24 |
  • 25 | ".$v->DisplayName."";?> 26 |
  • 27 | 28 | 29 |
30 |
31 | -------------------------------------------------------------------------------- /nys/Views/Settings.php: -------------------------------------------------------------------------------- 1 |

Account_Settings;?>

2 |
Account_Settings_Hint;?>
3 |
4 | 5 | $value) :?> 6 |
7 | 14 |
15 | Type == "Boolean") :?> 16 | Value == "true") ? "checked" : "";?>> 17 | 18 | Type == "Text") :?> 19 | 20 | 21 | Type == "Number") :?> 22 | 23 | 24 |
25 |
26 | 27 |
28 |
29 | 30 |
31 |
32 |
-------------------------------------------------------------------------------- /nys/Views/Share.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |

DisplayName; ?>

6 | DoRequest('Kernel.InterfaceKernel','GetErrorCodeTranslation',json_encode(array("R_ERR_".$mediaPreview,$_SESSION["Language"]))); 9 | echo '
'.$error."
"; 10 | unset($_SESSION["fileInject"]); 11 | } 12 | else 13 | echo $mediaPreview; 14 | ?> 15 | 22 |
23 | 24 |
25 | -------------------------------------------------------------------------------- /nys/Views/Shares.php: -------------------------------------------------------------------------------- 1 |

ShareMenu;?>

2 |
3 |

SharedByMe;?>

4 | 5 |
NothingShared;?>
6 | 7 | 10 |
    11 | $value): ?> 12 | Permissions) || $value->Permissions == "null"){ 17 | //The file is shared by link. 18 | $textForShare = sprintf($GLOBALS["Language"]->SharedByLink,$value->ShareCode,$value->SharedDateTime); 19 | } 20 | else{ 21 | 22 | $textForShare = sprintf($GLOBALS["Language"]->SharedToUser,$value->TargetUser->DisplayName,$value->SharedDateTime); 23 | } 24 | if (!is_null($value->Entry->FilePath)){ 25 | $href = "?detail&f=".$value->Entry->Hash; 26 | $displayName = $value->Entry->DisplayName;; 27 | } 28 | else{ 29 | $displayName = $value->Entry->DisplayName;//$GLOBALS['Router']->DoRequest('Kernel.FileSystemKernel','GetAbsolutePathById',json_encode(array($value->Entry->Id,$_SESSION['Token']))); 30 | $href = "?files&d=".$displayName; 31 | } 32 | ?> 33 |
  • - 34 | 35 | Permissions) || $value->Permissions == "null") :?> 36 | 37 | RemoveShare;?> 38 | 39 | NewCode;?> 40 | 41 | ShowShareLink;?> 42 |
  • 43 | 44 | 45 | Permissions) && $value->Permissions != "null") :?> 46 | 47 | RemoveShare;?> 48 | 49 | 50 | 51 |
52 |
53 |
54 |

SharedToMe;?>

55 |
    56 | $value): ?> 57 | DoRequest('Kernel.UserKernel','GetUserNameById',json_encode(array($value->UserID,$_SESSION['Token']))); 61 | $textForShare = sprintf($GLOBALS["Language"]->SharedToMeFromOthers,$fromUser->DisplayName,$value->SharedDateTime); 62 | $displayName = ""; 63 | if (!is_null($value->Entry->FilePath)){ 64 | $href = "?detail&f=".$value->Entry->Hash; 65 | $displayName = $value->Entry->DisplayName;; 66 | } 67 | else{ 68 | $displayName = $GLOBALS['Router']->DoRequest('Kernel.FileSystemKernel','GetAbsolutePathById',json_encode(array($value->Entry->Id,$_SESSION['Token']))); 69 | $href = "?files&d=".$displayName; 70 | } 71 | ?> 72 |
  • - 73 | 74 | Permissions) && $value->Permissions != "null") :?> 75 | 76 | AbortShareToMe;?> 77 |
  • 78 | 79 | 80 |
81 | 82 |
NothingShared;?>
83 | 84 |
85 | -------------------------------------------------------------------------------- /nys/Views/StartPage.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Startpage_Title;?>

4 |

Startpage_Title_Description;?>

5 |
6 |
7 |
8 |

Startpage_Wiki;?>

9 |

Startpage_Wiki_Description;?>

10 | 11 |

Startpage_Board;?>

12 |

Startpage_Board_Description;?>

13 |
14 | 15 |
16 | 17 |

Startpage_VersionInfo;?>

18 |

19 | 20 |

Startpage_Version;?>

21 |

Version_used,$version);?>

22 |
23 |
24 |

Files;?> -

25 |
26 |
27 |
28 |
-------------------------------------------------------------------------------- /nys/Views/Update.php: -------------------------------------------------------------------------------- 1 | 2 |

Update;?>

3 |
UpdateWarningLifeTime;?>
4 |
    5 |
  • 6 | 7 | UpdateSource;?> 8 |
  • 9 |
  • 10 | 11 | LocalVersion;?> 12 |
  • 13 |
  • 14 | 15 | RemoteVersion;?> 16 |
  • 17 |
  • "> 18 | UpdateNeeded : $GLOBALS["Language"]->AlreadyUpdated;?> 19 | 20 | UpdateStart;?> 21 | 22 |
  • 23 |
24 | 25 | 26 |

Updating,$remoteVersion);?>

27 | DoRequest('Kernel.UpdateKernel','Update',json_encode(array($_SESSION["Token"]))); 30 | ?> 31 | 32 |
Updated,$remoteVersion);?>
33 | 34 | 35 |
UpdateFailed;?>
36 | 37 | -------------------------------------------------------------------------------- /nys/Views/Upload.php: -------------------------------------------------------------------------------- 1 | '.$GLOBALS['Language']->Upload_Title.' '.$absolutePathCurrentDirectory.'.'; 3 | ?> 4 |
This view is only fallback. It will be removed in the next updates. Please drop files in the file view instead.
5 |
6 |
7 | 8 | 9 | 10 |
-------------------------------------------------------------------------------- /nys/Views/css/nys.css: -------------------------------------------------------------------------------- 1 | .infologo{ 2 | max-width: 20%; 3 | margin-right: 35%; 4 | margin-left: 35%; 5 | } 6 | .appname{ 7 | text-align: center; 8 | font-weight: 600; 9 | } 10 | .container{ 11 | padding-top: 20px; 12 | } 13 | .ui-dialog { 14 | position: absolute; 15 | top:50% !important; 16 | z-index:10000; 17 | } 18 | #spin { 19 | background: black; 20 | color: white; 21 | float: left; 22 | width: 200px; 23 | height: 200px; 24 | margin: 0 20px 20px 0; 25 | -webkit-border-radius: 10px; 26 | -moz-border-radius: 10px; 27 | border-radius: 10px; 28 | } 29 | .userbadge{ 30 | padding-right: 5px; 31 | } 32 | .ui-icon{ 33 | left: 50%; 34 | margin-left: -1px !important; 35 | margin-top: -1px !important; 36 | } 37 | .preview{ 38 | display: block; 39 | margin: auto; 40 | margin-bottom: 15px; 41 | width:100%; 42 | } 43 | .glyphicon{ 44 | padding-right:5px !important; 45 | } 46 | #spinner{ 47 | position: fixed; 48 | top: 30%; 49 | left: 54%; 50 | } 51 | .list-group-item a{ 52 | text-decoration: none; 53 | } 54 | .progress{ 55 | margin-left: 10px; 56 | padding: 3px; 57 | } 58 | .filelist li{ 59 | margin-top: 10px; 60 | } -------------------------------------------------------------------------------- /nys/Views/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/nys/Views/img/favicon.png -------------------------------------------------------------------------------- /nys/Views/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/nys/Views/img/logo.png -------------------------------------------------------------------------------- /nys/Views/img/logoWithText.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/nys/Views/img/logoWithText.png -------------------------------------------------------------------------------- /nys/Views/img/logoWithTextS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/nys/Views/img/logoWithTextS.png -------------------------------------------------------------------------------- /nys/Views/img/logoWithTextSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmllr/redundancy/125d851b6cebbf6cc06ae1e879bb811cb1fc8741/nys/Views/img/logoWithTextSmall.png -------------------------------------------------------------------------------- /nys/Views/js/Nys.Dialogs.js: -------------------------------------------------------------------------------- 1 | var nys; 2 | if (typeof nys === "undefined") 3 | nys = {}; 4 | 5 | ; 6 | (function() { 7 | function StartFolderDownload(entry, dialogTitle, dialogText) { 8 | var arguments = []; 9 | arguments.push(entry.Id); 10 | arguments.push(token); 11 | arguments.push(entry.Id); 12 | $.post('./Includes/api.inc.php', { 13 | module: 'Kernel.FileSystemKernel', 14 | method: 'StartZipCreation', 15 | args: arguments 16 | }) 17 | .done(function(data) { 18 | var dir = $.parseJSON(data); 19 | window.location.href = '?zipfolder&d=' + dir; 20 | }) 21 | .fail(function(e) { 22 | nys.ErrorDialog(e.responseText); 23 | }); 24 | } 25 | 26 | function StartSharingByLink(entry, dialogTitle, dialogText) { 27 | //,'ShareToUser',json_encode(array("/PerfTests/",84,$_SESSION['Token']))); 28 | var arguments = []; 29 | arguments.push(entry.Id); 30 | arguments.push(token); 31 | $.post('./Includes/api.inc.php', { 32 | module: 'Kernel.FileSystemKernel', 33 | method: 'GetAbsolutePathById', 34 | args: arguments 35 | }) 36 | .done(function(data) { 37 | ShareByLink($.parseJSON(data), dialogTitle, dialogText); 38 | }) 39 | .fail(function(e) { 40 | nys.ErrorDialog(e.responseText); 41 | }); 42 | } 43 | 44 | function ShareByLink(absolutepath, dialogTitle, dialogText) { 45 | var arguments = []; 46 | arguments.push(absolutepath); 47 | arguments.push(token); 48 | $.post('./Includes/api.inc.php', { 49 | module: 'Kernel.SharingKernel', 50 | method: 'ShareByCode', 51 | args: arguments 52 | }) 53 | .done(function(data) { 54 | var link = $.parseJSON(data); 55 | var code = window.location.origin + window.location.pathname + "?share&c=" + link; 56 | var text = dialogText.replace("%s", code); 57 | DisplayShareLink(text, dialogTitle); 58 | }) 59 | .fail(function(e) { 60 | nys.ErrorDialog(e.responseText); 61 | }); 62 | } 63 | 64 | function DisplayShareLink(text, dialogTitle) { 65 | $("

" + text + "

").dialog({ 66 | title: dialogTitle, 67 | width: 350, 68 | modal: true, 69 | draggable: false, 70 | buttons: { 71 | "OK": function() { 72 | $(this).dialog("close"); 73 | $(this).remove(); 74 | } 75 | } 76 | }); 77 | } 78 | 79 | nys.StartFolderDownload = StartFolderDownload; 80 | nys.StartSharingByLink = StartSharingByLink; 81 | nys.ShareByLink = ShareByLink; 82 | nys.DisplayShareLink = DisplayShareLink; 83 | }()); -------------------------------------------------------------------------------- /nys/Views/js/Nys.Helper.js: -------------------------------------------------------------------------------- 1 | var nys; 2 | if (typeof nys === "undefined") 3 | nys = {}; 4 | 5 | ; 6 | (function() { 7 | 8 | /** 9 | needed jquery extension... 10 | */ 11 | $.urlParam = function(name) { 12 | var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href); 13 | if (results == null) { 14 | return null; 15 | } else { 16 | return results[1] || 0; 17 | } 18 | } 19 | //https://stackoverflow.com/questions/881510/jquery-sorting-json-by-properties 20 | function sortJSON(data, key, way) { 21 | return data.sort(function(a, b) { 22 | var x = a[key]; 23 | var y = b[key]; 24 | if (way == 1) { 25 | return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 26 | } 27 | if (way == -1) { 28 | return ((x > y) ? -1 : ((x < y) ? 1 : 0)); 29 | } 30 | }); 31 | } 32 | 33 | function DisplaySpinner() { 34 | $(".entry").hide(); 35 | //Hide the spinner on small screens 36 | $("#spinner").addClass("hidden-xs"); 37 | var opts = { 38 | lines: 13, // The number of lines to draw 39 | length: 40, // The length of each line 40 | width: 10, // The line thickness 41 | radius: 60, // The radius of the inner circle 42 | corners: 0.8, // Corner roundness (0..1) 43 | rotate: 5, // The rotation offset 44 | direction: 1, // 1: clockwise, -1: counterclockwise 45 | color: '#000', // #rgb or #rrggbb or array of colors 46 | speed: 1, // Rounds per second 47 | trail: 100, // Afterglow percentage 48 | shadow: false, // Whether to render a shadow 49 | hwaccel: false, // Whether to use hardware acceleration 50 | className: 'spinner', // The CSS class to assign to the spinner 51 | zIndex: 2e9, // The z-index (defaults to 2000000000) 52 | // top: '50%', // Top position relative to parent 53 | // left: '50%' // Left position relative to parent 54 | }; 55 | var target = document.getElementById('spinner'); 56 | var spinner = new Spinner(opts).spin(target); 57 | } 58 | 59 | function HideSpinner() { 60 | var target = document.getElementById('spinner'); 61 | 62 | $(document).ready(function() { 63 | $("#spinner").html(""); 64 | $(".entry").fadeIn(); 65 | }); 66 | } 67 | 68 | nys.sortJSON = sortJSON; 69 | nys.DisplaySpinner = DisplaySpinner; 70 | nys.HideSpinner = HideSpinner; 71 | }()); -------------------------------------------------------------------------------- /runTests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ./tests/ 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test: -------------------------------------------------------------------------------- 1 | döner. -------------------------------------------------------------------------------- /tests/InterfaceKernelTest.php: -------------------------------------------------------------------------------- 1 | getMethod($name); 9 | $method->setAccessible(true); 10 | return $method; 11 | } 12 | //***********************Tests SplitFileNameAndExtension()*********************** 13 | public function testSplitFileNameAndExtension01(){ 14 | $got = $GLOBALS["Kernel"]->InterfaceKernel->SplitFileNameAndExtension("test.png"); 15 | $this->assertTrue($got[0] == "test"); 16 | $this->assertTrue($got[1] == ".png"); 17 | } 18 | public function testSplitFileNameAndExtension02(){ 19 | $got = $GLOBALS["Kernel"]->InterfaceKernel->SplitFileNameAndExtension("test"); 20 | $this->assertTrue($got[0] == "test"); 21 | $this->assertTrue($got[1] == ""); 22 | } 23 | public function testSplitFileNameAndExtension03(){ 24 | $got = $GLOBALS["Kernel"]->InterfaceKernel->SplitFileNameAndExtension("test..png"); 25 | $this->assertTrue($got[0] == "test."); 26 | $this->assertTrue($got[1] == ".png"); 27 | } 28 | public function testSplitFileNameAndExtension04(){ 29 | $got = $GLOBALS["Kernel"]->InterfaceKernel->SplitFileNameAndExtension("test.tar.gz"); 30 | $this->assertTrue($got[0] == "test.tar"); 31 | $this->assertTrue($got[1] == ".gz"); 32 | } 33 | public function testGetLanguageValue01(){ 34 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetLanguageValue("Translation_Author"); 35 | $this->assertTrue(!is_null($got)); 36 | } 37 | public function testGetGetAllLanguageValues01(){ 38 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetAllLanguageValues(); 39 | $this->assertTrue(count($got) != 0); 40 | } 41 | public function testGetCurrentLanguage01(){ 42 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetCurrentLanguage(); 43 | $expected = $GLOBALS["Kernel"]->SystemKernel->GetSetting("Program_Language")->Value; 44 | $this->assertTrue($got == $expected); 45 | } 46 | public function testSetCurrentLanguages01(){ 47 | $GLOBALS["Kernel"]->InterfaceKernel->SetCurrentLanguage("en"); 48 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetCurrentLanguage(); 49 | $GLOBALS["Kernel"]->InterfaceKernel->SetCurrentLanguage($GLOBALS["Kernel"]->SystemKernel->GetSetting("Program_Language")->Value); 50 | $this->assertTrue($got == "en"); 51 | } 52 | public function testGetInstalledLanguages() 53 | { 54 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetInstalledLanguages(); 55 | $this->assertTrue(count($got) == 3); 56 | } 57 | public function testGetEllipsedDisplayName01(){ 58 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetEllipsedDisplayName("thisishort.png"); 59 | $this->assertTrue($got[0] == "thisishort"); 60 | $this->assertTrue($got[1] == ".png"); 61 | } 62 | public function testGetEllipsedDisplayName02(){ 63 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetEllipsedDisplayName("thisisevenlongerthantheshortone.png"); 64 | $this->assertTrue(strlen($got[0]) == 23); 65 | $this->assertTrue($got[1] == ".png"); 66 | } 67 | public function testGetErrorTranslationCode01(){ 68 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetErrorCodeTranslation("R_ERR_DoesNotExist"); 69 | $this->assertTrue($got == "R_ERR_DoesNotExist"); 70 | } 71 | public function testGetErrorTranslationCode02(){ 72 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetErrorCodeTranslation("R_ERR_12"); 73 | $this->assertTrue($got != "R_ERR_12"); 74 | } 75 | public function testConstruct(){ 76 | $c = new \Redundancy\Kernel\InterfaceKernel(-1); 77 | } 78 | public function testGetReturnTo01(){ 79 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetReturnTo("/?login"); 80 | $this->assertTrue($got =="login"); 81 | } 82 | public function testGetReturnTo02(){ 83 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetReturnTo("/r2/index.php?files"); 84 | $this->assertTrue($got =="files"); 85 | } 86 | public function testGetReturnTo03(){ 87 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetReturnTo("/r2/index.php?files&d=/dir2/"); 88 | $this->assertTrue($got =="files&d=/dir2/"); 89 | } 90 | public function testGetReturnTo04(){ 91 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetReturnTo("/r2/index.php?"); 92 | $this->assertTrue($got =="main"); 93 | } 94 | public function testGetReturnTo05(){ 95 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetReturnTo("/r2/index.php"); 96 | $this->assertTrue($got =="main"); 97 | } 98 | public function testGetReturnTo06(){ 99 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetReturnTo(""); 100 | $this->assertTrue($got =="main"); 101 | } 102 | public function testGetReturnTo07(){ 103 | $got = $GLOBALS["Kernel"]->InterfaceKernel->GetReturnTo("/r2/index.php?files&d=/dir2/&x=y"); 104 | $this->assertTrue($got =="files&d=/dir2/&x=y"); 105 | } 106 | 107 | } 108 | ?> 109 | -------------------------------------------------------------------------------- /tests/ProgramKernelTest.php: -------------------------------------------------------------------------------- 1 | getMethod($name); 9 | $method->setAccessible(true); 10 | return $method; 11 | } 12 | public function testConstruct(){ 13 | $c = new \Redundancy\Kernel\Kernel(); 14 | } 15 | public function testGetVersion(){ 16 | $got = $GLOBALS["Kernel"]->GetVersion(); 17 | $this->assertTrue(!is_null($got)); 18 | } 19 | public function testGetShortenedVersion(){ 20 | $old = $GLOBALS["Kernel"]->GetVersion(); 21 | $GLOBALS["Kernel"]->Version = "1.2.3-testing-state-4"; 22 | $got = $GLOBALS["Kernel"]->GetShortenedVersion(); 23 | $this->assertTrue($got == "1.2.3.4"); 24 | $GLOBALS["Kernel"]->Version = $old; 25 | } 26 | public function testGetConfigValue(){ 27 | 28 | } 29 | public function testSetHTTPHeader01(){ 30 | $m = self::getMethod('SetHTTPHeader'); 31 | $got = $m->invokeArgs($GLOBALS["Kernel"], array(400)); 32 | $this->assertTrue($got == 400); 33 | } 34 | public function testSetHTTPHeader02(){ 35 | $m = self::getMethod('SetHTTPHeader'); 36 | $got = $m->invokeArgs($GLOBALS["Kernel"], array("sauerkraut")); 37 | $this->assertTrue($got == -1); 38 | } 39 | public function testIsJson01(){ 40 | $got = $GLOBALS["Kernel"]->isJson("['true']"); 41 | $this->assertTrue($got); 42 | } 43 | public function testGetAppName(){ 44 | $got = $GLOBALS["Kernel"]->GetAppName(); 45 | $this->assertTrue($got == "Redundancy"); 46 | } 47 | 48 | } 49 | ?> 50 | -------------------------------------------------------------------------------- /tests/UpdateKernelTest.php: -------------------------------------------------------------------------------- 1 | getMethod($name); 9 | $method->setAccessible(true); 10 | return $method; 11 | } 12 | //***********************Tests IsUpdateAvailable()*********************** 13 | public function testIsUpdateAvailable01(){ 14 | $remote = array( 15 | "major" => 1, 16 | "minor" => 9, 17 | "patch" => 15, 18 | "branch" =>"test", 19 | "stage" => "test", 20 | "update" => 0 21 | ); 22 | $local = array( 23 | "major" => 1, 24 | "minor" => 9, 25 | "patch" => 14, 26 | "branch" =>"test", 27 | "stage" => "test", 28 | "update" => 0 29 | ); 30 | $got = $GLOBALS["Kernel"]->UpdateKernel->IsUpdateAvailable($remote,$local); 31 | $this->assertTrue($got); 32 | } 33 | public function testIsUpdateAvailable02(){ 34 | $remote = array( 35 | "major" => 1, 36 | "minor" => 9, 37 | "patch" => 15, 38 | "branch" =>"test", 39 | "stage" => "test", 40 | "update" => 0 41 | ); 42 | $local = array( 43 | "major" => 1, 44 | "minor" => 8, 45 | "patch" => 15, 46 | "branch" =>"test", 47 | "stage" => "test", 48 | "update" => 0 49 | ); 50 | $got = $GLOBALS["Kernel"]->UpdateKernel->IsUpdateAvailable($remote,$local); 51 | $this->assertTrue($got); 52 | } 53 | public function testIsUpdateAvailable03(){ 54 | $remote = array( 55 | "major" => 0, 56 | "minor" => 9, 57 | "patch" => 15, 58 | "branch" =>"test", 59 | "stage" => "test", 60 | "update" => 0 61 | ); 62 | $local = array( 63 | "major" => 1, 64 | "minor" => 8, 65 | "patch" => 15, 66 | "branch" =>"test", 67 | "stage" => "test", 68 | "update" => 0 69 | ); 70 | $got = $GLOBALS["Kernel"]->UpdateKernel->IsUpdateAvailable($remote,$local); 71 | $this->assertTrue($got); 72 | } 73 | public function testIsUpdateAvailable04(){ 74 | $remote = array( 75 | "major" => 1, 76 | "minor" => 8, 77 | "patch" => 15, 78 | "branch" =>"test", 79 | "stage" => "test", 80 | "update" => 0 81 | ); 82 | $local = array( 83 | "major" => 1, 84 | "minor" => 8, 85 | "patch" => 15, 86 | "branch" =>"test", 87 | "stage" => "test", 88 | "update" => 0 89 | ); 90 | $got = $GLOBALS["Kernel"]->UpdateKernel->IsUpdateAvailable($remote,$local); 91 | $this->assertFalse($got); 92 | } 93 | public function testIsUpdateAvailable05(){ 94 | $remote = array( 95 | "major" => 1, 96 | "minor" => 9, 97 | "patch" => 15, 98 | "branch" =>"beta", 99 | "stage" => "1", 100 | "update" => 4 101 | ); 102 | $local = array( 103 | "major" => 1, 104 | "minor" => 9, 105 | "patch" => 14, 106 | "branch" =>"beta", 107 | "stage" => "2", 108 | "update" => 1 109 | ); 110 | $got = $GLOBALS["Kernel"]->UpdateKernel->IsUpdateAvailable($remote,$local); 111 | $this->assertTrue($got); 112 | } 113 | public function testGetVersion01(){ 114 | $got = $GLOBALS["Kernel"]->UpdateKernel->GetVersion(); 115 | $this->assertTrue(isset($got["major"]) && $got["major"] == 1); 116 | $this->assertTrue(isset($got["minor"]) && $got["minor"] == 10); 117 | $this->assertTrue(isset($got["patch"])); 118 | $this->assertTrue(isset($got["branch"]) && $got["branch"] == "Lenticularis"); 119 | } 120 | public function testGetBranch01(){ 121 | $got = $GLOBALS["Kernel"]->UpdateKernel->GetBranch(); 122 | $this->assertTrue($got == "Lenticularis"); 123 | } 124 | public function testGetLatestVersion01(){ 125 | $got = $GLOBALS["Kernel"]->UpdateKernel->GetLatestVersion(); 126 | $this->assertTrue($got != ""); //Well, we can't do a intelligent test here. 127 | } 128 | public function testGetLatestVersionAsString01(){ 129 | $got = $GLOBALS["Kernel"]->UpdateKernel->GetLatestVersion(); 130 | $this->assertTrue($got != ""); //Well, we can't do a intelligent test here. 131 | } 132 | public function testGetUpdateSource01(){ 133 | $got = $GLOBALS["Kernel"]->UpdateKernel->GetUpdateSource(); 134 | $this->assertTrue($got == "https://github.com/squarerootfury/redundancy/archive/Lenticularis.zip"); 135 | } 136 | } 137 | ?> 138 | -------------------------------------------------------------------------------- /webclient/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory" : "bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /webclient/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | -------------------------------------------------------------------------------- /webclient/.gitignore: -------------------------------------------------------------------------------- 1 | ############# 2 | ## npm, grunt, bower, distribution folder 3 | ############# 4 | 5 | bower_components/ 6 | node_modules/ 7 | dist/ 8 | #index.html -------------------------------------------------------------------------------- /webclient/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": false, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "boss": true, 11 | "eqnull": true, 12 | "browser": true, 13 | "smarttabs": true, 14 | "globals": { 15 | "jQuery": true, 16 | "angular": true, 17 | "console": true, 18 | "$": true, 19 | "_": true, 20 | "moment": true, 21 | "describe": true, 22 | "beforeEach": true, 23 | "module": true, 24 | "inject": true, 25 | "it": true, 26 | "expect": true, 27 | "xdescribe": true, 28 | "xit": true, 29 | "spyOn": true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /webclient/.npmignore: -------------------------------------------------------------------------------- 1 | temp/ 2 | dist/ 3 | node_modules/ 4 | _SpecRunner.html 5 | .DS_Store 6 | test-results.xml -------------------------------------------------------------------------------- /webclient/.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-cg-angular": { 3 | "uirouter": true, 4 | "partialDirectory": "partial/", 5 | "directiveDirectory": "directive/", 6 | "filterDirectory": "filter/", 7 | "serviceDirectory": "service/", 8 | "inject": { 9 | "js": { 10 | "file": "index.html", 11 | "marker": "", 12 | "template": "" 13 | }, 14 | "less": { 15 | "relativeToModule": true, 16 | "file": "<%= module %>.less", 17 | "marker": "/* Add Component LESS Above */", 18 | "template": "@import \"<%= filename %>\";" 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /webclient/app_components/TODOs.txt: -------------------------------------------------------------------------------- 1 | -Password Repetition Validator funktioniert noch nicht -> fixen! 2 | 3 | -Andere CSS Klassen verwenden, dass bei der Eingabe im Login fehlerlose Felder nicht "rot unterstrichen" werden 4 | 5 | -Fehlerbehandlung bei Registrierung: Errorcodes müssen überprüft werden! 6 | 7 | -implement stayLoggedIn parameter Checkbox on login 8 | 9 | -use abstract controller to avoid memory leak (forgotten principal) -------------------------------------------------------------------------------- /webclient/app_components/app.js: -------------------------------------------------------------------------------- 1 | angular.module('redundancy', ['ui.router', 'ngMessages', 'pascalprecht.translate']); 2 | 3 | var run = function($rootScope, $state, $stateParams, authorization, principal) { 4 | /* $rootScope.safeApply = function(fn) { 5 | var phase = $rootScope.$$phase; 6 | if (phase === '$apply' || phase === '$digest') { 7 | if (fn && (typeof(fn) === 'function')) { 8 | fn(); 9 | } 10 | } else { 11 | this.$apply(fn); 12 | } 13 | };*/ 14 | 15 | $rootScope.$on('$stateChangeStart', function(event, toState, toStateParams) { 16 | $rootScope.toState = toState; 17 | $rootScope.toStateParams = toStateParams; 18 | 19 | // if (principal.isIdentityResolved()) 20 | authorization.authorize(); 21 | 22 | if (principal.isAuthenticated() && toState.name === 'login') 23 | $state.go('main.start'); 24 | }); 25 | }; 26 | 27 | angular.module('redundancy') 28 | .run(['$rootScope', '$state', '$stateParams', 'authorization', 'principal', run]); -------------------------------------------------------------------------------- /webclient/app_components/config.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var config = function($httpProvider, $stateProvider, $urlRouterProvider, $translateProvider) { 5 | 6 | $translateProvider.useStaticFilesLoader({ 7 | prefix: 'app_components/i18n/', 8 | suffix: '.json' 9 | }); 10 | 11 | $translateProvider.preferredLanguage('de'); 12 | //$translateProvider.useLocalStorage(); 13 | 14 | 15 | //code from: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/ 16 | //necessary to make angular requests work like jquery ajax requests 17 | // Use x-www-form-urlencoded Content-Type 18 | $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; 19 | 20 | /** 21 | * The workhorse; converts an object to x-www-form-urlencoded serialization. 22 | * @param {Object} obj 23 | * @return {String} 24 | */ 25 | var param = function(obj) { 26 | var query = '', 27 | name, value, fullSubName, subName, subValue, innerObj, i; 28 | 29 | for (name in obj) { 30 | value = obj[name]; 31 | 32 | if (value instanceof Array) { 33 | for (i = 0; i < value.length; ++i) { 34 | subValue = value[i]; 35 | fullSubName = name + '[' + i + ']'; 36 | innerObj = {}; 37 | innerObj[fullSubName] = subValue; 38 | query += param(innerObj) + '&'; 39 | } 40 | } else if (value instanceof Object) { 41 | for (subName in value) { 42 | subValue = value[subName]; 43 | fullSubName = name + '[' + subName + ']'; 44 | innerObj = {}; 45 | innerObj[fullSubName] = subValue; 46 | query += param(innerObj) + '&'; 47 | } 48 | } else if (value !== undefined && value !== null) 49 | query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; 50 | } 51 | 52 | return query.length ? query.substr(0, query.length - 1) : query; 53 | }; 54 | 55 | // Override $http service's default transformRequest 56 | $httpProvider.defaults.transformRequest = [ 57 | 58 | function(data) { 59 | return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data; 60 | } 61 | ]; 62 | 63 | //routing 64 | 65 | //for any unmatched url, redirect to /login 66 | $urlRouterProvider.otherwise('/login'); 67 | 68 | //register page 69 | var register = { 70 | url: '/register', 71 | controller: 'registerController as register', 72 | templateUrl: 'app_components/templates/register.html', 73 | data: { 74 | roles: [] 75 | } 76 | }, 77 | 78 | //login Page 79 | login = { 80 | url: '/login', 81 | controller: 'loginController as login', 82 | templateUrl: 'app_components/templates/login.html', 83 | data: { 84 | roles: [] 85 | } 86 | }, 87 | 88 | accessdenied = { 89 | url: '/accessdenied', 90 | template: 'ACCESS DENIED', 91 | data: { 92 | roles: [] 93 | } 94 | }, 95 | 96 | //abstract state for capsulating principal object 97 | main = { 98 | abstract: true, 99 | url: '/main', 100 | controller: 'mainController as main', 101 | templateUrl: 'app_components/templates/main.html', 102 | resolve: { 103 | authorize: ['authorization', 104 | function(authorization) { 105 | return authorization.authorize(); 106 | } 107 | ] 108 | }, 109 | data: { 110 | roles: ['user'] 111 | } 112 | }, 113 | 114 | mainStart = { 115 | url: '/start', 116 | controller: 'startController as start', 117 | templateUrl: 'app_components/templates/mainStart.html', 118 | data: { 119 | roles: ['user'] 120 | } 121 | }; 122 | 123 | $stateProvider 124 | .state('register', register) 125 | .state('login', login) 126 | .state('accessdenied', accessdenied) 127 | .state('main', main) 128 | .state('main.start', mainStart); 129 | }; 130 | 131 | angular.module('redundancy').config(config); 132 | }()); -------------------------------------------------------------------------------- /webclient/app_components/i18n/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "LOGIN_HEADING": "Login", 3 | "LOGINNAME_INPUT": "Benutzername", 4 | "PASSWORD_INPUT": "Passwort", 5 | "REGISTER_HINT": "Falls Du noch nicht registriert bist, klicke hier." 6 | } -------------------------------------------------------------------------------- /webclient/app_components/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "LOGIN_HEADING": "Login", 3 | "LOGINNAME_INPUT": "Username", 4 | "PASSWORD_INPUT": "Password", 5 | "REGISTER_HINT": "If you're not registered yet, click here." 6 | } -------------------------------------------------------------------------------- /webclient/app_components/login/login.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var loginController = function($scope, $log, user, principal, $state) { 5 | var vm = this; 6 | vm.principal = principal; 7 | vm.loginErrors = {}; 8 | 9 | vm.user = { 10 | loginName: vm.principal.loginName 11 | }; 12 | 13 | vm.login = function() { 14 | //TODO: implement stayLoggedIn parameter Checkbox 15 | login(vm.user.loginName, vm.user.password, true); 16 | }; 17 | 18 | var login = function(loginName, password, stayLoggedIn) { 19 | user.login(loginName, password, stayLoggedIn) 20 | .then(onLoginSuccess, onLoginError); 21 | }; 22 | 23 | var validateErrors = function(errorcode) { 24 | switch (errorcode) { 25 | case '7': 26 | vm.loginErrors.wrongPasswordOrLoginName = true; 27 | break; 28 | 29 | //if there are no errors, reset all errors 30 | default: 31 | for (var prop in vm.loginErrors) 32 | if (vm.loginErrors.hasOwnProperty(prop)) 33 | vm.loginErrors[prop] = false; 34 | } 35 | }; 36 | 37 | var onLoginSuccess = function(response) { 38 | var token = response.data.substring(1, response.data.length - 1); 39 | 40 | principal.authenticate({ 41 | loginName: vm.user.loginName, 42 | token: token, 43 | roles: ['user'] //FOR TESTS HARDCODED!!! 44 | }); 45 | /* 46 | principal.loginName = vm.user.loginName; 47 | principal.token = token;*/ 48 | console.log($scope.returnToState); 49 | 50 | //reset errors 51 | validateErrors(); 52 | 53 | if ($scope.returnToState) 54 | $state.go($scope.returnToState.name, $scope.returnToStateParams); 55 | else 56 | $state.go('main.start'); 57 | }; 58 | 59 | var onLoginError = function(response) { 60 | validateErrors(response.data); 61 | }; 62 | }; 63 | 64 | angular.module('redundancy') 65 | .controller('loginController', ['$scope', '$log', 'user', 'principal', '$state', loginController]); 66 | }()); -------------------------------------------------------------------------------- /webclient/app_components/main/main.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var mainController = function(principal, user, $state) { 5 | var vm = this; 6 | vm.principal = principal.getIdentity(); 7 | 8 | var getUser = function() { 9 | var token = vm.principal.token; 10 | user.getUser(token).success(onGetUserSuccess); 11 | }; 12 | 13 | var onGetUserSuccess = function(response) { 14 | console.log(response); 15 | vm.principal.displayName = response.DisplayName; 16 | }; 17 | 18 | vm.logout = function() { 19 | principal.authenticate(null); 20 | $state.go('login'); 21 | }; 22 | 23 | getUser(); 24 | }; 25 | 26 | angular.module('redundancy') 27 | .controller('mainController', ['principal', 'user', '$state', mainController]); 28 | }()); -------------------------------------------------------------------------------- /webclient/app_components/register/passwordRepetitionValidator.js: -------------------------------------------------------------------------------- 1 | //original code from: http://www.yearofmoo.com/2014/05/how-to-use-ngmessages-in-angularjs.html#angular-1-3-and-above 2 | (function() { 3 | 'use strict'; 4 | 5 | var directive = function(user) { 6 | return { 7 | require: 'ngModel', 8 | link: function(scope, element, attrs, ngModel) { 9 | var password = attrs.passwordRepetitionValidator; 10 | 11 | var setAsPasswordIsRepeated = function(bool) { 12 | ngModel.$setValidity('passwordIsRepeated', bool); 13 | }; 14 | 15 | ngModel.$parsers.push(function(value) { 16 | console.log(value); 17 | if (!value | value.length === 0) return; 18 | 19 | console.log(password); 20 | setAsPasswordIsRepeated(password === value); 21 | 22 | return value; 23 | }); 24 | } 25 | }; 26 | }; 27 | 28 | angular.module('redundancy').directive('passwordRepetitionValidator', directive); 29 | }()); -------------------------------------------------------------------------------- /webclient/app_components/register/register.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var registerController = function(user) { 5 | var vm = this; 6 | 7 | vm.register = function() { 8 | console.log(vm.user); 9 | user.registerUser(vm.user.loginName, vm.user.displayName, vm.user.mailAddress, vm.user.password) 10 | .success(onRegisterSuccess).error(onRegisterError); 11 | }; 12 | 13 | var onRegisterSuccess = function(response) { 14 | 15 | //Save principal for authentification 16 | vm.principal.displayName = response.DisplayName; 17 | vm.principal.loginName = response.LoginName; 18 | }; 19 | 20 | var onRegisterError = function(response) { 21 | console.log(response); 22 | }; 23 | 24 | vm.interacted = function(field) { 25 | return vm.submitted || field.$dirty; 26 | }; 27 | }; 28 | 29 | angular.module('redundancy') 30 | .controller('registerController', ['user', registerController]); 31 | }()); -------------------------------------------------------------------------------- /webclient/app_components/register/userNameOrMailAddressAvailabilityValidator.js: -------------------------------------------------------------------------------- 1 | //original code from: http://www.yearofmoo.com/2014/05/how-to-use-ngmessages-in-angularjs.html#angular-1-3-and-above 2 | (function() { 3 | var directive = function(user) { 4 | return { 5 | require: 'ngModel', 6 | link: function(scope, element, attrs, ngModel) { 7 | var setAsLoading = function(bool) { 8 | ngModel.$setValidity('usernameOrMailAddressLoading', !bool); 9 | }; 10 | var setAsAvailable = function(bool) { 11 | ngModel.$setValidity('usernameOrMailAddressAvailable', bool); 12 | }; 13 | 14 | ngModel.$parsers.push(function(value) { 15 | if (!value | value.length === 0) return; 16 | 17 | // setAsLoading(true); 18 | // setAsAvailable(false); 19 | 20 | var onCheckingError = function() { 21 | setAsLoading(false); 22 | setAsAvailable(false); 23 | }; 24 | 25 | var onCheckingSuccess = function(response) { 26 | if (response === 'true') { 27 | setAsLoading(false); 28 | setAsAvailable(true); 29 | } else 30 | onCheckingError(); 31 | }; 32 | 33 | user.isLoginOrMailFree(value).success(onCheckingSuccess).error(onCheckingError); 34 | return value; 35 | }); 36 | } 37 | }; 38 | }; 39 | 40 | angular.module('redundancy').directive('usernameOrMailAddressAvailabilityValidator', ['user', directive]); 41 | }()); -------------------------------------------------------------------------------- /webclient/app_components/services/authorization.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var authorization = function($rootScope, $state, principal) { 5 | return { 6 | authorize: function() { 7 | return principal.identity() 8 | .then(function() { 9 | var isAuthenticated = principal.isAuthenticated(); 10 | 11 | if ($rootScope.toState.data.roles && $rootScope.toState.data.roles.length > 0 && !principal.isInAnyRole($rootScope.toState.data.roles)) { 12 | if (isAuthenticated) $state.go('accessdenied'); // user is signed in but not authorized for desired state 13 | else { 14 | // user is not authenticated. show the state they wanted before you 15 | // send them to the signin state, so you can return them when you're done 16 | $rootScope.returnToState = $rootScope.toState; 17 | $rootScope.returnToStateParams = $rootScope.toStateParams; 18 | 19 | // now, send them to the signin state so they can log in 20 | $state.go('login'); 21 | } 22 | } 23 | }); 24 | } 25 | }; 26 | }; 27 | 28 | var app = angular.module('redundancy'); 29 | app.factory('authorization', ['$rootScope', '$state', 'principal', authorization]); 30 | }()); -------------------------------------------------------------------------------- /webclient/app_components/services/fileSystem.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var fileSystem = function($http) { 3 | var apiUrl = 'http://localhost/redundancy/Includes/api.inc.php'; 4 | var module = 'Kernel.FileSystemKernel'; 5 | 6 | var post = function(method, args, makeEmptyStrings) { 7 | var params = { 8 | module: module, 9 | method: method 10 | }; 11 | 12 | //arguments are optional 13 | if (args) { 14 | 15 | //if makeEmptyStrings is undefined or true 16 | //undefined fields will be defined as empty strings 17 | if (makeEmptyStrings || makeEmptyStrings === undefined) 18 | params.args = makeEmptyStringsInArray(args); 19 | else 20 | params.args = args; 21 | } 22 | return $http.post(apiUrl, params); 23 | }; 24 | 25 | var makeEmptyStringsInArray = function(arr) { 26 | for (var i = 0; i < arr.length; i++) 27 | if (arr[i] === undefined) 28 | arr[i] = ''; 29 | return arr; 30 | }; 31 | 32 | //API functions 33 | var getSystemDir = function(directory) { 34 | return post('GetSystemDir', [directory]); 35 | }; 36 | var createDirectory = function(name, root, token) { 37 | var args = [ 38 | name, 39 | root, 40 | token 41 | ]; 42 | return post('CreateDirectory', args); 43 | }; 44 | var getStorage = function(token) { 45 | return post('GetStorage', [token]); 46 | }; 47 | var isDisplayNameAllowed = function(displayName) { 48 | return post('IsDisplayNameAllowed', [displayName]); 49 | }; 50 | //TODO: $_FILES handling! 51 | var uploadFile = function(root, token) { 52 | var args = [ 53 | root, 54 | token 55 | ]; 56 | return post('UploadFile', args); 57 | }; 58 | var deleteDirectory = function(name, token) { 59 | var args = [ 60 | name, 61 | token 62 | ]; 63 | return post('DeleteDirectory', args); 64 | }; 65 | var deleteFile = function(absolutePath, token) { 66 | var args = [ 67 | absolutePath, 68 | token 69 | ]; 70 | return post('DeleteFile', args); 71 | }; 72 | var getContent = function(absolutePath, token) { 73 | var args = [ 74 | absolutePath, 75 | token 76 | ]; 77 | return post('GetContent', args); 78 | }; 79 | var refreshLastChangeDateTimeOfParent = function(entryID, token) { 80 | var args = [ 81 | entryID, 82 | token 83 | ]; 84 | return post('RefreshLastChangeDateTimeOfParent', args); 85 | }; 86 | var calculateFolderSize = function(absolutePath, token) { 87 | var args = [ 88 | absolutePath, 89 | token 90 | ]; 91 | return post('CalculateFolderSize', args); 92 | }; 93 | var moveEntry = function(oldAbsolutePath, newRoot, token) { 94 | var args = [ 95 | oldAbsolutePath, 96 | newRoot, 97 | token 98 | ]; 99 | return post('MoveEntry', args); 100 | }; 101 | var copyEntry = function(oldAbsolutePath, newRoot, token) { 102 | var args = [ 103 | oldAbsolutePath, 104 | newRoot, 105 | token 106 | ]; 107 | return post('CopyEntry', args); 108 | }; 109 | var getEntryByAbsolutePath = function(absolutePath, token) { 110 | var args = [ 111 | absolutePath, 112 | token 113 | ]; 114 | return post('GetEntryByAbsolutePath', args); 115 | }; 116 | var renameEntry = function(id, newName, token) { 117 | var args = [ 118 | id, 119 | newName, 120 | token 121 | ]; 122 | return post('RenameEntry', args); 123 | }; 124 | var isEntryExisting = function(name, root, token) { 125 | var args = [ 126 | name, 127 | root, 128 | token 129 | ]; 130 | return post('IsEntryExisting', args); 131 | }; 132 | var getEntryById = function(id, token) { 133 | var args = [ 134 | id, 135 | token 136 | ]; 137 | return post('GetEntryById', args); 138 | }; 139 | var getAbsolutePathbyId = function(id, token) { 140 | var args = [ 141 | id, 142 | token 143 | ]; 144 | return post('GetAbsolutePathById', args); 145 | }; 146 | //end API functions 147 | 148 | return { 149 | getSystemDir: getSystemDir, 150 | createDirectory: createDirectory, 151 | getStorage: getStorage, 152 | isDisplayNameAllowed: isDisplayNameAllowed, 153 | uploadFile: uploadFile, 154 | deleteDirectory: deleteDirectory, 155 | getContent: getContent, 156 | refreshLastChangeDateTimeOfParent: refreshLastChangeDateTimeOfParent, 157 | calculateFolderSize: calculateFolderSize, 158 | moveEntry: moveEntry, 159 | copyEntry: copyEntry, 160 | getEntryByAbsolutePath: getEntryByAbsolutePath, 161 | renameEntry: renameEntry, 162 | isEntryExisting: isEntryExisting, 163 | getEntryById: getEntryById, 164 | getAbsolutePathbyId: getAbsolutePathbyId, 165 | }; 166 | }; 167 | 168 | angular.module('redundancy').factory('fileSystem', ['$http', fileSystem]); 169 | }()); -------------------------------------------------------------------------------- /webclient/app_components/services/principal.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var principal = function(user, $q) { 5 | var _identity; 6 | var _authenticated = false; 7 | /* 8 | var data = { 9 | loginName: '', 10 | displayName: '', 11 | token: '', 12 | roles: '' 13 | };*/ 14 | 15 | var getIdentity = function() { 16 | return _identity; 17 | }; 18 | 19 | var isIdentityResolved = function() { 20 | return angular.isDefined(_identity); 21 | }; 22 | 23 | var isAuthenticated = function() { 24 | //return _authenticated; 25 | return _identity != null; 26 | }; 27 | 28 | var isInRole = function(role) { 29 | if (!_authenticated || !_identity.roles) 30 | return false; 31 | 32 | return _identity.roles.indexOf(role) > -1; 33 | }; 34 | 35 | var isInAnyRole = function(roles) { 36 | if (!_authenticated || !_identity.roles) 37 | return false; 38 | 39 | for (var i = 0; i < roles.length; i++) 40 | if (isInRole(roles[i])) 41 | return true; 42 | 43 | return false; 44 | }; 45 | 46 | var authenticate = function(identity) { 47 | _identity = identity; 48 | _authenticated = _identity != null; 49 | 50 | console.log(identity); 51 | 52 | if (identity) { 53 | localStorage.setItem('r2.identity', angular.toJson(identity)); 54 | } else { 55 | localStorage.removeItem('r2.identity'); 56 | console.log("storage cleared"); 57 | } 58 | }; 59 | 60 | var identity = function(identity) { 61 | var deferred = $q.defer(); 62 | 63 | _identity = angular.fromJson(localStorage.getItem('r2.identity')); 64 | authenticate(_identity); 65 | deferred.resolve(_identity); 66 | 67 | return deferred.promise; 68 | }; 69 | 70 | return { 71 | getIdentity: getIdentity, 72 | isIdentityResolved: isIdentityResolved, 73 | identity: identity, 74 | isAuthenticated: isAuthenticated, 75 | isInRole: isInRole, 76 | isInAnyRole: isInAnyRole, 77 | authenticate: authenticate 78 | }; 79 | }; 80 | 81 | var app = angular.module('redundancy'); 82 | app.factory('principal', ['user', '$q', principal]); 83 | }()); -------------------------------------------------------------------------------- /webclient/app_components/services/user.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var user = function($http) { 3 | var apiUrl = 'http://localhost/redundancy/Includes/api.inc.php'; 4 | var module = 'Kernel.UserKernel'; 5 | 6 | var post = function(method, args, makeEmptyStrings) { 7 | var params = { 8 | module: module, 9 | method: method 10 | }; 11 | 12 | //arguments are optional 13 | if (args) { 14 | 15 | //if makeEmptyStrings is undefined or true 16 | //undefined fields will be defined as empty strings 17 | if (makeEmptyStrings || makeEmptyStrings === undefined) 18 | params.args = makeEmptyStringsInArray(args); 19 | else 20 | params.args = args; 21 | } 22 | return $http.post(apiUrl, params); 23 | }; 24 | 25 | var makeEmptyStringsInArray = function(arr) { 26 | for (var i = 0; i < arr.length; i++) 27 | if (arr[i] === undefined) 28 | arr[i] = ''; 29 | return arr; 30 | }; 31 | 32 | //API functions 33 | var registerUser = function(loginName, displayName, mailAddress, password) { 34 | var args = [ 35 | loginName, 36 | displayName, 37 | mailAddress, 38 | password 39 | ]; 40 | return post('RegisterUser', args); 41 | }; 42 | 43 | var deleteUser = function(loginName, password) { 44 | var args = [ 45 | loginName, 46 | password 47 | ]; 48 | return post('DeleteUser', args); 49 | }; 50 | 51 | var changePassword = function(token, oldPassword, newPassword) { 52 | var args = [ 53 | token, 54 | oldPassword, 55 | newPassword 56 | ]; 57 | return post('ChangePassword', args); 58 | }; 59 | 60 | var generatePassword = function(length) { 61 | return post('GeneratePassword', [length]); 62 | }; 63 | 64 | var resetPasswordByMail = function(mailAddress) { 65 | return post('ResetPasswordByMail', [mailAddress]); 66 | }; 67 | 68 | var getInstalledRoles = function() { 69 | return post('GetInstalledRoles'); 70 | }; 71 | 72 | var getUser = function(token) { 73 | return post('GetUser', [token]); 74 | }; 75 | 76 | var authentificate = function(loginName, password) { 77 | var args = [ 78 | loginName, 79 | password 80 | ]; 81 | return post('Authentificate', args); 82 | }; 83 | 84 | var login = function(loginName, password, stayLoggedIn) { 85 | var args = [ 86 | loginName, 87 | password, 88 | stayLoggedIn 89 | ]; 90 | return post('LogIn', args); 91 | }; 92 | 93 | var getSessionByCookie = function() { 94 | return post('GetSessionByCookie'); 95 | }; 96 | 97 | var killSessionByToken = function(token) { 98 | return post('KillSessionByToken', [token]); 99 | }; 100 | 101 | var isSessionExisting = function(token) { 102 | return post('IsSessionExisting', [token]); 103 | }; 104 | 105 | var isLoginOrMailFree = function(value) { 106 | return post('IsLoginOrMailFree', [value]); 107 | }; 108 | //end API functions 109 | 110 | return { 111 | registerUser: registerUser, 112 | deleteUser: deleteUser, 113 | changePassword: changePassword, 114 | generatePassword: generatePassword, 115 | resetPasswordByMail: resetPasswordByMail, 116 | getInstalledRoles: getInstalledRoles, 117 | getUser: getUser, 118 | authentificate: authentificate, 119 | login: login, 120 | getSessionByCookie: getSessionByCookie, 121 | killSessionByToken: killSessionByToken, 122 | isSessionExisting: isSessionExisting, 123 | isLoginOrMailFree: isLoginOrMailFree 124 | }; 125 | }; 126 | 127 | angular.module('redundancy').factory('user', ['$http', user]); 128 | }()); -------------------------------------------------------------------------------- /webclient/app_components/start/start.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var startController = function() { 5 | var vm = this; 6 | }; 7 | 8 | angular.module('redundancy') 9 | .controller('startController', [startController]); 10 | }()); -------------------------------------------------------------------------------- /webclient/app_components/templates/error-messages.html: -------------------------------------------------------------------------------- 1 | 2 |
Dieses Feld muss ausgefüllt werden
3 |
Zu kurz
4 |
Zu lang
5 |
Das ist keine gültige E-Mailadresse
6 |
Passwort oder Benutzername ist falsch
-------------------------------------------------------------------------------- /webclient/app_components/templates/error-messages.jade: -------------------------------------------------------------------------------- 1 | div.panel-body(ng-message='required') Dieses Feld muss ausgefüllt werden 2 | div.panel-body(ng-message='minlength') Zu kurz 3 | div.panel-body(ng-message='maxlength') Zu lang 4 | div.panel-body(ng-message='email') Das ist keine gültige E-Mailadresse 5 | div.panel-body(ng-message='wrongPasswordOrLoginName') Passwort oder Benutzername ist falsch -------------------------------------------------------------------------------- /webclient/app_components/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |

{{ 'LOGIN_HEADING' | translate }}

6 |
7 |
8 | 9 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |

Falls Du noch nicht registriert bist, klicke hier.

17 |
18 |
19 |
-------------------------------------------------------------------------------- /webclient/app_components/templates/login.jade: -------------------------------------------------------------------------------- 1 | div.container 2 | div.row 3 | div.col-md-offset-3.col-md-6 4 | h1.white {{ 'LOGIN_HEADING' | translate }} 5 | form.form-inline(name='loginForm', ng-submit!='loginForm.$valid && login.login()') 6 | div.form-group 7 | input.form-control(type='text', name='loginName', ng-model='login.user.loginName', placeholder='Benutzername', required) 8 | div.form-group 9 | input.form-control(type='password', name='password', ng-model='login.user.password', placeholder='Passwort', required) 10 | button.btn.btn-default(type='submit') Anmelden 11 | 12 | //-error validation 13 | div.panel.panel-danger(ng-messages='login.loginErrors', ng-messages-include='app_components/templates/error-messages.html') 14 | p.white Falls Du noch nicht registriert bist, 15 | a(ui-sref='register') klicke hier. -------------------------------------------------------------------------------- /webclient/app_components/templates/main.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 35 |
36 |
37 | 38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
-------------------------------------------------------------------------------- /webclient/app_components/templates/main.jade: -------------------------------------------------------------------------------- 1 | #wrapper 2 | // Navigation 3 | nav.navbar.navbar-default.navbar-fixed-top(role='navigation') 4 | // Brand and toggle get grouped for better mobile display 5 | .navbar-header 6 | button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-ex1-collapse') 7 | span.sr-only Toggle navigation 8 | span.icon-bar 9 | span.icon-bar 10 | span.icon-bar 11 | a.navbar-brand(href='index.html') R² 12 | // Top Menu Items 13 | ul.nav.navbar-right.top-nav 14 | li.dropdown 15 | a.dropdown-toggle(href='', data-toggle='dropdown') 16 | i.fa.fa-user 17 | | {{ main.principal.displayName }} 18 | b.caret 19 | ul.dropdown-menu 20 | li 21 | a(href='#') 22 | i.fa.fa-fw.fa-user 23 | | Profile 24 | li 25 | a(href='#') 26 | i.fa.fa-fw.fa-envelope 27 | | Inbox 28 | li 29 | a(href='#') 30 | i.fa.fa-fw.fa-gear 31 | | Settings 32 | li.divider 33 | li 34 | a(ng-click='main.logout()') 35 | i.fa.fa-fw.fa-power-off 36 | | Log Out 37 | // Sidebar Menu Items - These collapse to the responsive navigation menu on small screens 38 | .collapse.navbar-collapse.navbar-ex1-collapse 39 | ul.nav.navbar-nav.side-nav 40 | li.active 41 | a(href='blank-page.html') 42 | i.fa.fa-fw.fa-file 43 | | Start 44 | li 45 | a(href='javascript:;', data-toggle='collapse', data-target='#demo') 46 | i.fa.fa-fw.fa-arrows-v 47 | | Dropdown 48 | i.fa.fa-fw.fa-caret-down 49 | ul#demo.collapse 50 | li 51 | a(href='#') Dropdown Item 52 | li 53 | a(href='#') Dropdown Item 54 | // /.navbar-collapse 55 | #page-wrapper 56 | .container-fluid 57 | // Page Heading 58 | .row 59 | .col-lg-12 60 | div(ui-view='') 61 | //- h1.page-header 62 | //- | Blank Page 63 | //- small Subheading 64 | //- ol.breadcrumb 65 | //- li 66 | //- i.fa.fa-dashboard 67 | //- a(href='index.html') Dashboard 68 | //- li.active 69 | //- i.fa.fa-file 70 | //- | Blank page -------------------------------------------------------------------------------- /webclient/app_components/templates/mainStart.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

Start

4 |

Herzlich Willkommen, {{ main.principal.displayName }}!

5 |
-------------------------------------------------------------------------------- /webclient/app_components/templates/mainStart.jade: -------------------------------------------------------------------------------- 1 | div 2 | h1 Start 3 | p Herzlich Willkommen, {{ main.principal.displayName }}! -------------------------------------------------------------------------------- /webclient/app_components/templates/register.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |

Registrieren

6 |
7 |
8 | 9 |
10 | 11 |
12 |
Name wird überprüft...
13 |
Dieser Name ist nicht mehr verfügbar
14 |
15 |
16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 |
41 | 42 |
43 |
44 |
45 |
46 | 47 |
48 |
49 |
50 |
51 |
52 |
-------------------------------------------------------------------------------- /webclient/app_components/templates/register.jade: -------------------------------------------------------------------------------- 1 | div.container 2 | div.row 3 | div.col-md-offset-3.col-md-6 4 | h1.white Registrieren 5 | form.form-horizontal(name='registerForm', ng-submit!='registerForm.$valid && register.register()') 6 | div.form-group 7 | label.col-sm-3.control-label.white Anmeldename: 8 | div.col-sm-9 9 | input.form-control(type='text', ng-model='register.user.loginName', name='loginName', placeholder='Benutzername', loginname-or-mail-address-availability-validator, required) 10 | 11 | //-error validation 12 | div.panel.panel-danger.ng-active(ng-if='interacted(registerForm.loginName)', ng-messages='registerForm.loginName.$error', ng-messages-include='app_components/templates/error-messages.html') 13 | div.panel-body(ng-message='loginnameOrMailAddressLoading') Name wird überprüft... 14 | div.panel-body(ng-message='loginnameOrMailAddressAvailable') Dieser Name ist nicht mehr verfügbar 15 | div.form-group 16 | label.col-sm-3.control-label.white Anzeigename: 17 | div.col-sm-9 18 | input.form-control(type='text', ng-model='register.user.displayName', name='displayName', placeholder='Anzeigename', required) 19 | 20 | //-error validation 21 | div.panel.panel-danger(ng-if='interacted(registerForm.displayName)', ng-messages='registerForm.displayName.$error', ng-messages-include='app_components/templates/error-messages.html') 22 | div.form-group 23 | label.col-sm-3.control-label.white E-Mail Adresse: 24 | div.col-sm-9 25 | input.form-control(type='email', ng-model='register.user.mailAddress', name='mailAddress', placeholder='E-Mail Adresse', user-name-or-mail-address-availability-validator, required) 26 | 27 | //-error validation 28 | div.panel.panel-danger(ng-if='interacted(registerForm.mailAddress)', ng-messages='registerForm.mailAddress.$error', ng-messages-include='app_components/templates/error-messages.html') 29 | div.form-group 30 | label.col-sm-3.control-label.white Passwort: 31 | div.col-sm-9 32 | input.form-control(type='password', ng-model='register.user.password', name='password', placeholder='Passwort', required) 33 | 34 | //-error validation 35 | div.panel.panel-danger(ng-if='interacted(registerForm.passwordRepetition)', ng-messages='registerForm.password.$error', ng-messages-include='app_components/templates/error-messages.html') 36 | div.form-group 37 | label.col-sm-3.control-label.white Passwort wiederholen: 38 | div.col-sm-9 39 | input.form-control(type='password', ng-model='register.user.passwordRepetition', name='passwordRepetition', placeholder='Passwort', required) 40 | //-TODO: password repetition fixen! input.form-control(type='password', ng-model='register.user.passwordRepetition', name='passwordRepetition', placeholder='Passwort', password-repetition-validator='{{register.user.password}}' required) 41 | 42 | //-error validation 43 | //-TODO: password repetition fixen! div.panel.panel-danger(ng-if='interacted(registerForm.passwordRepetition)', ng-messages='registerForm.passwordRepetition.$error', ng-messages-include='app_components/templates/error-messages.html') 44 | //-div.panel-body(ng-message='passwordIsRepeated') Passwörter stimmen nicht überein 45 | div.form-group 46 | div.col-sm-9.col-sm-offset-3 47 | button.btn.btn-primary(type='submit') Registrieren -------------------------------------------------------------------------------- /webclient/app_components/vendor/sb-admin/css/sb-admin.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Start Bootstrap - SB Admin Bootstrap Admin Template (http://startbootstrap.com) 3 | * Code licensed under the Apache License v2.0. 4 | * For details, see http://www.apache.org/licenses/LICENSE-2.0. 5 | */ 6 | 7 | /* Global Styles */ 8 | 9 | body { 10 | margin-top: 100px; 11 | background-color: #222; 12 | } 13 | 14 | @media(min-width:768px) { 15 | body { 16 | margin-top: 50px; 17 | } 18 | } 19 | 20 | #wrapper { 21 | padding-left: 0; 22 | } 23 | 24 | #page-wrapper { 25 | width: 100%; 26 | padding: 0; 27 | background-color: #fff; 28 | } 29 | 30 | .huge { 31 | font-size: 50px; 32 | line-height: normal; 33 | } 34 | 35 | @media(min-width:768px) { 36 | #wrapper { 37 | padding-left: 225px; 38 | } 39 | 40 | #page-wrapper { 41 | padding: 10px; 42 | } 43 | } 44 | 45 | /* Top Navigation */ 46 | 47 | .top-nav { 48 | padding: 0 15px; 49 | } 50 | 51 | .top-nav>li { 52 | display: inline-block; 53 | float: left; 54 | } 55 | 56 | .top-nav>li>a { 57 | padding-top: 15px; 58 | padding-bottom: 15px; 59 | line-height: 20px; 60 | color: #999; 61 | } 62 | 63 | .top-nav>li>a:hover, 64 | .top-nav>li>a:focus, 65 | .top-nav>.open>a, 66 | .top-nav>.open>a:hover, 67 | .top-nav>.open>a:focus { 68 | color: #fff; 69 | background-color: #000; 70 | } 71 | 72 | .top-nav>.open>.dropdown-menu { 73 | float: left; 74 | position: absolute; 75 | margin-top: 0; 76 | border: 1px solid rgba(0,0,0,.15); 77 | border-top-left-radius: 0; 78 | border-top-right-radius: 0; 79 | background-color: #fff; 80 | -webkit-box-shadow: 0 6px 12px rgba(0,0,0,.175); 81 | box-shadow: 0 6px 12px rgba(0,0,0,.175); 82 | } 83 | 84 | .top-nav>.open>.dropdown-menu>li>a { 85 | white-space: normal; 86 | } 87 | 88 | ul.message-dropdown { 89 | padding: 0; 90 | max-height: 250px; 91 | overflow-x: hidden; 92 | overflow-y: auto; 93 | } 94 | 95 | li.message-preview { 96 | width: 275px; 97 | border-bottom: 1px solid rgba(0,0,0,.15); 98 | } 99 | 100 | li.message-preview>a { 101 | padding-top: 15px; 102 | padding-bottom: 15px; 103 | } 104 | 105 | li.message-footer { 106 | margin: 5px 0; 107 | } 108 | 109 | ul.alert-dropdown { 110 | width: 200px; 111 | } 112 | 113 | /* Side Navigation */ 114 | 115 | @media(min-width:768px) { 116 | .side-nav { 117 | position: fixed; 118 | top: 51px; 119 | left: 225px; 120 | width: 225px; 121 | margin-left: -225px; 122 | border: none; 123 | border-radius: 0; 124 | overflow-y: auto; 125 | background-color: #222; 126 | } 127 | 128 | .side-nav>li>a { 129 | width: 225px; 130 | } 131 | 132 | .side-nav li a:hover, 133 | .side-nav li a:focus { 134 | outline: none; 135 | background-color: #000 !important; 136 | } 137 | } 138 | 139 | .side-nav>li>ul { 140 | padding: 0; 141 | } 142 | 143 | .side-nav>li>ul>li>a { 144 | display: block; 145 | padding: 10px 15px 10px 38px; 146 | text-decoration: none; 147 | color: #999; 148 | } 149 | 150 | .side-nav>li>ul>li>a:hover { 151 | color: #fff; 152 | } 153 | 154 | /* Flot Chart Containers */ 155 | 156 | .flot-chart { 157 | display: block; 158 | height: 400px; 159 | } 160 | 161 | .flot-chart-content { 162 | width: 100%; 163 | height: 100%; 164 | } 165 | 166 | /* Custom Colored Panels */ 167 | 168 | .huge { 169 | font-size: 40px; 170 | } 171 | 172 | .panel-green { 173 | border-color: #5cb85c; 174 | } 175 | 176 | .panel-green .panel-heading { 177 | border-color: #5cb85c; 178 | color: #fff; 179 | background-color: #5cb85c; 180 | } 181 | 182 | .panel-green a { 183 | color: #5cb85c; 184 | } 185 | 186 | .panel-green a:hover { 187 | color: #3d8b3d; 188 | } 189 | 190 | .panel-red { 191 | border-color: #d9534f; 192 | } 193 | 194 | .panel-red .panel-heading { 195 | border-color: #d9534f; 196 | color: #fff; 197 | background-color: #d9534f; 198 | } 199 | 200 | .panel-red a { 201 | color: #d9534f; 202 | } 203 | 204 | .panel-red a:hover { 205 | color: #b52b27; 206 | } 207 | 208 | .panel-yellow { 209 | border-color: #f0ad4e; 210 | } 211 | 212 | .panel-yellow .panel-heading { 213 | border-color: #f0ad4e; 214 | color: #fff; 215 | background-color: #f0ad4e; 216 | } 217 | 218 | .panel-yellow a { 219 | color: #f0ad4e; 220 | } 221 | 222 | .panel-yellow a:hover { 223 | color: #df8a13; 224 | } 225 | 226 | .white { 227 | color: white; 228 | } -------------------------------------------------------------------------------- /webclient/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redundancy", 3 | "version": "0.1.0", 4 | "main": "index.html", 5 | "ignore": [ 6 | "**/.*", 7 | "node_modules", 8 | "bower_components", 9 | "test", 10 | "tests" 11 | ], 12 | "dependencies": { 13 | "jquery": "~2.0", 14 | "bootstrap": "~3.2.0", 15 | "angular": "~1.3.0", 16 | "angular-ui-router": "~0.2", 17 | "angular-mocks": "~1.2", 18 | "font-awesome": "~4.0", 19 | "ng-messages": "*", 20 | "bootswatch": "~3.2.0", 21 | "angular-translate": "~2.2.0", 22 | "angular-translate-loader-static-files": "~2.2.0" 23 | }, 24 | "authors": [ 25 | "Phisherman " 26 | ], 27 | "license": "MIT", 28 | "private": true, 29 | "resolutions": { 30 | "angular": "~1.3.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /webclient/gulpfile.js: -------------------------------------------------------------------------------- 1 | //Experimental 2 | 3 | /*jslint node: true */ 4 | var gulp = require('gulp'); 5 | var concat = require('gulp-concat'); 6 | var uglify = require('gulp-uglify'); 7 | var imagemin = require('gulp-imagemin'); 8 | var less = require('gulp-less'); 9 | var gCheerio = require('gulp-cheerio'); 10 | var ngHtml2js = require("gulp-ng-html2js"); 11 | var ngmin = require('gulp-ngmin'); 12 | var htmlmin = require('gulp-htmlmin'); 13 | var cssmin = require('gulp-cssmin'); 14 | var packagejson = require('./package.json'); 15 | var streamqueue = require('streamqueue'); 16 | var rimraf = require('rimraf'); 17 | var rename = require('gulp-rename'); 18 | var jshint = require('gulp-jshint'); 19 | var jasmine = require('gulp-jasmine'); 20 | var stylish = require('jshint-stylish'); 21 | var domSrc = require('gulp-dom-src'); 22 | 23 | var htmlminOptions = { 24 | collapseBooleanAttributes: true, 25 | collapseWhitespace: true, 26 | removeAttributeQuotes: true, 27 | removeComments: true, 28 | removeEmptyAttributes: true, 29 | // removeRedundantAttributes: true, 30 | removeScriptTypeAttributes: true, 31 | removeStyleLinkTypeAttributes: true 32 | }; 33 | 34 | gulp.task('clean', function() { 35 | rimraf.sync('dist'); 36 | }); 37 | 38 | gulp.task('css', ['clean'], function() { 39 | return gulp.src('app.less') 40 | .pipe(less()) 41 | .pipe(cssmin({keepSpecialComments: 0})) 42 | .pipe(rename('app.full.min.css')) 43 | .pipe(gulp.dest('dist/')); 44 | }); 45 | 46 | gulp.task('js', ['clean'], function() { 47 | 48 | var templateStream = gulp.src(['!node_modules/**','!index.html','!_SpecRunner.html','!.grunt/**','!dist/**','!bower_components/**','**/*.html']) 49 | .pipe(htmlmin(htmlminOptions)) 50 | .pipe(ngHtml2js({ 51 | moduleName: packagejson.name 52 | })); 53 | 54 | var jsStream = domSrc({file:'index.html',selector:'script[data-build!="exclude"]',attribute:'src'}); 55 | 56 | var combined = streamqueue({ objectMode: true }); 57 | 58 | combined.queue(jsStream); 59 | combined.queue(templateStream); 60 | 61 | return combined.done() 62 | .pipe(concat('app.full.min.js')) 63 | .pipe(ngmin()) 64 | .pipe(uglify()) 65 | .pipe(gulp.dest('dist/')); 66 | 67 | 68 | /* 69 | Should be able to add to an existing stream easier, like: 70 | gulp.src([... partials html ...]) 71 | .pipe(htmlmin()) 72 | .pipe(ngHtml2js()) 73 | .pipe(domSrc(... js from script tags ...)) <-- add new files to existing stream 74 | .pipe(concat()) 75 | .pipe(ngmin()) 76 | .pipe(uglify()) 77 | .pipe(gulp.dest()); 78 | 79 | https://github.com/wearefractal/vinyl-fs/issues/9 80 | */ 81 | }); 82 | 83 | gulp.task('indexHtml', ['clean'], function() { 84 | return gulp.src('index.html') 85 | .pipe(gCheerio(function ($) { 86 | $('script[data-remove!="exclude"]').remove(); 87 | $('link').remove(); 88 | $('body').append(''); 89 | $('head').append(''); 90 | })) 91 | .pipe(htmlmin(htmlminOptions)) 92 | .pipe(gulp.dest('dist/')); 93 | }); 94 | 95 | gulp.task('images', ['clean'], function(){ 96 | return gulp.src('img/**') 97 | .pipe(imagemin()) 98 | .pipe(gulp.dest('dist/')); 99 | }); 100 | 101 | gulp.task('fonts', ['clean'], function(){ 102 | return gulp.src('bower_components/font-awesome/fonts/**') 103 | .pipe(gulp.dest('dist/bower_components/font-awesome/fonts/')); 104 | }); 105 | 106 | gulp.task('jshint', function(){ 107 | gulp.src(['!node_modules/**','!.grunt/**','!dist/**','!bower_components/**','**/*.js']) 108 | .pipe(jshint()) 109 | .pipe(jshint.reporter(stylish)); 110 | }); 111 | 112 | gulp.task('build', ['clean', 'css', 'js', 'indexHtml', 'images', 'fonts']); 113 | 114 | /* 115 | 116 | -specifying clean dependency on each task is ugly 117 | https://github.com/robrich/orchestrator/issues/26 118 | 119 | -gulp-jasmine needs a phantomjs option 120 | https://github.com/sindresorhus/gulp-jasmine/issues/2 121 | 122 | */ 123 | 124 | /* 125 | "gulp-dom-src": "~0.1.0", 126 | "gulp-concat": "~2.1.7", 127 | "gulp-uglify": "~0.2.1", 128 | "gulp-cssmin": "~0.1.3", 129 | "gulp-imagemin": "~0.1.5", 130 | "gulp-less": "~1.2.2", 131 | "gulp-cheerio": "~0.2.0", 132 | "gulp-rename": "~1.2.0", 133 | "gulp-ng-html2js": "~0.1.6", 134 | "gulp-ngmin": "~0.1.2", 135 | "gulp-htmlmin": "~0.1.2", 136 | "gulp-jshint": "~1.5.0", 137 | "gulp-jasmine": "~0.2.0", 138 | "jshint-stylish": "~0.1.5", 139 | "rimraf": "~2.2.6", 140 | "streamqueue": "0.0.5", 141 | "gulp": "~3.5.5" 142 | */ -------------------------------------------------------------------------------- /webclient/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
36 | -------------------------------------------------------------------------------- /webclient/index.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(ng-app='redundancy') 3 | head 4 | title 5 | meta(name='viewport', content='width=device-width, initial-scale=1.0') 6 | meta(charset='utf-8') 7 | link(href='bower_components/bootswatch/cosmo/bootstrap.min.css', rel='stylesheet') 8 | link(href='app_components/vendor/sb-admin/css/sb-admin.css', rel='stylesheet') 9 | body 10 | //Livereload script for development only (stripped during dist build) 11 | script(src='http://localhost:35729/livereload.js', data-concat='false') 12 | 13 | //JS from Bower Components 14 | script(src='bower_components/jquery/jquery.js') 15 | script(src='bower_components/bootstrap/dist/js/bootstrap.js') 16 | script(src='bower_components/angular/angular.js') 17 | script(src='bower_components/angular-ui-router/release/angular-ui-router.js') 18 | script(src='bower_components/ng-messages/angular-messages.js') 19 | script(src='bower_components/angular-translate/angular-translate.js') 20 | script(src='bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js') 21 | //Add New Bower Component JS Above 22 | 23 | //Main App JS 24 | script(src='app_components/app.js') 25 | script(src='app_components/config.js') 26 | script(src='app_components/services/user.js') 27 | script(src='app_components/services/principal.js') 28 | script(src='app_components/services/authorization.js') 29 | script(src='app_components/register/register.js') 30 | script(src='app_components/register/usernameOrMailAddressAvailabilityValidator.js') 31 | script(src='app_components/register/passwordRepetitionValidator.js') 32 | script(src='app_components/login/login.js') 33 | script(src='app_components/main/main.js') 34 | script(src='app_components/start/start.js') 35 | 36 | //Add New Component JS Above 37 | div(ui-view='') -------------------------------------------------------------------------------- /webclient/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redundancy", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "grunt": "~0.4", 6 | "grunt-dom-munger": "~3.4", 7 | "grunt-angular-templates": "~0.5", 8 | "grunt-ngmin": "0.0.3", 9 | "grunt-contrib-connect": "~0.6", 10 | "grunt-contrib-copy": "~0.5", 11 | "grunt-contrib-clean": "~0.5", 12 | "grunt-contrib-concat": "~0.3", 13 | "grunt-contrib-cssmin": "~0.7", 14 | "grunt-contrib-uglify": "~0.2", 15 | "grunt-contrib-jshint": "~0.9", 16 | "grunt-contrib-htmlmin": "~0.1", 17 | "grunt-contrib-imagemin": "~0.4", 18 | "grunt-contrib-less": "~0.8", 19 | "grunt-contrib-watch": "~0.6", 20 | "grunt-browser-output": "0.1.0", 21 | "load-grunt-tasks": "~0.2", 22 | "karma": "~0.12.6", 23 | "grunt-karma": "~0.8.3", 24 | "karma-jasmine": "~0.1.5", 25 | "karma-phantomjs-launcher": "~0.1.4", 26 | "karma-chrome-launcher": "~0.1.3", 27 | "karma-mocha-reporter": "~0.2.5", 28 | "karma-firefox-launcher": "~0.1.3", 29 | "grunt-contrib-jade": "^0.12.0" 30 | } 31 | } 32 | --------------------------------------------------------------------------------