From bcf29a3d4f6eb5c360e2e1b26ff4b463eaa5c7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1ndly=20Gerg=C5=91?= Date: Thu, 8 Aug 2019 16:40:15 +0300 Subject: [PATCH] Dump everything from SVN --- .gitignore | 1 + .htaccess | 3 + SignUp.zip | Bin 0 -> 106085 bytes SignUp.zip.sig | Bin 0 -> 566 bytes config/.htaccess | 2 + config/allowlogin.cnf | 1 + config/allowsignup.cnf | 1 + config/config.php | 148 +++++ config/cryptokey.cnf | 1 + config/db.sql | 89 +++ config/lang/hun.ini | 125 ++++ config/lib/defuse-crypto.phar | Bin 0 -> 61949 bytes config/lib/functions.php | 270 +++++++++ config/lib/loginManager/lmConfig.php | 82 +++ config/lib/loginManager/lmHandler.php | 14 + config/lib/loginManager/lmPassword.php | 14 + config/lib/loginManager/lmStates.php | 24 + config/lib/loginManager/lmTwoFactor.php | 14 + config/lib/loginManager/lmUtils.php | 44 ++ config/lib/loginManager/loginManager.php | 394 +++++++++++++ index.php | 194 ++++++ license.txt | 621 ++++++++++++++++++++ res/icon.png | Bin 0 -> 19419 bytes res/loading.gif | Bin 0 -> 14255 bytes script/footable/footable.min.js | 10 + script/footable/footable.standalone.min.css | 1 + script/script.js | 109 ++++ setup/.htaccess | 2 + setup/001-generateKey.php | 25 + setup/002-createAdmin.php | 39 ++ signupproj.geany | 67 +++ style.css | 191 ++++++ style_mobile.css | 221 +++++++ subs/.backend.php | 8 + subs/.htaccess | 2 + subs/.php | 14 + subs/admin.backend.php | 44 ++ subs/admin.php | 74 +++ subs/programs.backend.php | 299 ++++++++++ subs/programs.php | 245 ++++++++ subs/timetable.backend.php | 292 +++++++++ subs/timetable.php | 186 ++++++ subs/timetable_programs.backend.php | 13 + subs/timetable_programs.php | 78 +++ subs/users.backend.php | 144 +++++ subs/users.php | 99 ++++ 46 files changed, 4205 insertions(+) create mode 100644 .gitignore create mode 100644 .htaccess create mode 100644 SignUp.zip create mode 100644 SignUp.zip.sig create mode 100644 config/.htaccess create mode 100644 config/allowlogin.cnf create mode 100644 config/allowsignup.cnf create mode 100644 config/config.php create mode 100644 config/cryptokey.cnf create mode 100644 config/db.sql create mode 100644 config/lang/hun.ini create mode 100644 config/lib/defuse-crypto.phar create mode 100644 config/lib/functions.php create mode 100644 config/lib/loginManager/lmConfig.php create mode 100644 config/lib/loginManager/lmHandler.php create mode 100644 config/lib/loginManager/lmPassword.php create mode 100644 config/lib/loginManager/lmStates.php create mode 100644 config/lib/loginManager/lmTwoFactor.php create mode 100644 config/lib/loginManager/lmUtils.php create mode 100644 config/lib/loginManager/loginManager.php create mode 100644 index.php create mode 100644 license.txt create mode 100644 res/icon.png create mode 100644 res/loading.gif create mode 100644 script/footable/footable.min.js create mode 100644 script/footable/footable.standalone.min.css create mode 100644 script/script.js create mode 100644 setup/.htaccess create mode 100644 setup/001-generateKey.php create mode 100644 setup/002-createAdmin.php create mode 100644 signupproj.geany create mode 100644 style.css create mode 100644 style_mobile.css create mode 100644 subs/.backend.php create mode 100644 subs/.htaccess create mode 100644 subs/.php create mode 100644 subs/admin.backend.php create mode 100644 subs/admin.php create mode 100644 subs/programs.backend.php create mode 100644 subs/programs.php create mode 100644 subs/timetable.backend.php create mode 100644 subs/timetable.php create mode 100644 subs/timetable_programs.backend.php create mode 100644 subs/timetable_programs.php create mode 100644 subs/users.backend.php create mode 100644 subs/users.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2fa7ce7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.ini diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..bec493d --- /dev/null +++ b/.htaccess @@ -0,0 +1,3 @@ +RewriteEngine on +RewriteRule ^(config|res|script|setup)($|/) - [L] +RewriteRule ^([a-zA-Z_]+)(\/([a-zA-Z0-9_]))?$ index.php?view=$1 [L,QSA] diff --git a/SignUp.zip b/SignUp.zip new file mode 100644 index 0000000000000000000000000000000000000000..02fa56b35cf3fcbaaba27c4d4dca4adba99a8e9b GIT binary patch literal 106085 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 literal 0 HcmV?d00001 diff --git a/SignUp.zip.sig b/SignUp.zip.sig new file mode 100644 index 0000000000000000000000000000000000000000..f2f4886add1cda64717ef504a2ca5e65eced623f GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j-LOPO1!tsPIDO?zRncMK5~(fOwM@x01;Dz zRye%E4D&T^*Fwp%+A_e?msjP^ufaFdRA#2RiYG}GRYG%*DF3AbRy_d1a%+i^|ridg!oO9cX-mMvy=n@>hV)C0dwW-)enaol&?~5 zs$p(<`d%aE-8f#&&T4h52agz(dBf(f)sqMVr7?_=nWVDu6 z@#D|Zb>f~TBu_8s64t7OZ8E&s>G?V7jw`?xdobS~{pDHv zAC#`=s0gwdrdxV)&j5fGi$_h@;QXgj%d@gvTGNTOB2t84%QEYHmnoT2o&QI#8*0PJ zQzZrADPV(DfdsOJYjkC*Or&3j!cnJ<^z;@Fr6bNDUpVGI0z*x~*LI5}k>DkUAxC+4 zW2X5XUFc~taSb%c8HeE|Kc!Ce6eW^^yx*#Vj+lG~TYz0D*NB#@j(Pt0csgHnx!8D{ zB6rmBHU79lye$Ps3tF5Ten47*)`;E0dRr3t`51Zw7l*A!YCiZ_Su>6IKRqcj@E{B) E5PY}~hX4Qo literal 0 HcmV?d00001 diff --git a/config/.htaccess b/config/.htaccess new file mode 100644 index 0000000..281d5c3 --- /dev/null +++ b/config/.htaccess @@ -0,0 +1,2 @@ +order allow,deny +deny from all diff --git a/config/allowlogin.cnf b/config/allowlogin.cnf new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/config/allowlogin.cnf @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/config/allowsignup.cnf b/config/allowsignup.cnf new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/config/allowsignup.cnf @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000..07f0df8 --- /dev/null +++ b/config/config.php @@ -0,0 +1,148 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + ini_set("display_errors", true); +} + +/* + * Versioning + */ +const VERSION="2.0"; + +/* + * Set up loginManager + */ +//build needed classes +class handler implements lmHandler{ + public function handle($state, $target=0){ + global $db; + switch($state){ + case lmStates::LOGIN_FAILED: + functions::setError(1); + header("Location: ".explode("?", $_SERVER['REQUEST_URI'])[0]); + break; + case lmStates::LOGIN_OK: + $sql=$db->prepare("SELECT id, name, class, accesslevel, except_signup FROM users WHERE id=:id"); + $sql->execute(array(":id"=>$target)); + $res=$sql->fetch(PDO::FETCH_ASSOC); + $_SESSION['id']=$res['id']; + $_SESSION['name']=$res['name']; + $_SESSION['class']=$res['class']; + $_SESSION['accesslevel']=$res['accesslevel']; + $_SESSION['except_signup']=$res['except_signup']; + + header("Location: ".explode("?", $_SERVER['REQUEST_URI'])[0]); + break; + case lmStates::CAPTCHA_FAILED: + functions::setError(2); + header("Location: ".explode("?", $_SERVER['REQUEST_URI'])[0]); + break; + case lmStates::BANNED: + functions::setError(3); + header("Location: ".explode("?", $_SERVER['REQUEST_URI'])[0]); + break; + case lmStates::FORGET_DONE: + functions::setMessage(1); + header("Location: ".explode("?", $_SERVER['REQUEST_URI'])[0]); + break; + case lmStates::LOGOUT_DONE: + functions::setMessage(2); + header("Location: ".explode("?", $_SERVER['REQUEST_URI'])[0]); + break; + } + return; + } +} +class password implements lmPassword{ + public function verifyPassword($cleartext, $database){ + global $crypto; + + if($database==""){ + return false; + } + + if($cleartext==\Defuse\Crypto\Crypto::decrypt($database, $crypto)){ + return true; + } + else{ + return false; + } + } +} +class twoFactor implements lmTwoFactor{ + public function secondFactor($uid){ + global $config, $db; + $sql=$db->prepare("SELECT accesslevel, except_login FROM users WHERE id=:id"); + $sql->execute(array(":id"=>$uid)); + $res=$sql->fetch(PDO::FETCH_ASSOC); + if(($config['allowlogin']=="1" || $res['accesslevel']>0 || $res['except_login']==1) && $res['except_login']!=2){ + return true; + } + else{ + functions::setError(4); + header("Location: ./"); + die(); + return false; + } + } +} + +//build the class +$lm=new loginManager(new lmConfig($db, $config['login']['session_lifetime'], $config['login']['captcha_enable'], $config['login']['captcha_after'], $config['login']['captcha_sitekey'], $config['login']['captcha_secretkey'], $config['login']['ban_enable'], $config['login']['ban_after'], $config['login']['ban_time'], $config['login']['look'], $config['login']['remember_enable'], $config['login']['remember_time'], lmStates::AUTH_ID), new handler(), new password(), new twoFactor()); + +/* + * init LM + */ +$lm->init(); diff --git a/config/cryptokey.cnf b/config/cryptokey.cnf new file mode 100644 index 0000000..d775f63 --- /dev/null +++ b/config/cryptokey.cnf @@ -0,0 +1 @@ +def00000b0c6c796affdb1dbc89821e277b7ddcc88fd99669ab04984330c574c049eea27a3d54d40d1033d7c4ce9b500e04517ff27bcce47a57c54aaba85681404edc32a \ No newline at end of file diff --git a/config/db.sql b/config/db.sql new file mode 100644 index 0000000..423682f --- /dev/null +++ b/config/db.sql @@ -0,0 +1,89 @@ +/** + * /config/db.sql + * @version 1.0 + * @desc SQL set up file + * @author Fándly Gergő Zoltán + * @copy 2017 Fándly Gergő Zoltán + */ + +DROP TABLE IF EXISTS `users`, `login_history`, `login_bans`, `time_sequences`, `time_blocks`, `programs`, `registrations`, `registration_log`; + +CREATE TABLE `users`( + `id` int(4) UNSIGNED NOT NULL auto_increment, + `name` varchar(65) NOT NULL default '', + `class` varchar(10) NOT NULL default '', /* format: ddC (ex: 05D) */ + `accesslevel` tinyint(1) UNSIGNED NOT NULL default 0, /* 0:student; 1:head teacher; 2:manager; 3:administrator */ + `password` varchar(255) NOT NULL default '', + `except_login` tinyint(1) UNSIGNED NOT NULL default 0, /* 0:no change; 1:always allow login; 2:never allow login - only takes effect for students */ + `except_signup` tinyint(1) UNSIGNED NOT NULL default 0, /* 0:no change; 1:always allow sign up; 2:never allow sign up - only takes effect for students */ + PRIMARY KEY (`id`) +) CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE TABLE `login_history`( + `id` int(4) UNSIGNED NOT NULL auto_increment, + `user` int(4) UNSIGNED NOT NULL default 1, /* id of nouser */ + `date` timestamp NOT NULL default current_timestamp, + `ip` varchar(45) NOT NULL default '0.0.0.0', + `auth_token` varchar(65) NOT NULL default '', + `user_agent` varchar(500) NOT NULL default '', + `success` tinyint(1) NOT NULL default 0, + PRIMARY KEY (`id`), + FOREIGN KEY (`user`) REFERENCES users(`id`) ON DELETE CASCADE +) CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE TABLE `login_bans`( + `id` int(4) UNSIGNED NOT NULL auto_increment, + `ip` varchar(45) NOT NULL default '0.0.0.0', + `until` timestamp NOT NULL default current_timestamp, + PRIMARY KEY (`id`) +) CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE TABLE `time_sequences`( + `id` int(4) UNSIGNED NOT NULL auto_increment, + `name` varchar(65) NOT NULL default '', /* ex: monday, tuesday, 1st week, etc */ + `allow_signup` tinyint(1) UNSIGNED NOT NULL default 1, /* 0:forbid; 1:allow */ + PRIMARY KEY (`id`) +) CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE TABLE `time_blocks`( + `id` int(4) UNSIGNED NOT NULL auto_increment, + `name` varchar(65) NOT NULL default '', /* ex: 9-10, 8:00, etc */ + `sequence` int(4) UNSIGNED NOT NULL default 0, + PRIMARY KEY (`id`), + FOREIGN KEY (`sequence`) REFERENCES time_sequences(`id`) ON DELETE CASCADE +) CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE TABLE `programs`( + `id` int(4) UNSIGNED NOT NULL auto_increment, + `name` varchar(65) NOT NULL default '', + `description` text NOT NULL default '', /* as long, as wished! */ + `instructor` varchar(150) NOT NULL default '', + `location` varchar(150) NOT NULL default '', + `category` tinyint(1) UNSIGNED NOT NULL default 0, /* 0:0th class; 1:1-2th class; 2:3-4th class; 3:5-6th class; 4:7-8th class; 5:9-10th class 6:11-12th class; 10:0-4th class; 11:5-8th class; 12:9-12th class; 20:0-12th class */ + `time_block` int(4) UNSIGNED NOT NULL default 0, + `max_participants` int(4) UNSIGNED NOT NULL default 0, + PRIMARY KEY (`id`), + FOREIGN KEY (`time_block`) REFERENCES time_blocks(`id`) ON DELETE NO ACTION +) CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE TABLE `registrations`( + `id` int(4) UNSIGNED NOT NULL auto_increment, + `user` int(4) UNSIGNED NOT NULL default 0, + `program` int(4) UNSIGNED NOT NULL default 0, + PRIMARY KEY (`id`), + FOREIGN KEY (`user`) REFERENCES users(`id`) ON DELETE CASCADE, + FOREIGN KEY (`program`) REFERENCES programs(`id`) ON DELETE CASCADE +) CHARACTER SET utf8 COLLATE utf8_general_ci; + +CREATE TABLE `registration_log`( + `id` int(4) UNSIGNED NOT NULL auto_increment, + `user` int(4) UNSIGNED NOT NULL default 0, + `date` timestamp NOT NULL default current_timestamp, + `action` tinyint(1) UNSIGNED NOT NULL default 0, /* 0:unsibscribe; 1:subscribe; 10:admin deleted; 11:admin added */ + `program` int(4) UNSIGNED NOT NULL default 0, + PRIMARY KEY (`id`), + FOREIGN KEY (`user`) REFERENCES users(`id`) ON DELETE CASCADE, + FOREIGN KEY (`program`) REFERENCES programs(`id`) ON DELETE CASCADE +) CHARACTER SET utf8 COLLATE utf8_general_ci; + +INSERT INTO users (`id`, `name`) VALUES (1, 'nouser'); diff --git a/config/lang/hun.ini b/config/lang/hun.ini new file mode 100644 index 0000000..25ff1da --- /dev/null +++ b/config/lang/hun.ini @@ -0,0 +1,125 @@ +; /config/lang/hun.ini +; hungarian language file + +index="Kezdőlap" +programs="Programok" +timetable="Órarend" +timetable_programs="Órarend programok szerint" +studentcard="Ellenőrző" +users="Felhasználók" +admin="Adminisztrátori eszközök" +logout="Kijelentkezés" + +cookie_message="Oldalunk sütiket használ a megfelelő működés biztosításához." +cookie_dismiss="Elfogadom!" +login="Bejelentkezés" +id="Azonosító" +uid="Felhasználó azonosító" +password="Jelszó" +ok="Mehet!" +index_content="Ide kerül majd valami, ha minden igaz. Vagy lehet mégse." +name="Név" +class="Osztály" +programs_content="Programok listája" +description="Leírás" +instructor="Tanár" +category="Kategória" +timesequence="Nap" +timeblock="Időintervallum" +maxpart="Maximum résztvevők" +curpart="Résztvevők száma" +subscribe="Feliratkozás" +actions="Műveletek" +edit="Szerkesztés" +delete="Törlés" +qdelete="Biztosan le szeretné törölni ezt az adatelemet?" +unsubscribe="Leiratkozás" +qunsubscribe="Biztosan le szeretnél iratkozni erre a programról?" +new="Létrehozás" +newprogram="Új program létrehozása" +newtimesequence="Új nap hozzáadása" +newtimeblock="Új időblokk hozzáadása" +location="Helyszín" +editprogram="Program szerkesztése" +edittimesequence="Nap szerkesztése" +forceadd="Program manuális hozzáadása" +forceadddisc="Használat előtt kérem nézze meg, hogy az adott diáknak van e már programja arra az időpontra, ha igen, elősször törölje azt!" +pid="Program azonosító" +pleaseselect="Kérem válasszon!" +user="Diák" +program="Program" +export="Exportálás CSV-be" +notcomplete="Nem teljes feliratkozások" +progcount="Programok száma" +num="Sorszám" +print="Nyomtatás" +progname="Program neve" +signature="Aláírás" +studentprinted="Diák nyomtatta" +newuser="Új felhasználó létrehozása" +accesslevel="Jogszint" +except_login="Bejelentkezés kivételezés" +except_signup="Feliratkozás kivételezés" +qnewpassword="Adjon meg egy új jelszavat! random:" +newpassword="Új jelszó" +qexceptlogin="Bejelentkezési kivételezés. 0-alap beállítás, 1-mindig engedje belépni, 2-sose engedje belépni" +qexceptsignup="Feliratkozási kivételezés. 0-alap beállítás, 1-mindig engedje feliratkozni, 2-sose engedje feliratkozni" +newpassword4all="Új jelszó generálása minden diáknak és osztályfőnöknek" +resetall="Minden kivételezés visszaállítása alapértelmezettre" +allow_login="Bejelentkezés engedélyezése" +allow_signup="Feliratkozás engedélyezése" +positive="Igen" +negative="Nem" +current="Jelenleg" +allow_signup_timesequence="Feliratkozás engedélyezése" +toggle="Átállítás" +time_block_disclaimer="Kérem használja az ÓÓ:PP formátumot a megfelelő rendezés érdekében!" +orthis="vagy" +qproceed="Biztosan végre szeretné hajtani ezt a műveletet?" +masterswitch="Főkapcsolók" + + +;accesslevels +al[0]="Diák" +al[1]="Osztályfőnök" +al[2]="Manager" +al[3]="Adminisztrátor" + + +;categories +cat[100]="Rejtett" +cat[0]="0. osztály" +cat[1]="1-2. osztály" +cat[2]="3-4. osztály" +cat[3]="5-6. osztály" +cat[4]="7-8. osztály" +cat[5]="9-10. osztály" +cat[6]="11-12. osztály" +cat[10]="0-4. osztály" +cat[11]="5-8. osztály" +cat[12]="9-12. osztály" +cat[20]="0-12. osztály" + +;errors +error[1]="Hibás felhasználónév vagy jelszó! Ha elfelejtetted jelszavadat, keresd az osztályfőnöködet!" +error[2]="Hibásan töltötted ki a Captcha-t!" +error[3]="Az oldal ideiglenesen kitiltott a túl sok hibás bejelentkezési kísérlet miatt erről az IP címről" +error[4]="A bejelentkezés le van tiltva." +error[5]="Már létezik egy elem ezzel a névvel." +error[6]="A művelet nem lett sikeres. Kérem próbálja újra!" +error[7]="Nem található semmi a kért azonosítóval." +error[8]="Erre a programra már nincs több hely. Kérlek keress egy másikat!" +error[9]="Erre az időpontra már van egy programod. Válassz másikat, vagy iratkozz le az előbbiről!" +error[10]="Ez a program nem a te kategóriád számára van! Ide amúgy sem juthatsz el legálisan, szóval kérlek ne keress exploit-ot. Úgysem fogsz találni." +error[11]="A jelentkezés jelenleg nem engedélyezett!" +error[12]="A diáknak már van erre az időpontra egy programja. Előbb törölje azt!" +error[13]="A feliratkozás nem módosítható ennél a programnál." + +;messages +message[1]="Felhasználó elfelejtve!" +message[2]="Sikeresen kijelentkeztél!" +message[3]="Adat sikeresen hozzáadva!" +message[4]="Adat sikeresen törölve!" +message[5]="Sikeresen feliratkoztál a programra!" +message[6]="Sikeresen leiratkoztál a programról!" +message[7]="Művelet sikeresen végrehajtva!" diff --git a/config/lib/defuse-crypto.phar b/config/lib/defuse-crypto.phar new file mode 100644 index 0000000000000000000000000000000000000000..05e024cbbb5922ca7e7a0b2255db33d87bee9cef GIT binary patch literal 61949 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 literal 0 HcmV?d00001 diff --git a/config/lib/functions.php b/config/lib/functions.php new file mode 100644 index 0000000..c4e5793 --- /dev/null +++ b/config/lib/functions.php @@ -0,0 +1,270 @@ +,<"; + } + $charsetlength=strlen($charset); + $string=""; + for($i=0; $i<$length; $i++){ + $string=$string . $charset[rand(0, $charsetlength-1)]; + } + return $string; + } + + public static function get_string_between($string, $start, $end){ + $string=' ' . $string; + $ini=strpos($string, $start); + if($ini==0) return ''; + $ini+=strlen($start); + $len=strpos($string, $end, $ini) - $ini; + return substr($string, $ini, $len); + } + + public static function process_string($str, $dep){ + global $functions_accent_convert; + switch($dep){ + case 0: + { + return $str; + break; + } + case 1: + { + return strtolower($str); + break; + } + case 2: + { + return strtr($str, $functions_accent_convert); + break; + } + case 3: + { + return strtolower(strtr($str, $functions_accent_convert)); + break; + } + } + return 0; + } + + public static function validate_captcha($secretkey, $response){ + $verify=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secretkey."&response=".$response); + $data=json_decode($verify); + if($data->success){ + return true; + } + else{ + return false; + } + } +}; + +$functions_accent_convert=array( + // Decompositions for Latin-1 Supplement + chr(195).chr(128) => 'A', chr(195).chr(129) => 'A', + chr(195).chr(130) => 'A', chr(195).chr(131) => 'A', + chr(195).chr(132) => 'A', chr(195).chr(133) => 'A', + chr(195).chr(135) => 'C', chr(195).chr(136) => 'E', + chr(195).chr(137) => 'E', chr(195).chr(138) => 'E', + chr(195).chr(139) => 'E', chr(195).chr(140) => 'I', + chr(195).chr(141) => 'I', chr(195).chr(142) => 'I', + chr(195).chr(143) => 'I', chr(195).chr(145) => 'N', + chr(195).chr(146) => 'O', chr(195).chr(147) => 'O', + chr(195).chr(148) => 'O', chr(195).chr(149) => 'O', + chr(195).chr(150) => 'O', chr(195).chr(153) => 'U', + chr(195).chr(154) => 'U', chr(195).chr(155) => 'U', + chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y', + chr(195).chr(159) => 's', chr(195).chr(160) => 'a', + chr(195).chr(161) => 'a', chr(195).chr(162) => 'a', + chr(195).chr(163) => 'a', chr(195).chr(164) => 'a', + chr(195).chr(165) => 'a', chr(195).chr(167) => 'c', + chr(195).chr(168) => 'e', chr(195).chr(169) => 'e', + chr(195).chr(170) => 'e', chr(195).chr(171) => 'e', + chr(195).chr(172) => 'i', chr(195).chr(173) => 'i', + chr(195).chr(174) => 'i', chr(195).chr(175) => 'i', + chr(195).chr(177) => 'n', chr(195).chr(178) => 'o', + chr(195).chr(179) => 'o', chr(195).chr(180) => 'o', + chr(195).chr(181) => 'o', chr(195).chr(182) => 'o', + chr(195).chr(182) => 'o', chr(195).chr(185) => 'u', + chr(195).chr(186) => 'u', chr(195).chr(187) => 'u', + chr(195).chr(188) => 'u', chr(195).chr(189) => 'y', + chr(195).chr(191) => 'y', + // Decompositions for Latin Extended-A + chr(196).chr(128) => 'A', chr(196).chr(129) => 'a', + chr(196).chr(130) => 'A', chr(196).chr(131) => 'a', + chr(196).chr(132) => 'A', chr(196).chr(133) => 'a', + chr(196).chr(134) => 'C', chr(196).chr(135) => 'c', + chr(196).chr(136) => 'C', chr(196).chr(137) => 'c', + chr(196).chr(138) => 'C', chr(196).chr(139) => 'c', + chr(196).chr(140) => 'C', chr(196).chr(141) => 'c', + chr(196).chr(142) => 'D', chr(196).chr(143) => 'd', + chr(196).chr(144) => 'D', chr(196).chr(145) => 'd', + chr(196).chr(146) => 'E', chr(196).chr(147) => 'e', + chr(196).chr(148) => 'E', chr(196).chr(149) => 'e', + chr(196).chr(150) => 'E', chr(196).chr(151) => 'e', + chr(196).chr(152) => 'E', chr(196).chr(153) => 'e', + chr(196).chr(154) => 'E', chr(196).chr(155) => 'e', + chr(196).chr(156) => 'G', chr(196).chr(157) => 'g', + chr(196).chr(158) => 'G', chr(196).chr(159) => 'g', + chr(196).chr(160) => 'G', chr(196).chr(161) => 'g', + chr(196).chr(162) => 'G', chr(196).chr(163) => 'g', + chr(196).chr(164) => 'H', chr(196).chr(165) => 'h', + chr(196).chr(166) => 'H', chr(196).chr(167) => 'h', + chr(196).chr(168) => 'I', chr(196).chr(169) => 'i', + chr(196).chr(170) => 'I', chr(196).chr(171) => 'i', + chr(196).chr(172) => 'I', chr(196).chr(173) => 'i', + chr(196).chr(174) => 'I', chr(196).chr(175) => 'i', + chr(196).chr(176) => 'I', chr(196).chr(177) => 'i', + chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij', + chr(196).chr(180) => 'J', chr(196).chr(181) => 'j', + chr(196).chr(182) => 'K', chr(196).chr(183) => 'k', + chr(196).chr(184) => 'k', chr(196).chr(185) => 'L', + chr(196).chr(186) => 'l', chr(196).chr(187) => 'L', + chr(196).chr(188) => 'l', chr(196).chr(189) => 'L', + chr(196).chr(190) => 'l', chr(196).chr(191) => 'L', + chr(197).chr(128) => 'l', chr(197).chr(129) => 'L', + chr(197).chr(130) => 'l', chr(197).chr(131) => 'N', + chr(197).chr(132) => 'n', chr(197).chr(133) => 'N', + chr(197).chr(134) => 'n', chr(197).chr(135) => 'N', + chr(197).chr(136) => 'n', chr(197).chr(137) => 'N', + chr(197).chr(138) => 'n', chr(197).chr(139) => 'N', + chr(197).chr(140) => 'O', chr(197).chr(141) => 'o', + chr(197).chr(142) => 'O', chr(197).chr(143) => 'o', + chr(197).chr(144) => 'O', chr(197).chr(145) => 'o', + chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe', + chr(197).chr(148) => 'R',chr(197).chr(149) => 'r', + chr(197).chr(150) => 'R',chr(197).chr(151) => 'r', + chr(197).chr(152) => 'R',chr(197).chr(153) => 'r', + chr(197).chr(154) => 'S',chr(197).chr(155) => 's', + chr(197).chr(156) => 'S',chr(197).chr(157) => 's', + chr(197).chr(158) => 'S',chr(197).chr(159) => 's', + chr(197).chr(160) => 'S', chr(197).chr(161) => 's', + chr(197).chr(162) => 'T', chr(197).chr(163) => 't', + chr(197).chr(164) => 'T', chr(197).chr(165) => 't', + chr(197).chr(166) => 'T', chr(197).chr(167) => 't', + chr(197).chr(168) => 'U', chr(197).chr(169) => 'u', + chr(197).chr(170) => 'U', chr(197).chr(171) => 'u', + chr(197).chr(172) => 'U', chr(197).chr(173) => 'u', + chr(197).chr(174) => 'U', chr(197).chr(175) => 'u', + chr(197).chr(176) => 'U', chr(197).chr(177) => 'u', + chr(197).chr(178) => 'U', chr(197).chr(179) => 'u', + chr(197).chr(180) => 'W', chr(197).chr(181) => 'w', + chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y', + chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z', + chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z', + chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z', + chr(197).chr(190) => 'z', chr(197).chr(191) => 's'); + +?> diff --git a/config/lib/loginManager/lmConfig.php b/config/lib/loginManager/lmConfig.php new file mode 100644 index 0000000..d8f8f89 --- /dev/null +++ b/config/lib/loginManager/lmConfig.php @@ -0,0 +1,82 @@ +pdo=$_pdo; + $this->session_lifetime=$_session_lifetime; + $this->captcha_enable=$_captcha_enable; + $this->captcha_after=$_captcha_after; + $this->captcha_sitekey=$_captcha_sitekey; + $this->captcha_secretkey=$_captcha_secretkey; + $this->ban_enable=$_ban_enable; + $this->ban_after=$_ban_after; + $this->ban_time=$_ban_time; + $this->look=$_look; + $this->remember_enable=$_remember_enable; + $this->remember_time=$_remember_time; + $this->auth_type=$_auth_type; + } + + private $pdo; + private $session_lifetime; + private $captcha_enable; + private $captcha_after; + private $captcha_sitekey; + private $captcha_secretkey; + private $ban_enable; + private $ban_after; + private $ban_time; + private $look; + private $remember_enable; //NOT SAFE AT ALL!!! + private $remember_time; + private $auth_type; + + public function getPDO(){ + return $this->pdo; + } + public function getSessionLifetime(){ + return $this->session_lifetime; + } + public function isCaptchaEnabled(){ + return $this->captcha_enable; + } + public function getCaptchaAfter(){ + return $this->captcha_after; + } + public function getCaptchaSitekey(){ + return $this->captcha_sitekey; + } + public function getCaptchaSecretkey(){ + return $this->captcha_secretkey; + } + public function isBanEnabled(){ + return $this->ban_enable; + } + public function getBanAfter(){ + return $this->ban_after; + } + public function getBanTime(){ + return $this->ban_time; + } + public function getLook(){ + return $this->look; + } + public function isRememberEnabled(){ + return $this->remember_enable; + } + public function getRememberTime(){ + return $this->remember_time; + } + public function getAuthType(){ + return $this->auth_type; + } +} + +?> diff --git a/config/lib/loginManager/lmHandler.php b/config/lib/loginManager/lmHandler.php new file mode 100644 index 0000000..43fbf32 --- /dev/null +++ b/config/lib/loginManager/lmHandler.php @@ -0,0 +1,14 @@ + diff --git a/config/lib/loginManager/lmPassword.php b/config/lib/loginManager/lmPassword.php new file mode 100644 index 0000000..660e4e4 --- /dev/null +++ b/config/lib/loginManager/lmPassword.php @@ -0,0 +1,14 @@ + diff --git a/config/lib/loginManager/lmStates.php b/config/lib/loginManager/lmStates.php new file mode 100644 index 0000000..8c509c3 --- /dev/null +++ b/config/lib/loginManager/lmStates.php @@ -0,0 +1,24 @@ + diff --git a/config/lib/loginManager/lmTwoFactor.php b/config/lib/loginManager/lmTwoFactor.php new file mode 100644 index 0000000..749e58a --- /dev/null +++ b/config/lib/loginManager/lmTwoFactor.php @@ -0,0 +1,14 @@ + diff --git a/config/lib/loginManager/lmUtils.php b/config/lib/loginManager/lmUtils.php new file mode 100644 index 0000000..f841de5 --- /dev/null +++ b/config/lib/loginManager/lmUtils.php @@ -0,0 +1,44 @@ +,<"; + $charsetLength=strlen($charset); + $string=""; + for($i=0; $i<$length; $i++){ + $string.=$charset[rand(0, $charsetLength-1)]; + } + return $string; + } + + /** + * validate google ReCaptcha + * @param string $secretkey secret key to captcha API + * @param string $response response of API + * @return bool + */ + public static function validateCaptcha($secretkey, $response){ + $verify=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secretkey."&response=".$response); + $data=json_decode($verify); + if($data->success){ + return true; + } + else{ + return false; + } + } +} + +?> diff --git a/config/lib/loginManager/loginManager.php b/config/lib/loginManager/loginManager.php new file mode 100644 index 0000000..6851f27 --- /dev/null +++ b/config/lib/loginManager/loginManager.php @@ -0,0 +1,394 @@ + + * + */ + + +/* + * Includes + */ +require("lmStates.php"); +require("lmConfig.php"); +require("lmHandler.php"); +require("lmPassword.php"); +require("lmTwoFactor.php"); +require("lmUtils.php"); + + +/* + * Class + */ +class loginManager{ + //constructor + + /** + * building... + * @param lmConfig $_config configuration for login Manager + * @param lmHandler $_eventHandler handler of events + * @param lmPassword $_passwordEngine engine for verifying passwords + * @return void + */ + public function __construct($_config, $_eventHandler, $_passwordEngine, $_twoFactor){ + $this->config=$_config; + $this->eventHandler=$_eventHandler; + $this->passwordEngine=$_passwordEngine; + $this->twoFactor=$_twoFactor; + return; + } + + + + //settings + + private $config; + private $eventHandler; + private $passwordEngine; + private $twoFactor; + + + + //frontend functions + + /** + * initialize session and set its lifetime + * @return bool + */ + public function init(){ + session_set_cookie_params($this->config->getSessionLifetime()); + return session_start(); + } + + /** + * prepare for login. Run this on the top of your login page! + * @return void + */ + public function loginPrepare(){ + $this->passFailedAttempts(); + return; + } + + /** + * lets start here! + * @param int/string @identifier id or username of user + * @param string @password cleartext password from input + * @param bool $remember save user fot further use + * @return void + */ + public function login($identifier, $password, $remember=false){ + global $lm_force_captcha; + + if($this->passFailedAttempts()){ //not banned + if(isset($lm_force_captcha)){ //check captcha + if(!isset($_POST['g-recaptcha-response'])){ + $captcha_failed=true; + $this->addLoginHistory(lmStates::NOUSER, lmStates::LOGIN_FAILED); + $this->eventHandler->handle(lmStates::CAPTCHA_FAILED); + return; + } + else{ + if(!lmUtils::validateCaptcha($this->config->getCaptchaSecretkey(), $_POST['g-recaptcha-response'])){ + $captcha_failed=true; + $this->addLoginHistory(lmStates::NOUSER, lmStates::LOGIN_FAILED); + $this->eventHandler->handle(lmStates::CAPTCHA_FAILED); + return; + } + } + } + + if(!isset($captcha_failed)){ + if($this->config->isRememberEnabled()){ //check if remembering is enabled + if($this->isRememberingUser() && $this->twoFactor->secondFactor($this->isRememberingUser())){ //remembering. + $this->permitLogin($this->isRememberingUser()); //good to go! + return; + } + } + //proceed with normal login + if($this->config->getAuthType()==lmStates::AUTH_UNAME){ //username based authentication + $sql=$this->config->getPDO()->prepare("SELECT COUNT(id) AS count, id, password FROM users WHERE username=:identifier"); + } + else{ + $sql=$this->config->getPDO()->prepare("SELECT COUNT(id) AS count, id, password FROM users WHERE id=:identifier"); + } + $sql->execute(array(":identifier"=>$identifier)); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']==0){ //user not existing + $this->addLoginHistory(lmStates::NOUSER, lmStates::LOGIN_FAILED); + $this->eventHandler->handle(lmStates::LOGIN_FAILED); + return; + } + else{ + if($this->passwordEngine->verifyPassword($password, $res['password']) && $this->twoFactor->secondFactor($res['id'])){ + if($this->config->isRememberEnabled()){ //remember... if he wants to be insecure + if($remember){ + $this->rememberUser($res['id']); + } + } + $this->permitLogin($res['id']); //good to go! + return; + } + else{ + $this->addLoginHistory($res['id'], lmStates::LOGIN_FAILED); + $this->eventHandler->handle(lmStates::LOGIN_FAILED); + return; + } + } + } + } + return; + } + + /** + * finish it up! + * @return void + */ + public function logout(){ + $_SESSION=array(); + session_destroy(); + setcookie("lm_login_random", NULL, -1); + $this->eventHandler->handle(lmStates::LOGOUT_DONE); + return; + } + + /** + * just some formal checking + * @return bool + */ + public function validateLogin(){ + if(!isset($_SESSION['lm_id'])){ + return false; + } + else{ + $sql=$this->config->getPDO()->prepare("SELECT auth_token FROM login_history WHERE user=:id and success=1 ORDER BY id DESC LIMIT 1"); + $sql->execute(array(":id"=>$_SESSION['lm_id'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['auth_token']==$this->getSessionKey()){ + return true; + } + else{ + $this->addLoginHistory(lmStates::NOUSER, lmStates::LOGIN_FAILED); + return false; + } + } + } + + /** + * do i know you? + * @return int + */ + public function isRememberingUser(){ + if(!$this->config->isRememberEnabled()){ + return NULL; + } + + if(is_null($this->getRememberKey())){ + return NULL; + } + else{ + $sql=$this->config->getPDO()->prepare("SELECT COUNT(id) AS count, user FROM login_remember WHERE remember_token=:token and until>:until"); + $sql->execute(array(":token"=>$this->getRememberKey(), ":until"=>date("Y-m-d H:i:s"))); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']!=1){ + addLoginHistory(lmStates::NOUSER, lmStates::LOGIN_FAILED); + return NULL; + } + else{ + return $res['user']; + } + } + } + + /** + * i don't know you anymore! + * @return void + */ + public function forgetUser(){ + $sql=$this->config->getPDO()->prepare("UPDATE login_remember SET until=0 WHERE remember_token=:token"); + $sql->execute(array(":token"=>$this->getRememberKey())); + + setcookie("lm_login_remember", NULL, -1); + + $this->eventHandler->handle(lmStates::FORGET_DONE); + + return; + } + + /** + * print captcha html code if needed + * @param bool $dark use the dark theme, default false + * @return void + */ + public function printCaptcha($dark=false){ + if($this->config->isCaptchaEnabled()){ + global $lm_force_captcha; + if(isset($lm_force_captcha)){ + if($dark){ + echo "

config->getCaptchaSitekey()."\" data-theme=\"dark\">
"; + } + else{ + echo "
config->getCaptchaSitekey()."\">
"; + } + return; + } + else{ + return; + } + } + return; + } + + + + //backend functions + + protected function generateSessionKey(){ + $random=lmUtils::randomString(32); + setcookie("lm_login_random", $random, time()+$this->config->getSessionLifetime()); + $hash=hash("sha256", $_SERVER['REMOTE_ADDR']."***".$_SERVER['HTTP_USER_AGENT']."***".$random); + return $hash; + } + + protected function getSessionKey(){ + if(!isset($_COOKIE['lm_login_random'])){ + return NULL; + } + else{ + $hash=hash("sha256", $_SERVER['REMOTE_ADDR']."***".$_SERVER['HTTP_USER_AGENT']."***".$_COOKIE['lm_login_random']); + return $hash; + } + } + + protected function passFailedAttempts(){ + //check if no limitations are enabled + if(!$this->config->isCaptchaEnabled() && !$this->config->isBanEnabled()){ + return true; //nothing to do + } + + //check if is already banned + if($this->config->isBanEnabled()){ + $sql=$this->config->getPDO()->prepare("SELECT COUNT(id) AS count FROM login_bans WHERE id=:ip and until>:until"); + $sql->execute(array(":ip"=>$_SERVER['REMOTE_ADDR'], ":until"=>date("Y-m-d H:i:s"))); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']!=0){ + $this->eventHandler->handle(lmStates::BANNED); + return false; + } + } + + //count failed attempts + $sql=$this->config->getPDO()->prepare("SELECT COUNT(id) AS count FROM login_history WHERE ip=:ip and date>:date and success=0"); + $sql->execute(array(":ip"=>$_SERVER['REMOTE_ADDR'], ":date"=>date("Y-m-d H:i:s", time()-$this->config->getLook()))); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + //force captcha if case + if($res['count']>=$this->config->getCaptchaAfter() && $this->config->isCaptchaEnabled()){ + global $lm_force_captcha; + $lm_force_captcha=true; + } + + //bann if case + if($res['count']>=$this->config->getBanAfter() && $this->config->isBanEnabled()){ + $sql=$this->config->getPDO()->prepare("INSERT INTO login_bans (ip, until) VALUES (:ip, :until)"); + $sql->execute(array(":ip"=>$_SERVER['REMOTE_ADDR'], ":until"=>date("Y-m-d H:i:s", time()+$config->getBanTime()))); + global $lm_banned; + $lm_banned=true; + $this->eventHandler->handle(lmStates::BANNED); + return false; + } + + return true; + } + + protected function addLoginHistory($uid, $success=lmStates::LOGIN_FAILED, $token=""){ + $sql=$this->config->getPDO()->prepare("INSERT INTO login_history (user, date, ip, auth_token, user_agent, success) VALUES (:user, :date, :ip, :auth_token, :user_agent, :success)"); + $sql->execute(array(":user"=>$uid, ":date"=>date("Y-m-d H:i:s"), ":ip"=>$_SERVER['REMOTE_ADDR'], ":auth_token"=>$token, ":user_agent"=>$_SERVER['HTTP_USER_AGENT'], ":success"=>$success)); + return; + } + + protected function permitLogin($uid){ + $token=$this->generateSessionKey(); + $this->addLoginHistory($uid, lmStates::LOGIN_OK, $token); + + $_SESSION=array(); + $_SESSION['lm_id']=$uid; + + $this->eventHandler->handle(lmStates::LOGIN_OK, $uid); + + return; + } + + //functions for remembering + protected function generateRememberKey(){ + $random=lmUtils::randomString(32); + setcookie("lm_login_remember", $random, time()+(86000*$config->getRememberTime())); + $hash=hash("sha256", $_SERVER['REMOTE_ADDR']."***".$_SERVER['HTTP_USER_AGENT']."***".$random); + return $hash; + } + + protected function getRememberKey(){ + if(!isset($_COOKIE['lm_login_remember'])){ + return NULL; + } + else{ + $hash=hash("sha256", $_SERVER['REMOTE_ADDR']."***".$_SERVER['HTTP_USER_AGENT']."***".$random); + return $hash; + } + } + + protected function rememberUser($uid){ + $sql=$this->config->getPDO()->prepare("INSERT INTO login_remember (user, remember_token, until) VALUES (:user, :token, :until)"); + $sql->execute(array(":user"=>$uid, ":token"=>generateRememberKey(), ":until"=>date("Y-m-d H:i:s", time()+(86400*$config->getRememberTime())))); + return; + } +} diff --git a/index.php b/index.php new file mode 100644 index 0000000..2810b56 --- /dev/null +++ b/index.php @@ -0,0 +1,194 @@ +validateLogin()){ + if(isset($_POST['uname']) && isset($_POST['passwd'])){ + $lm->login($_POST['uname'], $_POST['passwd']); + } +} +else{ + if(isset($_GET['logout'])){ + $lm->logout(); + } + + if(isset($_GET['view'])){ + $view=$_GET['view']; + + if($view!="programs" && $view!="timetable" && $view!="timetable_programs" && $view!="users" && $view!="admin"){ + header("Location: ./"); + } + + if($view=="timetable_programs" && $_SESSION['accesslevel']<1){ + $view=""; + } + else if($view=="users" && $_SESSION['accesslevel']<2){ + $view=""; + } + else if($view=="admin" && $_SESSION['accesslevel']<3){ + $view=""; + } + } + else{ + $view=""; + } + + //include sub + include("subs/".$view.".backend.php"); + + //if just the backend was requested, stop here + if(isset($_GET['backend'])){ + //echo messages + echo "
"; + if(functions::isMessage()){ + foreach(functions::getMessageArray() as $m){ + echo "
"; + echo "

".$lang['message'][$m]."

"; + echo "
"; + } + echo "
"; + } + if(functions::isError()){ + foreach(functions::getErrorArray() as $m){ + echo "
"; + echo "

".$lang['error'][$m]."

"; + echo "
"; + } + echo "
"; + } + echo "
"; + + //clear messages + functions::clearError(); + functions::clearMessage(); + + //stop execution + die(); + } +} + +$oid=0; + +?> + + + + + <?php echo ($view==""?$lang['index']:$lang[$view])." :: ".$config['general']['title']." - ".$config['general']['org'] ?> + + + + + + + + + + + + + + + + + + + + + +

+
+
+
+ "; + echo "

".$lang['message'][$m]."

"; + echo "
"; + } + echo "
"; + } + if(functions::isError()){ + foreach(functions::getErrorArray() as $m){ + echo "
"; + echo "

".$lang['error'][$m]."

"; + echo "
"; + } + echo "
"; + } + ?> + + validateLogin()): ?> +
+
+
+
+ +
+ + + + + + + + + +
" required>
" required>
+
+ loginPrepare(); $lm->printCaptcha() ?> +
+ +
+
+
+
+
+ +
+
+

+
+ +
+ + + +
+ +
+
+ +
+

+

Powered by: SignUP
version:
Created by: Fándly Gergő
systemtest.tk

+
+ diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..810fce6 --- /dev/null +++ b/license.txt @@ -0,0 +1,621 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS diff --git a/res/icon.png b/res/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9977747c072053aedd8071ee3095ac6662039375 GIT binary patch literal 19419 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 literal 0 HcmV?d00001 diff --git a/script/footable/footable.min.js b/script/footable/footable.min.js new file mode 100644 index 0000000..131c887 --- /dev/null +++ b/script/footable/footable.min.js @@ -0,0 +1,10 @@ +/* +* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome. +* @version 3.1.4 +* @link http://fooplugins.com +* @copyright Steven Usher & Brad Vincent 2015 +* @license Released under the GPLv3 license. +*/ +!function(a,b){window.console=window.console||{log:function(){},error:function(){}},a.fn.footable=function(a,c){return a=a||{},this.filter("table").each(function(d,e){b.init(e,a,c)})};var c={events:[]};b.__debug__=JSON.parse(localStorage.getItem("footable_debug"))||!1,b.__debug_options__=JSON.parse(localStorage.getItem("footable_debug_options"))||c,b.debug=function(d,e){return b.is["boolean"](d)?(b.__debug__=d,void(b.__debug__?(localStorage.setItem("footable_debug",JSON.stringify(b.__debug__)),b.__debug_options__=a.extend(!0,{},c,e||{}),b.is.hash(e)&&localStorage.setItem("footable_debug_options",JSON.stringify(b.__debug_options__))):(localStorage.removeItem("footable_debug"),localStorage.removeItem("footable_debug_options")))):b.__debug__},b.get=function(b){return a(b).first().data("__FooTable__")},b.init=function(a,c,d){var e=b.get(a);return e instanceof b.Table&&e.destroy(),new b.Table(a,c,d)},b.getRow=function(b){var c=a(b).closest("tr");return c.hasClass("footable-detail-row")&&(c=c.prev()),c.data("__FooTableRow__")}}(jQuery,FooTable=window.FooTable||{}),function(a){var b=function(){return!0};a.arr={},a.arr.each=function(b,c){if(a.is.array(b)&&a.is.fn(c))for(var d=0,e=b.length;e>d&&c(b[d],d)!==!1;d++);},a.arr.get=function(b,c){var d=[];if(!a.is.array(b))return d;if(!a.is.fn(c))return b;for(var e=0,f=b.length;f>e;e++)c(b[e],e)&&d.push(b[e]);return d},a.arr.any=function(c,d){if(!a.is.array(c))return!1;d=a.is.fn(d)?d:b;for(var e=0,f=c.length;f>e;e++)if(d(c[e],e))return!0;return!1},a.arr.contains=function(b,c){if(!a.is.array(b)||a.is.undef(c))return!1;for(var d=0,e=b.length;e>d;d++)if(b[d]==c)return!0;return!1},a.arr.first=function(c,d){if(!a.is.array(c))return null;d=a.is.fn(d)?d:b;for(var e=0,f=c.length;f>e;e++)if(d(c[e],e))return c[e];return null},a.arr.map=function(b,c){var d=[],e=null;if(!a.is.array(b)||!a.is.fn(c))return d;for(var f=0,g=b.length;g>f;f++)null!=(e=c(b[f],f))&&d.push(e);return d},a.arr.remove=function(b,c){var d=[],e=[];if(!a.is.array(b)||!a.is.fn(c))return e;for(var f=0,g=b.length;g>f;f++)c(b[f],f,e)&&(d.push(f),e.push(b[f]));for(d.sort(function(a,b){return b-a}),f=0,g=d.length;g>f;f++){var h=d[f]-f;b.splice(h,1)}return e},a.arr["delete"]=function(b,c){var d=-1,e=null;if(!a.is.array(b)||a.is.undef(c))return e;for(var f=0,g=b.length;g>f;f++)if(b[f]==c){d=f,e=b[f];break}return-1!=d&&b.splice(d,1),e},a.arr.replace=function(a,b,c){var d=a.indexOf(b);-1!==d&&(a[d]=c)}}(FooTable),function(a){a.is={},a.is.type=function(a,b){return typeof a===b},a.is.defined=function(a){return"undefined"!=typeof a},a.is.undef=function(a){return"undefined"==typeof a},a.is.array=function(a){return"[object Array]"===Object.prototype.toString.call(a)},a.is.date=function(a){return"[object Date]"===Object.prototype.toString.call(a)&&!isNaN(a.getTime())},a.is["boolean"]=function(a){return"[object Boolean]"===Object.prototype.toString.call(a)},a.is.string=function(a){return"[object String]"===Object.prototype.toString.call(a)},a.is.number=function(a){return"[object Number]"===Object.prototype.toString.call(a)&&!isNaN(a)},a.is.fn=function(b){return a.is.defined(window)&&b===window.alert||"[object Function]"===Object.prototype.toString.call(b)},a.is.error=function(a){return"[object Error]"===Object.prototype.toString.call(a)},a.is.object=function(a){return"[object Object]"===Object.prototype.toString.call(a)},a.is.hash=function(b){return a.is.object(b)&&b.constructor===Object&&!b.nodeType&&!b.setInterval},a.is.element=function(a){return"object"==typeof HTMLElement?a instanceof HTMLElement:a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName},a.is.promise=function(b){return a.is.object(b)&&a.is.fn(b.then)&&a.is.fn(b.promise)},a.is.jq=function(b){return a.is.defined(window.jQuery)&&b instanceof jQuery&&b.length>0},a.is.moment=function(b){return a.is.defined(window.moment)&&a.is.object(b)&&a.is["boolean"](b._isAMomentObject)},a.is.emptyObject=function(b){if(!a.is.hash(b))return!1;for(var c in b)if(b.hasOwnProperty(c))return!1;return!0},a.is.emptyArray=function(b){return a.is.array(b)?0===b.length:!0},a.is.emptyString=function(b){return a.is.string(b)?0===b.length:!0}}(FooTable),function(a){a.str={},a.str.contains=function(b,c,d){return a.is.emptyString(b)||a.is.emptyString(c)?!1:c.length<=b.length&&-1!==(d?b.toUpperCase().indexOf(c.toUpperCase()):b.indexOf(c))},a.str.containsExact=function(b,c,d){return a.is.emptyString(b)||a.is.emptyString(c)||c.length>b.length?!1:new RegExp("\\b"+a.str.escapeRegExp(c)+"\\b",d?"i":"").test(b)},a.str.containsWord=function(b,c,d){if(a.is.emptyString(b)||a.is.emptyString(c)||b.lengthf;f++)if(d?e[f].toUpperCase()==c.toUpperCase():e[f]==c)return!0;return!1},a.str.from=function(b,c){return a.is.emptyString(b)?b:a.str.contains(b,c)?b.substring(b.indexOf(c)+1):b},a.str.startsWith=function(b,c){return a.is.emptyString(b)?b==c:b.slice(0,c.length)==c},a.str.toCamelCase=function(b){return a.is.emptyString(b)?b:b.toUpperCase()===b?b.toLowerCase():b.replace(/^([A-Z])|[-\s_](\w)/g,function(b,c,d){return a.is.string(d)?d.toUpperCase():c.toLowerCase()})},a.str.random=function(b){return b=a.is.emptyString(b)?"":b,b+Math.random().toString(36).substr(2,9)},a.str.escapeRegExp=function(b){return a.is.emptyString(b)?b:b.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}}(FooTable),function(a){"use strict";function b(){}Object.create||(Object.create=function(){var b=function(){};return function(c){if(arguments.length>1)throw Error("Second argument not supported");if(!a.is.object(c))throw TypeError("Argument must be an object");b.prototype=c;var d=new b;return b.prototype=null,d}}());var c=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;b.__extend__=function(b,d,e,f){b[d]=a.is.fn(f)&&c.test(e)?function(a,b){return function(){var a,c;return a=this._super,this._super=f,c=b.apply(this,arguments),this._super=a,c}}(d,e):e},b.extend=function(d,e){function f(b,d,e,f){b[d]=a.is.fn(f)&&c.test(e)?function(a,b,c){return function(){var a,d;return a=this._super,this._super=c,d=b.apply(this,arguments),this._super=a,d}}(d,e,f):e}var g=Array.prototype.slice.call(arguments);if(d=g.shift(),e=g.shift(),a.is.hash(d)){var h=Object.create(this.prototype),i=this.prototype;for(var j in d)"__ctor__"!==j&&f(h,j,d[j],i[j]);var k=a.is.fn(h.__ctor__)?h.__ctor__:function(){if(!a.is.fn(this.construct))throw new SyntaxError('FooTable class objects must be constructed with the "new" keyword.');this.construct.apply(this,arguments)};return h.construct=a.is.fn(h.construct)?h.construct:function(){},k.prototype=h,h.constructor=k,k.extend=b.extend,k}a.is.string(d)&&a.is.fn(e)&&f(this.prototype,d,e,this.prototype[d])},a.Class=b,a.ClassFactory=a.Class.extend({construct:function(){this.registered={}},contains:function(b){return a.is.defined(this.registered[b])},names:function(){var a,b=[];for(a in this.registered)this.registered.hasOwnProperty(a)&&b.push(a);return b},register:function(b,c,d){if(a.is.string(b)&&a.is.fn(c)){var e=this.registered[b];this.registered[b]={name:b,klass:c,priority:a.is.number(d)?d:a.is.defined(e)?e.priority:0}}},load:function(b,c,d){var e,f,g=this,h=Array.prototype.slice.call(arguments),i=[],j=[];b=h.shift()||{};for(e in g.registered)if(g.registered.hasOwnProperty(e)){var k=g.registered[e];b.hasOwnProperty(e)&&(f=b[e],a.is.string(f)&&(f=a.getFnPointer(b[e])),a.is.fn(f)&&(k={name:e,klass:f,priority:g.registered[e].priority})),i.push(k)}for(e in b)b.hasOwnProperty(e)&&!g.registered.hasOwnProperty(e)&&(f=b[e],a.is.string(f)&&(f=a.getFnPointer(b[e])),a.is.fn(f)&&i.push({name:e,klass:f,priority:0}));return i.sort(function(a,b){return b.priority-a.priority}),a.arr.each(i,function(b){a.is.fn(b.klass)&&j.push(g._make(b.klass,h))}),j},make:function(b,c,d){var e,f=this,g=Array.prototype.slice.call(arguments);return b=g.shift(),e=f.registered[b],a.is.fn(e.klass)?f._make(e.klass,g):null},_make:function(a,b){function c(){return a.apply(this,b)}return c.prototype=a.prototype,new c}})}(FooTable),function(a,b){b.css2json=function(c){if(b.is.emptyString(c))return{};for(var d,e,f,g={},h=c.split(";"),i=0,j=h.length;j>i;i++)b.is.emptyString(h[i])||(d=h[i].split(":"),b.is.emptyString(d[0])||b.is.emptyString(d[1])||(e=b.str.toCamelCase(a.trim(d[0])),f=a.trim(d[1]),g[e]=f));return g},b.getFnPointer=function(a){if(b.is.emptyString(a))return null;var c=window,d=a.split(".");return b.arr.each(d,function(a){c[a]&&(c=c[a])}),b.is.fn(c)?c:null},b.checkFnValue=function(a,c,d){function e(a,c,d){return b.is.fn(c)?function(){return c.apply(a,arguments)}:d}return d=b.is.fn(d)?d:null,b.is.fn(c)?e(a,c,d):b.is.type(c,"string")?e(a,b.getFnPointer(c),d):d}}(jQuery,FooTable),function(a,b){b.Cell=b.Class.extend({construct:function(a,b,c,d){this.ft=a,this.row=b,this.column=c,this.created=!1,this.define(d)},define:function(c){this.$el=b.is.element(c)||b.is.jq(c)?a(c):null,this.$detail=null;var d=b.is.hash(c)&&b.is.hash(c.options)&&b.is.defined(c.value);this.value=this.column.parser.call(this.column,b.is.jq(this.$el)?this.$el:d?c.value:c,this.ft.o),this.o=a.extend(!0,{classes:null,style:null},d?c.options:{}),this.classes=b.is.jq(this.$el)&&this.$el.attr("class")?this.$el.attr("class").match(/\S+/g):b.is.array(this.o.classes)?this.o.classes:b.is.string(this.o.classes)?this.o.classes.match(/\S+/g):[],this.style=b.is.jq(this.$el)&&this.$el.attr("style")?b.css2json(this.$el.attr("style")):b.is.hash(this.o.style)?this.o.style:b.is.string(this.o.style)?b.css2json(this.o.style):{}},$create:function(){this.created||((this.$el=b.is.jq(this.$el)?this.$el:a("")).data("value",this.value).contents().detach().end().append(this.format(this.value)),this._setClasses(this.$el),this._setStyle(this.$el),this.$detail=a("").addClass(this.row.classes.join(" ")).data("__FooTableCell__",this).append(a("")).append(a("")),this.created=!0)},collapse:function(){this.created&&(this.$detail.children("th").html(this.column.title),this.$el.clone().attr("id",this.$el.attr("id")?this.$el.attr("id")+"-detail":void 0).css("display","table-cell").html("").append(this.$el.contents().detach()).replaceAll(this.$detail.children("td").first()),b.is.jq(this.$detail.parent())||this.$detail.appendTo(this.row.$details.find(".footable-details > tbody")))},restore:function(){if(this.created){if(b.is.jq(this.$detail.parent())){var a=this.$detail.children("td").first();this.$el.attr("class",a.attr("class")).attr("style",a.attr("style")).css("display",this.column.hidden||!this.column.visible?"none":"table-cell").append(a.contents().detach())}this.$detail.detach()}},parse:function(){return this.column.parser.call(this.column,this.$el,this.ft.o)},format:function(a){return this.column.formatter.call(this.column,a,this.ft.o)},val:function(c,d){if(b.is.undef(c))return this.value;var e=this,f=b.is.hash(c)&&b.is.hash(c.options)&&b.is.defined(c.value);if(this.o=a.extend(!0,{classes:e.classes,style:e.style},f?c.options:{}),this.value=f?c.value:c,this.classes=b.is.array(this.o.classes)?this.o.classes:b.is.string(this.o.classes)?this.o.classes.match(/\S+/g):[],this.style=b.is.hash(this.o.style)?this.o.style:b.is.string(this.o.style)?b.css2json(this.o.style):{},this.created){this.$el.data("value",this.value).empty();var g=this.$detail.children("td").first().empty(),h=b.is.jq(this.$detail.parent())?g:this.$el;h.append(this.format(this.value)),this._setClasses(h),this._setStyle(h),(b.is["boolean"](d)?d:!0)&&this.row.draw()}},_setClasses:function(a){var c=!b.is.emptyArray(this.column.classes),d=!b.is.emptyArray(this.classes),e=null;a.removeAttr("class"),(c||d)&&(c&&d?e=this.classes.concat(this.column.classes).join(" "):c?e=this.column.classes.join(" "):d&&(e=this.classes.join(" ")),b.is.emptyString(e)||a.addClass(e))},_setStyle:function(c){var d=!b.is.emptyObject(this.column.style),e=!b.is.emptyObject(this.style),f=null;c.removeAttr("style"),(d||e)&&(d&&e?f=a.extend({},this.column.style,this.style):d?f=this.column.style:e&&(f=this.style),b.is.hash(f)&&c.css(f))}})}(jQuery,FooTable),function(a,b){b.Column=b.Class.extend({construct:function(a,c,d){this.ft=a,this.type=b.is.emptyString(d)?"text":d,this.virtual=b.is["boolean"](c.virtual)?c.virtual:!1,this.$el=b.is.jq(c.$el)?c.$el:null,this.index=b.is.number(c.index)?c.index:-1,this.define(c),this.$create()},define:function(a){this.hidden=b.is["boolean"](a.hidden)?a.hidden:!1,this.visible=b.is["boolean"](a.visible)?a.visible:!0,this.name=b.is.string(a.name)?a.name:null,null==this.name&&(this.name="col"+(a.index+1)),this.title=b.is.string(a.title)?a.title:null,!this.virtual&&null==this.title&&b.is.jq(this.$el)&&(this.title=this.$el.html()),null==this.title&&(this.title="Column "+(a.index+1)),this.style=b.is.hash(a.style)?a.style:b.is.string(a.style)?b.css2json(a.style):{},this.classes=b.is.array(a.classes)?a.classes:b.is.string(a.classes)?a.classes.match(/\S+/g):[],this.parser=b.checkFnValue(this,a.parser,this.parser),this.formatter=b.checkFnValue(this,a.formatter,this.formatter)},$create:function(){(this.$el=!this.virtual&&b.is.jq(this.$el)?this.$el:a("")).html(this.title).addClass(this.classes.join(" ")).css(this.style)},parser:function(c){if(b.is.element(c)||b.is.jq(c)){var d=a(c).data("value");return b.is.defined(d)?d:a(c).html()}return b.is.defined(c)&&null!=c?c+"":null},formatter:function(a){return null==a?"":a},createCell:function(a){var c=b.is.jq(a.$el)?a.$el.children("td,th").get(this.index):null,d=b.is.hash(a.value)?a.value[this.name]:null;return new b.Cell(this.ft,a,this,c||d)}}),b.columns=new b.ClassFactory,b.columns.register("text",b.Column)}(jQuery,FooTable),function(a,b){b.Component=b.Class.extend({construct:function(a,c){if(!(a instanceof b.Table))throw new TypeError("The instance parameter must be an instance of FooTable.Table.");this.ft=a,this.enabled=b.is["boolean"](c)?c:!1},preinit:function(a){},init:function(){},destroy:function(){},predraw:function(){},draw:function(){},postdraw:function(){}}),b.components=new b.ClassFactory}(jQuery,FooTable),function(a,b){b.Defaults=function(){this.stopPropagation=!1,this.on=null},b.defaults=new b.Defaults}(jQuery,FooTable),function(a,b){b.Row=b.Class.extend({construct:function(a,b,c){this.ft=a,this.columns=b,this.created=!1,this.define(c)},define:function(c){this.$el=b.is.element(c)||b.is.jq(c)?a(c):null,this.$toggle=a("",{"class":"footable-toggle fooicon fooicon-plus"});var d=b.is.hash(c),e=d&&b.is.hash(c.options)&&b.is.hash(c.value);this.value=d?e?c.value:c:null,this.o=a.extend(!0,{expanded:!1,classes:null,style:null},e?c.options:{}),this.expanded=b.is.jq(this.$el)?this.$el.data("expanded")||this.o.expanded:this.o.expanded,this.classes=b.is.jq(this.$el)&&this.$el.attr("class")?this.$el.attr("class").match(/\S+/g):b.is.array(this.o.classes)?this.o.classes:b.is.string(this.o.classes)?this.o.classes.match(/\S+/g):[],this.style=b.is.jq(this.$el)&&this.$el.attr("style")?b.css2json(this.$el.attr("style")):b.is.hash(this.o.style)?this.o.style:b.is.string(this.o.style)?b.css2json(this.o.style):{},this.cells=this.createCells();var f=this;f.value={},b.arr.each(f.cells,function(a){f.value[a.column.name]=a.val()})},$create:function(){if(!this.created){(this.$el=b.is.jq(this.$el)?this.$el:a("")).data("__FooTableRow__",this),this._setClasses(this.$el),this._setStyle(this.$el),"last"==this.ft.rows.toggleColumn&&this.$toggle.addClass("last-column"),this.$details=a("",{"class":"footable-detail-row"}).append(a("",{colspan:this.ft.columns.visibleColspan}).append(a("",{"class":"footable-details "+this.ft.classes.join(" ")}).append("")));var c=this;b.arr.each(c.cells,function(a){a.created||a.$create(),c.$el.append(a.$el)}),c.$el.off("click.ft.row").on("click.ft.row",{self:c},c._onToggle),this.created=!0}},createCells:function(){var a=this;return b.arr.map(a.columns,function(b){return b.createCell(a)})},val:function(c,d){var e=this;if(!b.is.hash(c))return b.is.hash(this.value)&&!b.is.emptyObject(this.value)||(this.value={},b.arr.each(this.cells,function(a){e.value[a.column.name]=a.val()})),this.value;this.collapse(!1);var f=b.is.hash(c),g=f&&b.is.hash(c.options)&&b.is.hash(c.value);if(this.o=a.extend(!0,{expanded:e.expanded,classes:e.classes,style:e.style},g?c.options:{}),this.expanded=this.o.expanded,this.classes=b.is.array(this.o.classes)?this.o.classes:b.is.string(this.o.classes)?this.o.classes.match(/\S+/g):[],this.style=b.is.hash(this.o.style)?this.o.style:b.is.string(this.o.style)?b.css2json(this.o.style):{},f)if(g&&(c=c.value),b.is.hash(this.value))for(var h in c)c.hasOwnProperty(h)&&(this.value[h]=c[h]);else this.value=c;else this.value=null;b.arr.each(this.cells,function(a){b.is.defined(e.value[a.column.name])&&a.val(e.value[a.column.name],!1)}),this.created&&(this._setClasses(this.$el),this._setStyle(this.$el),(b.is["boolean"](d)?d:!0)&&this.draw())},_setClasses:function(a){var c=!b.is.emptyArray(this.classes),d=null;a.removeAttr("class"),c&&(d=this.classes.join(" "),b.is.emptyString(d)||a.addClass(d))},_setStyle:function(a){var c=!b.is.emptyObject(this.style),d=null;a.removeAttr("style"),c&&(d=this.style,b.is.hash(d)&&a.css(d))},expand:function(){if(this.created){var a=this;a.ft.raise("expand.ft.row",[a]).then(function(){a.__hidden__=b.arr.map(a.cells,function(a){return a.column.hidden&&a.column.visible?a:null}),a.__hidden__.length>0&&(a.$details.insertAfter(a.$el).children("td").first().attr("colspan",a.ft.columns.visibleColspan),b.arr.each(a.__hidden__,function(a){a.collapse()})),a.$el.attr("data-expanded",!0),a.$toggle.removeClass("fooicon-plus").addClass("fooicon-minus"),a.expanded=!0})}},collapse:function(a){if(this.created){var c=this;c.ft.raise("collapse.ft.row",[c]).then(function(){b.arr.each(c.__hidden__,function(a){a.restore()}),c.$details.detach(),c.$el.removeAttr("data-expanded"),c.$toggle.removeClass("fooicon-minus").addClass("fooicon-plus"),(b.is["boolean"](a)?a:!0)&&(c.expanded=!1)})}},predraw:function(a){this.created&&(this.expanded&&this.collapse(!1),this.$toggle.detach(),a=b.is["boolean"](a)?a:!0,a&&this.$el.detach())},draw:function(a){this.created||this.$create(),b.is.jq(a)&&a.append(this.$el);var c=this;b.arr.each(c.cells,function(a){a.$el.css("display",a.column.hidden||!a.column.visible?"none":"table-cell"),c.ft.rows.showToggle&&c.ft.columns.hasHidden&&("first"==c.ft.rows.toggleColumn&&a.column.index==c.ft.columns.firstVisibleIndex||"last"==c.ft.rows.toggleColumn&&a.column.index==c.ft.columns.lastVisibleIndex)&&a.$el.prepend(c.$toggle),a.$el.add(a.column.$el).removeClass("footable-first-visible footable-last-visible"),a.column.index==c.ft.columns.firstVisibleIndex&&a.$el.add(a.column.$el).addClass("footable-first-visible"),a.column.index==c.ft.columns.lastVisibleIndex&&a.$el.add(a.column.$el).addClass("footable-last-visible")}),this.expanded&&this.expand()},toggle:function(){this.created&&this.ft.columns.hasHidden&&(this.expanded?this.collapse():this.expand())},_onToggle:function(b){var c=b.data.self;a(b.target).is(c.ft.rows.toggleSelector)&&c.toggle()}})}(jQuery,FooTable),function(a,b){b.instances=[],b.Table=b.Class.extend({construct:function(c,d,e){this._resizeTimeout=null,this.id=b.instances.push(this),this.initialized=!1,this.$el=(b.is.jq(c)?c:a(c)).first(),this.$loader=a("
",{"class":"footable-loader"}).append(a("",{"class":"fooicon fooicon-loader"})),this.o=a.extend(!0,{},b.defaults,d),this.data=this.$el.data()||{},this.classes=[],this.components=b.components.load(b.is.hash(this.data.components)?this.data.components:this.o.components,this),this.breakpoints=this.use(FooTable.Breakpoints),this.columns=this.use(FooTable.Columns),this.rows=this.use(FooTable.Rows),this._construct(e)},_construct:function(a){var c=this;this._preinit().then(function(){return c._init()}).always(function(d){return c.$el.show(),b.is.error(d)?void console.error("FooTable: unhandled error thrown during initialization.",d):c.raise("ready.ft.table").then(function(){b.is.fn(a)&&a.call(c,c)})})},_preinit:function(){var a=this;return this.raise("preinit.ft.table",[a.data]).then(function(){var c=(a.$el.attr("class")||"").match(/\S+/g)||[];a.o.ajax=b.checkFnValue(a,a.data.ajax,a.o.ajax),a.o.stopPropagation=b.is["boolean"](a.data.stopPropagation)?a.data.stopPropagation:a.o.stopPropagation;for(var d=0,e=c.length;e>d;d++)b.str.startsWith(c[d],"footable")||a.classes.push(c[d]);return a.$el.hide().after(a.$loader),a.execute(!1,!1,"preinit",a.data)})},_init:function(){var c=this;return c.raise("init.ft.table").then(function(){var d=c.$el.children("thead"),e=c.$el.children("tbody"),f=c.$el.children("tfoot");return c.$el.addClass("footable footable-"+c.id),b.is.hash(c.o.on)&&c.$el.on(c.o.on),0==f.length&&c.$el.append(f=a("
")),0==e.length&&c.$el.append(""),0==d.length&&c.$el.prepend(d=a("")),c.execute(!1,!0,"init").then(function(){return c.$el.data("__FooTable__",c),0==f.children("tr").length&&f.remove(),0==d.children("tr").length&&d.remove(),c.raise("postinit.ft.table").then(function(){return c.draw()}).always(function(){a(window).off("resize.ft"+c.id,c._onWindowResize).on("resize.ft"+c.id,{self:c},c._onWindowResize),c.initialized=!0})})})},destroy:function(){var c=this;return c.raise("destroy.ft.table").then(function(){return c.execute(!0,!0,"destroy").then(function(){c.$el.removeData("__FooTable__").removeClass("footable-"+c.id),b.is.hash(c.o.on)&&c.$el.off(c.o.on),a(window).off("resize.ft"+c.id,c._onWindowResize),c.initialized=!1})}).fail(function(a){b.is.error(a)&&console.error("FooTable: unhandled error thrown while destroying the plugin.",a)})},raise:function(c,d){var e=this,f=b.__debug__&&(b.is.emptyArray(b.__debug_options__.events)||b.arr.any(b.__debug_options__.events,function(a){return b.str.contains(c,a)}));return d=d||[],d.unshift(this),a.Deferred(function(b){var g=a.Event(c);1==e.o.stopPropagation&&e.$el.one(c,function(a){a.stopPropagation()}),f&&console.log("FooTable:"+c+": ",d),e.$el.trigger(g,d),g.isDefaultPrevented()?(f&&console.log('FooTable: default prevented for the "'+c+'" event.'),b.reject(g)):b.resolve(g)})},use:function(a){for(var b=0,c=this.components.length;c>b;b++)if(this.components[b]instanceof a)return this.components[b];return null},draw:function(){var a=this,c=a.$el.clone().insertBefore(a.$el);return a.$el.detach(),a.execute(!1,!0,"predraw").then(function(){return a.raise("predraw.ft.table").then(function(){return a.execute(!1,!0,"draw").then(function(){return a.raise("draw.ft.table").then(function(){return a.execute(!1,!0,"postdraw").then(function(){return a.raise("postdraw.ft.table")})})})})}).fail(function(a){b.is.error(a)&&console.error("FooTable: unhandled error thrown during a draw operation.",a)}).always(function(){c.replaceWith(a.$el),a.$loader.remove()})},execute:function(a,c,d,e,f){var g=this,h=Array.prototype.slice.call(arguments);a=h.shift(),c=h.shift();var i=c?b.arr.get(g.components,function(a){return a.enabled}):g.components.slice(0);return h.unshift(a?i.reverse():i),g._execute.apply(g,h)},_execute:function(c,d,e,f){if(!c||!c.length)return a.when();var g,h=this,i=Array.prototype.slice.call(arguments);return c=i.shift(),d=i.shift(),g=c.shift(),b.is.fn(g[d])?a.Deferred(function(a){try{var c=g[d].apply(g,i);if(b.is.promise(c))return c.then(a.resolve,a.reject);a.resolve(c)}catch(e){a.reject(e)}}).then(function(){return h._execute.apply(h,[c,d].concat(i))}):h._execute.apply(h,[c,d].concat(i))},_onWindowResize:function(a){var b=a.data.self;null!=b._resizeTimeout&&clearTimeout(b._resizeTimeout),b._resizeTimeout=setTimeout(function(){b._resizeTimeout=null,b.raise("resize.ft.table").then(function(){b.breakpoints.check()})},300)}})}(jQuery,FooTable),function(a,b){b.is.undef(window.moment)||(b.DateColumn=b.Column.extend({construct:function(a,c){this._super(a,c,"date"),this.formatString=b.is.string(c.formatString)?c.formatString:"MM-DD-YYYY"},parser:function(c){if(b.is.element(c)||b.is.jq(c)){var d=a(c).data("value");c=b.is.defined(d)?d:a(c).text(),b.is.string(c)&&(c=isNaN(c)?c:+c)}if(b.is.date(c))return moment(c);if(b.is.object(c)&&b.is["boolean"](c._isAMomentObject))return c;if(b.is.string(c)){if(isNaN(c))return moment(c,this.formatString);c=+c}return b.is.number(c)?moment(c):null},formatter:function(a){return b.is.object(a)&&b.is["boolean"](a._isAMomentObject)&&a.isValid()?a.format(this.formatString):""},filterValue:function(c){if((b.is.element(c)||b.is.jq(c))&&(c=a(c).data("filterValue")||a(c).text()),b.is.hash(c)&&b.is.hash(c.options)&&(b.is.string(c.options.filterValue)&&(c=c.options.filterValue),b.is.defined(c.value)&&(c=c.value)),b.is.object(c)&&b.is["boolean"](c._isAMomentObject))return c.format(this.formatString);if(b.is.string(c)){if(isNaN(c))return c;c=+c}return b.is.number(c)||b.is.date(c)?moment(c).format(this.formatString):b.is.defined(c)&&null!=c?c+"":""}}),b.columns.register("date",b.DateColumn))}(jQuery,FooTable),function(a,b){b.HTMLColumn=b.Column.extend({construct:function(a,b){this._super(a,b,"html")},parser:function(c){if(b.is.string(c)&&(c=a(a.trim(c))),b.is.element(c)&&(c=a(c)),b.is.jq(c)){var d=c.prop("tagName").toLowerCase();if("td"==d||"th"==d){var e=c.data("value");return b.is.defined(e)?e:c.contents()}return c}return null}}),b.columns.register("html",b.HTMLColumn)}(jQuery,FooTable),function(a,b){b.NumberColumn=b.Column.extend({construct:function(a,c){this._super(a,c,"number"),this.decimalSeparator=b.is.string(c.decimalSeparator)?c.decimalSeparator:".",this.thousandSeparator=b.is.string(c.thousandSeparator)?c.thousandSeparator:",",this.decimalSeparatorRegex=new RegExp(b.str.escapeRegExp(this.decimalSeparator),"g"),this.thousandSeparatorRegex=new RegExp(b.str.escapeRegExp(this.thousandSeparator),"g"),this.cleanRegex=new RegExp("[^0-9"+b.str.escapeRegExp(this.decimalSeparator)+"]","g")},parser:function(c){if(b.is.element(c)||b.is.jq(c)){var d=a(c).data("value");c=b.is.defined(d)?d:a(c).text().replace(this.cleanRegex,"")}return b.is.string(c)&&(c=c.replace(this.thousandSeparatorRegex,"").replace(this.decimalSeparatorRegex,"."),c=parseFloat(c)),b.is.number(c)?c:null},formatter:function(a){if(null==a)return"";var b=(a+"").split(".");return 2==b.length&&b[0].length>3&&(b[0]=b[0].replace(/\B(?=(?:\d{3})+(?!\d))/g,this.thousandSeparator)),b.join(this.decimalSeparator)}}),b.columns.register("number",b.NumberColumn)}(jQuery,FooTable),function(a,b){b.Breakpoint=b.Class.extend({construct:function(a,b){this.name=a,this.width=b}})}(jQuery,FooTable),function(a,b){b.Breakpoints=b.Component.extend({construct:function(a){this._super(a,!0),this.o=a.o,this.current=null,this.array=[],this.cascade=this.o.cascade,this.useParentWidth=this.o.useParentWidth,this.hidden=null,this._classNames="",this.getWidth=b.checkFnValue(this,this.o.getWidth,this.getWidth)},preinit:function(a){var c=this;return this.ft.raise("preinit.ft.breakpoints",[a]).then(function(){c.cascade=b.is["boolean"](a.cascade)?a.cascade:c.cascade,c.o.breakpoints=b.is.hash(a.breakpoints)?a.breakpoints:c.o.breakpoints,c.getWidth=b.checkFnValue(c,a.getWidth,c.getWidth),null==c.o.breakpoints&&(c.o.breakpoints={xs:480,sm:768,md:992,lg:1200});for(var d in c.o.breakpoints)c.o.breakpoints.hasOwnProperty(d)&&(c.array.push(new b.Breakpoint(d,c.o.breakpoints[d])),c._classNames+="breakpoint-"+d+" ");c.array.sort(function(a,b){return b.width-a.width})})},init:function(){var a=this;return this.ft.raise("init.ft.breakpoints").then(function(){a.current=a.get()})},draw:function(){this.ft.$el.removeClass(this._classNames).addClass("breakpoint-"+this.current.name)},calculate:function(){for(var a,c=this,d=null,e=[],f=null,g=c.getWidth(),h=0,i=c.array.length;i>h;h++)a=c.array[h],(!d&&h==i-1||g>=a.width&&(f instanceof b.Breakpoint?gd;d++)if(this.cascade?b.str.containsWord(this.hidden,c[d]):c[d]==this.current.name)return!1;return!0},check:function(){var a=this,c=a.get();c instanceof b.Breakpoint&&c!=a.current&&a.ft.raise("before.ft.breakpoints",[a.current,c]).then(function(){var b=a.current;return a.current=c,a.ft.draw().then(function(){a.ft.raise("after.ft.breakpoints",[a.current,b])})})},get:function(a){return b.is.undef(a)?this.calculate():a instanceof b.Breakpoint?a:b.is.string(a)?b.arr.first(this.array,function(b){return b.name==a}):b.is.number(a)&&a>=0&&af&&(f=a.index)}),f++;for(var g,h,i=0;f>i;i++)g={},b.arr.each(c,function(a){return a.index==i?(g=a,!1):void 0}),h={},b.arr.each(d,function(a){return a.index==i?(h=a,!1):void 0}),e.push(a.extend(!0,{},g,h))}return e}var f,g,h=[],i=[],j=d.ft.$el.find("tr.footable-header, thead > tr:last:has([data-breakpoints]), tbody > tr:first:has([data-breakpoints]), thead > tr:last, tbody > tr:first").first();if(j.length>0){var k=j.parent().is("tbody")&&j.children().length==j.children("td").length;k||(d.$header=j.addClass("footable-header")),j.children("td,th").each(function(b,c){f=a(c),g=f.data(),g.index=b,g.$el=f,g.virtual=k,i.push(g)}),k&&(d.showHeader=!1)}b.is.array(d.o.columns)&&!b.is.emptyArray(d.o.columns)?(b.arr.each(d.o.columns,function(a,b){a.index=b,h.push(a)}),d.parseFinalize(c,e(h,i))):b.is.promise(d.o.columns)?d.o.columns.then(function(a){b.arr.each(a,function(a,b){a.index=b,h.push(a)}),d.parseFinalize(c,e(h,i))},function(a){c.reject(Error("Columns ajax request error: "+a.status+" ("+a.statusText+")"))}):d.parseFinalize(c,e(h,i))})},parseFinalize:function(a,c){var d,e=this,f=[];b.arr.each(c,function(a){(d=b.columns.contains(a.type)?b.columns.make(a.type,e.ft,a):new b.Column(e.ft,a))&&f.push(d)}),b.is.emptyArray(f)?a.reject(Error("No columns supplied.")):(f.sort(function(a,b){return a.index-b.index}),a.resolve(f))},preinit:function(a){var c=this;return c.ft.raise("preinit.ft.columns",[a]).then(function(){return c.parse(a).then(function(d){c.array=d,c.showHeader=b.is["boolean"](a.showHeader)?a.showHeader:c.showHeader})})},init:function(){var a=this;return this.ft.raise("init.ft.columns",[a.array]).then(function(){a.$create()})},destroy:function(){var a=this;this.ft.raise("destroy.ft.columns").then(function(){a._fromHTML||a.$header.remove()})},predraw:function(){var a=this,c=!0;a.visibleColspan=0,a.firstVisibleIndex=0,a.lastVisibleIndex=0,a.hasHidden=!1,b.arr.each(a.array,function(b){b.hidden=!a.ft.breakpoints.visible(b.breakpoints),!b.hidden&&b.visible&&(c&&(a.firstVisibleIndex=b.index,c=!1),a.lastVisibleIndex=b.index,a.visibleColspan++),b.hidden&&(a.hasHidden=!0)}),a.ft.$el.toggleClass("breakpoint",a.hasHidden)},draw:function(){b.arr.each(this.array,function(a){a.$el.css("display",a.hidden||!a.visible?"none":"table-cell")}),!this.showHeader&&b.is.jq(this.$header.parent())&&this.$header.detach()},$create:function(){var c=this;c.$header=b.is.jq(c.$header)?c.$header:a("",{"class":"footable-header" +}),c.$header.children("th,td").detach(),b.arr.each(c.array,function(a){c.$header.append(a.$el)}),c.showHeader&&!b.is.jq(c.$header.parent())&&c.ft.$el.children("thead").append(c.$header)},get:function(a){return a instanceof b.Column?a:b.is.string(a)?b.arr.first(this.array,function(b){return b.name==a}):b.is.number(a)?b.arr.first(this.array,function(b){return b.index==a}):b.is.fn(a)?b.arr.get(this.array,a):null},ensure:function(a){var c=this,d=[];return b.is.array(a)?(b.arr.each(a,function(a){d.push(c.get(a))}),d):d}}),b.components.register("columns",b.Columns,900)}(jQuery,FooTable),function(a){a.Defaults.prototype.columns=[],a.Defaults.prototype.showHeader=!0}(FooTable),function(a,b){b.Rows=b.Component.extend({construct:function(a){this._super(a,!0),this.o=a.o,this.array=[],this.all=[],this.showToggle=a.o.showToggle,this.toggleSelector=a.o.toggleSelector,this.toggleColumn=a.o.toggleColumn,this.emptyString=a.o.empty,this.expandFirst=a.o.expandFirst,this.expandAll=a.o.expandAll,this.$empty=null,this._fromHTML=b.is.emptyArray(a.o.rows)&&!b.is.promise(a.o.rows)},parse:function(){var c=this;return a.Deferred(function(a){var d=c.ft.$el.children("tbody").children("tr");b.is.array(c.o.rows)&&c.o.rows.length>0?c.parseFinalize(a,c.o.rows):b.is.promise(c.o.rows)?c.o.rows.then(function(b){c.parseFinalize(a,b)},function(b){a.reject(Error("Rows ajax request error: "+b.status+" ("+b.statusText+")"))}):b.is.jq(d)?(c.parseFinalize(a,d),d.detach()):c.parseFinalize(a,[])})},parseFinalize:function(c,d){var e=this,f=a.map(d,function(a){return new b.Row(e.ft,e.ft.columns.array,a)});c.resolve(f)},preinit:function(a){var c=this;return c.ft.raise("preinit.ft.rows",[a]).then(function(){return c.parse().then(function(d){c.all=d,c.array=c.all.slice(0),c.showToggle=b.is["boolean"](a.showToggle)?a.showToggle:c.showToggle,c.toggleSelector=b.is.string(a.toggleSelector)?a.toggleSelector:c.toggleSelector,c.toggleColumn=b.is.string(a.toggleColumn)?a.toggleColumn:c.toggleColumn,"first"!=c.toggleColumn&&"last"!=c.toggleColumn&&(c.toggleColumn="first"),c.emptyString=b.is.string(a.empty)?a.empty:c.emptyString,c.expandFirst=b.is["boolean"](a.expandFirst)?a.expandFirst:c.expandFirst,c.expandAll=b.is["boolean"](a.expandAll)?a.expandAll:c.expandAll})})},init:function(){var a=this;return a.ft.raise("init.ft.rows",[a.all]).then(function(){a.$create()})},destroy:function(){var a=this;this.ft.raise("destroy.ft.rows").then(function(){b.arr.each(a.array,function(b){b.predraw(!a._fromHTML)})})},predraw:function(){b.arr.each(this.array,function(a){a.predraw()}),this.array=this.all.slice(0)},$create:function(){this.$empty=a("",{"class":"footable-empty"}).append(a("",{"class":"footable-filtering"}).prependTo(d.ft.$el.children("thead")),d.$cell=a(""),this.ft.$el.append(b)),this.$row.appendTo(b),this.detached=!1}this.$cell.attr("colspan",this.ft.columns.visibleColspan),this._createLinks(),this._setVisible(this.current,this.current>this.previous),this._setNavigation(!0),this.$count.text(this.formattedCount)}},$create:function(){this._createdLinks=0;var b="footable-paging-center";switch(this.position){case"left":b="footable-paging-left";break;case"right":b="footable-paging-right"}this.ft.$el.addClass("footable-paging").addClass(b),this.$cell=a(""),this.ft.$el.append(c)),this.$row=a("",{"class":"footable-paging"}).append(this.$cell).appendTo(c),this.$pagination=a(""),b.ft.$el.append(d)),b.$row=a("",{"class":"footable-editing"}).append(b.$cell).appendTo(d)},$buttonShow:function(){return'"},$buttonHide:function(){return'"},$buttonAdd:function(){return' "},$buttonEdit:function(){return' "},$buttonDelete:function(){return'"},$buttonView:function(){return' "},$rowButtons:function(){return b.is.jq(this._$buttons)?this._$buttons.clone():(this._$buttons=a('
'),this.allowView&&this._$buttons.append(this.$buttonView()),this.allowEdit&&this._$buttons.append(this.$buttonEdit()),this.allowDelete&&this._$buttons.append(this.$buttonDelete()),this._$buttons)},draw:function(){this.$cell.attr("colspan",this.ft.columns.visibleColspan)},_onEditClick:function(c){c.preventDefault();var d=c.data.self,e=a(this).closest("tr").data("__FooTableRow__");e instanceof b.Row&&d.ft.raise("edit.ft.editing",[e]).then(function(){d.callbacks.editRow.call(d.ft,e)})},_onDeleteClick:function(c){c.preventDefault();var d=c.data.self,e=a(this).closest("tr").data("__FooTableRow__");e instanceof b.Row&&d.ft.raise("delete.ft.editing",[e]).then(function(){d.callbacks.deleteRow.call(d.ft,e)})},_onViewClick:function(c){c.preventDefault();var d=c.data.self,e=a(this).closest("tr").data("__FooTableRow__");e instanceof b.Row&&d.ft.raise("view.ft.editing",[e]).then(function(){d.callbacks.viewRow.call(d.ft,e)})},_onAddClick:function(a){a.preventDefault();var b=a.data.self;b.ft.raise("add.ft.editing").then(function(){b.callbacks.addRow.call(b.ft)})},_onShowClick:function(a){a.preventDefault();var b=a.data.self;b.ft.raise("show.ft.editing").then(function(){b.ft.$el.addClass("footable-editing-show"),b.column.visible=!0,b.ft.draw()})},_onHideClick:function(a){a.preventDefault();var b=a.data.self;b.ft.raise("hide.ft.editing").then(function(){b.ft.$el.removeClass("footable-editing-show"),b.column.visible=!1,b.ft.draw()})}}),b.components.register("editing",b.Editing,850)}(jQuery,FooTable),function(a,b){b.EditingColumn=b.Column.extend({construct:function(a,b,c){this._super(a,c,"editing"),this.editing=b},$create:function(){(this.$el=!this.virtual&&b.is.jq(this.$el)?this.$el:a("
"; + $html.=""; + $html.=""; + $html.="
").text(this.emptyString))},draw:function(){var a=this,c=a.ft.$el.children("tbody"),d=!0;a.array.length>0?(a.$empty.detach(),b.arr.each(a.array,function(b){(a.expandFirst&&d||a.expandAll)&&(b.expanded=!0,d=!1),b.draw(c)})):(a.$empty.children("td").attr("colspan",a.ft.columns.visibleColspan),c.append(a.$empty))},load:function(c,d){var e=this,f=a.map(c,function(a){return new b.Row(e.ft,e.ft.columns.array,a)});b.arr.each(this.array,function(a){a.predraw()}),this.all=(b.is["boolean"](d)?d:!1)?this.all.concat(f):f,this.array=this.all.slice(0),this.ft.draw()},expand:function(){b.arr.each(this.array,function(a){a.expand()})},collapse:function(){b.arr.each(this.array,function(a){a.collapse()})}}),b.components.register("rows",b.Rows,800)}(jQuery,FooTable),function(a){a.Defaults.prototype.rows=[],a.Defaults.prototype.empty="No results",a.Defaults.prototype.showToggle=!0,a.Defaults.prototype.toggleSelector="tr,td,.footable-toggle",a.Defaults.prototype.toggleColumn="first",a.Defaults.prototype.expandFirst=!1,a.Defaults.prototype.expandAll=!1}(FooTable),function(a){a.Table.prototype.loadRows=function(a,b){this.rows.load(a,b)}}(FooTable),function(a){a.Filter=a.Class.extend({construct:function(b,c,d,e,f,g,h){this.name=b,this.space=!a.is.string(e)||"OR"!=e&&"AND"!=e?"AND":e,this.connectors=a.is["boolean"](f)?f:!0,this.ignoreCase=a.is["boolean"](g)?g:!0,this.hidden=a.is["boolean"](h)?h:!1,this.query=c instanceof a.Query?c:new a.Query(c,this.space,this.connectors,this.ignoreCase),this.columns=d},match:function(b){return a.is.string(b)?(a.is.string(this.query)&&(this.query=new a.Query(this.query,this.space,this.connectors,this.ignoreCase)),this.query instanceof a.Query?this.query.match(b):!1):!1},matchRow:function(b){var c=this,d=a.arr.map(b.cells,function(b){return a.arr.contains(c.columns,b.column)?b.filterValue:null}).join(" ");return c.match(d)}})}(FooTable),function(a,b){b.Filtering=b.Component.extend({construct:function(a){this._super(a,a.o.filtering.enabled),this.filters=a.o.filtering.filters,this.delay=a.o.filtering.delay,this.min=a.o.filtering.min,this.space=a.o.filtering.space,this.connectors=a.o.filtering.connectors,this.ignoreCase=a.o.filtering.ignoreCase,this.exactMatch=a.o.filtering.exactMatch,this.placeholder=a.o.filtering.placeholder,this.dropdownTitle=a.o.filtering.dropdownTitle,this.position=a.o.filtering.position,this.$row=null,this.$cell=null,this.$dropdown=null,this.$input=null,this.$button=null,this._filterTimeout=null,this._exactRegExp=/^"(.*?)"$/},preinit:function(a){var c=this;return c.ft.raise("preinit.ft.filtering").then(function(){c.ft.$el.hasClass("footable-filtering")&&(c.enabled=!0),c.enabled=b.is["boolean"](a.filtering)?a.filtering:c.enabled,c.enabled&&(c.space=b.is.string(a.filterSpace)?a.filterSpace:c.space,c.min=b.is.number(a.filterMin)?a.filterMin:c.min,c.connectors=b.is["boolean"](a.filterConnectors)?a.filterConnectors:c.connectors,c.ignoreCase=b.is["boolean"](a.filterIgnoreCase)?a.filterIgnoreCase:c.ignoreCase,c.exactMatch=b.is["boolean"](a.filterExactMatch)?a.filterExactMatch:c.exactMatch,c.delay=b.is.number(a.filterDelay)?a.filterDelay:c.delay,c.placeholder=b.is.string(a.filterPlaceholder)?a.filterPlaceholder:c.placeholder,c.dropdownTitle=b.is.string(a.filterDropdownTitle)?a.filterDropdownTitle:c.dropdownTitle,c.filters=b.is.array(a.filterFilters)?c.ensure(a.filterFilters):c.ensure(c.filters),c.ft.$el.hasClass("footable-filtering-left")&&(c.position="left"),c.ft.$el.hasClass("footable-filtering-center")&&(c.position="center"),c.ft.$el.hasClass("footable-filtering-right")&&(c.position="right"),c.position=b.is.string(a.filterPosition)?a.filterPosition:c.position)},function(){c.enabled=!1})},init:function(){var a=this;return a.ft.raise("init.ft.filtering").then(function(){a.$create()},function(){a.enabled=!1})},destroy:function(){var a=this;return a.ft.raise("destroy.ft.filtering").then(function(){a.ft.$el.removeClass("footable-filtering").find("thead > tr.footable-filtering").remove()})},$create:function(){var c,d=this,e=a("
",{"class":"form-group footable-filtering-search"}).append(a("
").attr("colspan",d.ft.columns.visibleColspan).appendTo(d.$row),d.$form=a("
",{"class":"form-inline"}).append(e).appendTo(d.$cell),d.$input=a("",{type:"text","class":"form-control",placeholder:d.placeholder}),d.$button=a("
").attr("colspan",this.ft.columns.visibleColspan);var c=this.ft.$el.children("tfoot");0==c.length&&(c=a("
").attr("colspan",b.ft.columns.visibleColspan).append(b.$buttonShow()),b.allowAdd&&b.$cell.append(b.$buttonAdd()),b.$cell.append(b.$buttonHide()),b.alwaysShow&&b.ft.$el.addClass("footable-editing-always-show"),b.allowAdd||b.ft.$el.addClass("footable-editing-no-add"),b.allowEdit||b.ft.$el.addClass("footable-editing-no-edit"),b.allowDelete||b.ft.$el.addClass("footable-editing-no-delete"),b.allowView||b.ft.$el.addClass("footable-editing-no-view");var d=b.ft.$el.children("tfoot");0==d.length&&(d=a("
",{"class":"footable-editing"})).html(this.title)},parser:function(c){if(b.is.string(c)&&(c=a(a.trim(c))),b.is.element(c)&&(c=a(c)),b.is.jq(c)){var d=c.prop("tagName").toLowerCase();return"td"==d||"th"==d?c.data("value")||c.contents():c}return null},createCell:function(c){var d=this.editing.$rowButtons(),e=a("").append(d);return b.is.jq(c.$el)&&(0===this.index?e.prependTo(c.$el):e.insertAfter(c.$el.children().eq(this.index-1))),new b.Cell(this.ft,c,this,e||e.html())}}),b.columns.register("editing",b.EditingColumn)}(jQuery,FooTable),function(a,b){b.Defaults.prototype.editing={enabled:!1,pageToNew:!0,position:"right",alwaysShow:!1,addRow:function(){},editRow:function(a){},deleteRow:function(a){},viewRow:function(a){},showText:' Edit rows',hideText:"Cancel",addText:"New row",editText:'',deleteText:'',viewText:'',allowAdd:!0,allowEdit:!0,allowDelete:!0,allowView:!1,column:{classes:"footable-editing",name:"editing",title:"",filterable:!1,sortable:!1}}}(jQuery,FooTable),function(a,b){b.is.defined(b.Paging)&&(b.Paging.prototype.unpaged=[],b.Paging.extend("predraw",function(){this.unpaged=this.ft.rows.array.slice(0),this._super()}))}(jQuery,FooTable),function(a,b){b.Row.prototype.add=function(c){c=b.is["boolean"](c)?c:!0;var d=this;return a.Deferred(function(a){var b=d.ft.rows.all.push(d)-1;return c?d.ft.draw().then(function(){a.resolve(b)}):void a.resolve(b)})},b.Row.prototype["delete"]=function(c){c=b.is["boolean"](c)?c:!0;var d=this;return a.Deferred(function(a){var e=d.ft.rows.all.indexOf(d);return b.is.number(e)&&e>=0&&e=0&&e>b&&(f=this.ft.rows.all[b]),f instanceof FooTable.Row&&a.is.hash(c)&&f.val(c,d)},a.Rows.prototype["delete"]=function(b,c){var d=this.ft.rows.all.length,e=b;a.is.number(b)&&b>=0&&d>b&&(e=this.ft.rows.all[b]),e instanceof FooTable.Row&&e["delete"](c)}}(FooTable),function(a,b){var c=0,d=function(a){var b,c,d=2166136261;for(b=0,c=a.length;c>b;b++)d^=a.charCodeAt(b),d+=(d<<1)+(d<<4)+(d<<7)+(d<<8)+(d<<24);return d>>>0}(location.origin+location.pathname);b.State=b.Component.extend({construct:function(a){this._super(a,a.o.state.enabled),this._key="1",this.key=this._key+(b.is.string(a.o.state.key)?a.o.state.key:this._uid()),this.filtering=b.is["boolean"](a.o.state.filtering)?a.o.state.filtering:!0,this.paging=b.is["boolean"](a.o.state.paging)?a.o.state.paging:!0,this.sorting=b.is["boolean"](a.o.state.sorting)?a.o.state.sorting:!0},preinit:function(a){var c=this;this.ft.raise("preinit.ft.state",[a]).then(function(){c.enabled=b.is["boolean"](a.state)?a.state:c.enabled,c.enabled&&(c.key=c._key+(b.is.string(a.stateKey)?a.stateKey:c.key),c.filtering=b.is["boolean"](a.stateFiltering)?a.stateFiltering:c.filtering,c.paging=b.is["boolean"](a.statePaging)?a.statePaging:c.paging,c.sorting=b.is["boolean"](a.stateSorting)?a.stateSorting:c.sorting)},function(){c.enabled=!1})},get:function(a){return JSON.parse(localStorage.getItem(this.key+":"+a))},set:function(a,b){localStorage.setItem(this.key+":"+a,JSON.stringify(b))},remove:function(a){localStorage.removeItem(this.key+":"+a)},read:function(){this.ft.execute(!1,!0,"readState")},write:function(){this.ft.execute(!1,!0,"writeState")},clear:function(){this.ft.execute(!1,!0,"clearState")},_uid:function(){var a=this.ft.$el.attr("id");return d+"_"+(b.is.string(a)?a:++c)}}),b.components.register("state",b.State,700)}(jQuery,FooTable),function(a){a.Component.prototype.readState=function(){},a.Component.prototype.writeState=function(){},a.Component.prototype.clearState=function(){}}(FooTable),function(a){a.Defaults.prototype.state={enabled:!1,filtering:!0,paging:!0,sorting:!0,key:null}}(FooTable),function(a){a.Filtering&&(a.Filtering.prototype.readState=function(){if(this.ft.state.filtering){var b=this.ft.state.get("filtering");a.is.hash(b)&&!a.is.emptyArray(b.filters)&&(this.filters=this.ensure(b.filters))}},a.Filtering.prototype.writeState=function(){if(this.ft.state.filtering){var b=a.arr.map(this.filters,function(b){return{name:b.name,query:b.query instanceof a.Query?b.query.val():b.query,columns:a.arr.map(b.columns,function(a){return a.name}),hidden:b.hidden,space:b.space,connectors:b.connectors,ignoreCase:b.ignoreCase}});this.ft.state.set("filtering",{filters:b})}},a.Filtering.prototype.clearState=function(){this.ft.state.filtering&&this.ft.state.remove("filtering")})}(FooTable),function(a){a.Paging&&(a.Paging.prototype.readState=function(){if(this.ft.state.paging){var b=this.ft.state.get("paging");a.is.hash(b)&&(this.current=b.current,this.size=b.size)}},a.Paging.prototype.writeState=function(){this.ft.state.paging&&this.ft.state.set("paging",{current:this.current,size:this.size})},a.Paging.prototype.clearState=function(){this.ft.state.paging&&this.ft.state.remove("paging")})}(FooTable),function(a){a.Sorting&&(a.Sorting.prototype.readState=function(){if(this.ft.state.sorting){var b=this.ft.state.get("sorting");if(a.is.hash(b)){var c=this.ft.columns.get(b.column);c instanceof a.Column&&(this.column=c,this.column.direction=b.direction)}}},a.Sorting.prototype.writeState=function(){this.ft.state.sorting&&this.column instanceof a.Column&&this.ft.state.set("sorting",{column:this.column.name,direction:this.column.direction})},a.Sorting.prototype.clearState=function(){this.ft.state.sorting&&this.ft.state.remove("sorting")})}(FooTable),function(a){a.Table.extend("_construct",function(a){this.state=this.use(FooTable.State),this._super(a)}),a.Table.extend("_preinit",function(){var a=this;return a._super().then(function(){a.state.enabled&&a.state.read()})}),a.Table.extend("draw",function(){var a=this;return a._super().then(function(){a.state.enabled&&a.state.write()})})}(FooTable); \ No newline at end of file diff --git a/script/footable/footable.standalone.min.css b/script/footable/footable.standalone.min.css new file mode 100644 index 0000000..0ac5adf --- /dev/null +++ b/script/footable/footable.standalone.min.css @@ -0,0 +1 @@ +.footable .btn,.footable .caret{display:inline-block;vertical-align:middle}.footable-details.table,.footable-details.table *,.footable.table,.footable.table *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.footable-details.table th,.footable.table th{text-align:left}.footable-details.table,.footable.table{width:100%;max-width:100%;margin-bottom:20px}.footable-details.table>caption+thead>tr:first-child>td,.footable-details.table>caption+thead>tr:first-child>th,.footable-details.table>colgroup+thead>tr:first-child>td,.footable-details.table>colgroup+thead>tr:first-child>th,.footable-details.table>thead:first-child>tr:first-child>td,.footable-details.table>thead:first-child>tr:first-child>th,.footable.table>caption+thead>tr:first-child>td,.footable.table>caption+thead>tr:first-child>th,.footable.table>colgroup+thead>tr:first-child>td,.footable.table>colgroup+thead>tr:first-child>th,.footable.table>thead:first-child>tr:first-child>td,.footable.table>thead:first-child>tr:first-child>th{border-top:0}.footable-details.table>tbody>tr>td,.footable-details.table>tbody>tr>th,.footable-details.table>tfoot>tr>td,.footable-details.table>tfoot>tr>th,.footable-details.table>thead>tr>td,.footable-details.table>thead>tr>th,.footable.table>tbody>tr>td,.footable.table>tbody>tr>th,.footable.table>tfoot>tr>td,.footable.table>tfoot>tr>th,.footable.table>thead>tr>td,.footable.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.footable-details.table>thead>tr>td,.footable-details.table>thead>tr>th,.footable.table>thead>tr>td,.footable.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.footable-details.table-condensed>tbody>tr>td,.footable-details.table-condensed>tbody>tr>th,.footable-details.table-condensed>tfoot>tr>td,.footable-details.table-condensed>tfoot>tr>th,.footable-details.table-condensed>thead>tr>td,.footable-details.table-condensed>thead>tr>th,.footable.table-condensed>tbody>tr>td,.footable.table-condensed>tbody>tr>th,.footable.table-condensed>tfoot>tr>td,.footable.table-condensed>tfoot>tr>th,.footable.table-condensed>thead>tr>td,.footable.table-condensed>thead>tr>th{padding:5px}.footable-details.table-bordered,.footable-details.table-bordered>tbody>tr>td,.footable-details.table-bordered>tbody>tr>th,.footable-details.table-bordered>tfoot>tr>td,.footable-details.table-bordered>tfoot>tr>th,.footable-details.table-bordered>thead>tr>td,.footable-details.table-bordered>thead>tr>th,.footable.table-bordered,.footable.table-bordered>tbody>tr>td,.footable.table-bordered>tbody>tr>th,.footable.table-bordered>tfoot>tr>td,.footable.table-bordered>tfoot>tr>th,.footable.table-bordered>thead>tr>td,.footable.table-bordered>thead>tr>th{border:1px solid #ddd}.footable-details.table-bordered>thead>tr>td,.footable-details.table-bordered>thead>tr>th,.footable.table-bordered>thead>tr>td,.footable.table-bordered>thead>tr>th{border-bottom-width:2px}.footable-details.table-striped>tbody>tr:nth-child(odd),.footable.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.footable-details.table-hover>tbody>tr:hover,.footable.table-hover>tbody>tr:hover{background-color:#f5f5f5}.footable .btn{padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-appearance:button;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px;overflow:visible;text-transform:none}.footable .btn.focus,.footable .btn:focus,.footable .btn:hover{color:#333;text-decoration:none}.footable .btn-default{color:#333;background-color:#fff;border-color:#ccc}.footable .btn-default.active,.footable .btn-default.focus,.footable .btn-default:active,.footable .btn-default:focus,.footable .btn-default:hover,.footable .open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.footable .btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.footable .btn-primary.active,.footable .btn-primary.focus,.footable .btn-primary:active,.footable .btn-primary:focus,.footable .btn-primary:hover,.footable .open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.footable .btn-group,.footable .btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.footable .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.footable .btn-group>.btn:first-child{margin-left:0}.footable .btn-group-vertical>.btn,.footable .btn-group>.btn{position:relative;float:left}.footable .btn-group-xs>.btn,.footable .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.footable .btn-group-sm>.btn,.footable .btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.footable .btn-group-lg>.btn,.footable .btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.footable .caret{width:0;height:0;margin-left:2px;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.footable .btn .caret{margin-left:0}.form-group{margin-bottom:15px}.footable .form-control{display:block;width:100%;height:34px;padding:6px 12px;margin:0;font-family:inherit;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.footable .input-group{position:relative;display:table;border-collapse:separate}.footable .input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.footable .input-group-btn{position:relative;font-size:0}.footable .input-group-addon,.footable .input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.footable .input-group .form-control,.footable .input-group-addon,.footable .input-group-btn{display:table-cell}.footable .input-group-btn:last-child>.btn,.footable .input-group-btn:last-child>.btn-group,.footable .input-group-btn>.btn+.btn{margin-left:-1px}.footable .input-group-btn>.btn{position:relative}.footable .input-group-btn>.btn:active,.footable .input-group-btn>.btn:focus,.footable .input-group-btn>.btn:hover{z-index:2}.footable .input-group .form-control:first-child,.footable .input-group-addon:first-child,.footable .input-group-btn:first-child>.btn,.footable .input-group-btn:first-child>.btn-group>.btn,.footable .input-group-btn:first-child>.dropdown-toggle,.footable .input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.footable .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.footable .input-group .form-control:last-child,.footable .input-group-addon:last-child,.footable .input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.footable .input-group-btn:first-child>.btn:not(:first-child),.footable .input-group-btn:last-child>.btn,.footable .input-group-btn:last-child>.btn-group>.btn,.footable .input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.footable .checkbox,.footable .radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.footable .checkbox label,.footable .radio label{max-width:100%;min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.footable .checkbox input[type=checkbox],.footable .checkbox-inline input[type=checkbox],.footable .radio input[type=radio],.footable .radio-inline input[type=radio]{position:absolute;margin:4px 0 0 -20px;line-height:normal}.footable .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.footable .open>.dropdown-menu{display:block}.footable .dropdown-menu-right{right:0;left:auto}.footable .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.footable .dropdown-menu>li>a:focus,.footable .dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.footable .pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.footable .pagination>li{display:inline}.footable .pagination>li:first-child>a,.footable .pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.footable .pagination>li>a,.footable .pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.footable .pagination>li>a:focus,.footable .pagination>li>a:hover,.footable .pagination>li>span:focus,.footable .pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.footable .pagination>.active>a,.footable .pagination>.active>a:focus,.footable .pagination>.active>a:hover,.footable .pagination>.active>span,.footable .pagination>.active>span:focus,.footable .pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.footable .pagination>.disabled>a,.footable .pagination>.disabled>a:focus,.footable .pagination>.disabled>a:hover,.footable .pagination>.disabled>span,.footable .pagination>.disabled>span:focus,.footable .pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.footable .label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.footable .label-default{background-color:#777}.footable-loader.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.footable .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}table.footable-details,table.footable>thead>tr.footable-filtering>th div.form-group{margin-bottom:0}@media (min-width:768px){.footable .form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.footable .form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.footable .form-inline .input-group{display:inline-table;vertical-align:middle}.footable .form-inline .input-group .form-control,.footable .form-inline .input-group .input-group-addon,.footable .form-inline .input-group .input-group-btn{width:auto}.footable .form-inline .input-group>.form-control{width:100%}}table.footable,table.footable-details{position:relative;width:100%;border-spacing:0;border-collapse:collapse}table.footable-hide-fouc{display:none}table>tbody>tr>td>span.footable-toggle{margin-right:8px;opacity:.3}table>tbody>tr>td>span.footable-toggle.last-column{margin-left:8px;float:right}table.table-condensed>tbody>tr>td>span.footable-toggle{margin-right:5px}table.footable-details>tbody>tr>th:nth-child(1){min-width:40px;width:120px}table.footable-details>tbody>tr>td:nth-child(2){word-break:break-all}table.footable-details>tbody>tr:first-child>td,table.footable-details>tbody>tr:first-child>th,table.footable-details>tfoot>tr:first-child>td,table.footable-details>tfoot>tr:first-child>th,table.footable-details>thead>tr:first-child>td,table.footable-details>thead>tr:first-child>th{border-top-width:0}table.footable-details.table-bordered>tbody>tr:first-child>td,table.footable-details.table-bordered>tbody>tr:first-child>th,table.footable-details.table-bordered>tfoot>tr:first-child>td,table.footable-details.table-bordered>tfoot>tr:first-child>th,table.footable-details.table-bordered>thead>tr:first-child>td,table.footable-details.table-bordered>thead>tr:first-child>th{border-top-width:1px}div.footable-loader{vertical-align:middle;text-align:center;height:300px;position:relative}div.footable-loader>span.fooicon{display:inline-block;opacity:.3;font-size:30px;line-height:32px;width:32px;height:32px;margin-top:-16px;margin-left:-16px;position:absolute;top:50%;left:50%;-webkit-animation:fooicon-spin-r 2s infinite linear;animation:fooicon-spin-r 2s infinite linear}table.footable>tbody>tr.footable-empty>td{vertical-align:middle;text-align:center;font-size:30px}table.footable>tbody>tr>td,table.footable>tbody>tr>th{display:none}table.footable>tbody>tr.footable-detail-row>td,table.footable>tbody>tr.footable-detail-row>th,table.footable>tbody>tr.footable-empty>td,table.footable>tbody>tr.footable-empty>th{display:table-cell}@-webkit-keyframes fooicon-spin-r{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fooicon-spin-r{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fooicon{display:inline-block;font-size:inherit;font-family:FontAwesome!important;font-style:normal;font-weight:400;line-height:1;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0,0)}.fooicon:after,.fooicon:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fooicon-loader:before{content:"\f01e"}.fooicon-plus:before{content:"\f067"}.fooicon-minus:before{content:"\f068"}.fooicon-search:before{content:"\f002"}.fooicon-remove:before{content:"\f00d"}.fooicon-sort:before{content:"\f0dc"}.fooicon-sort-asc:before{content:"\f160"}.fooicon-sort-desc:before{content:"\f161"}.fooicon-pencil:before{content:"\f040"}.fooicon-trash:before{content:"\f1f8"}.fooicon-eye-close:before{content:"\f070"}.fooicon-flash:before{content:"\f0e7"}.fooicon-cog:before{content:"\f013"}.fooicon-stats:before{content:"\f080"}table.footable>thead>tr.footable-filtering>th{border-bottom-width:1px;font-weight:400}.footable-filtering-external.footable-filtering-right,table.footable.footable-filtering-right>thead>tr.footable-filtering>th,table.footable>thead>tr.footable-filtering>th{text-align:right}.footable-filtering-external.footable-filtering-left,table.footable.footable-filtering-left>thead>tr.footable-filtering>th{text-align:left}.footable-filtering-external.footable-filtering-center,.footable-paging-external.footable-paging-center,table.footable-paging-center>tfoot>tr.footable-paging>td,table.footable.footable-filtering-center>thead>tr.footable-filtering>th,table.footable>tfoot>tr.footable-paging>td{text-align:center}table.footable>thead>tr.footable-filtering>th div.form-group+div.form-group{margin-top:5px}table.footable>thead>tr.footable-filtering>th div.input-group{width:100%}.footable-filtering-external ul.dropdown-menu>li>a.checkbox,table.footable>thead>tr.footable-filtering>th ul.dropdown-menu>li>a.checkbox{margin:0;display:block;position:relative}.footable-filtering-external ul.dropdown-menu>li>a.checkbox>label,table.footable>thead>tr.footable-filtering>th ul.dropdown-menu>li>a.checkbox>label{display:block;padding-left:20px}.footable-filtering-external ul.dropdown-menu>li>a.checkbox input[type=checkbox],table.footable>thead>tr.footable-filtering>th ul.dropdown-menu>li>a.checkbox input[type=checkbox]{position:absolute;margin-left:-20px}@media (min-width:768px){table.footable>thead>tr.footable-filtering>th div.input-group{width:auto}table.footable>thead>tr.footable-filtering>th div.form-group{margin-left:2px;margin-right:2px}table.footable>thead>tr.footable-filtering>th div.form-group+div.form-group{margin-top:0}}table.footable>tbody>tr>td.footable-sortable,table.footable>tbody>tr>th.footable-sortable,table.footable>tfoot>tr>td.footable-sortable,table.footable>tfoot>tr>th.footable-sortable,table.footable>thead>tr>td.footable-sortable,table.footable>thead>tr>th.footable-sortable{position:relative;padding-right:30px;cursor:pointer}td.footable-sortable>span.fooicon,th.footable-sortable>span.fooicon{position:absolute;right:6px;top:50%;margin-top:-7px;opacity:0;transition:opacity .3s ease-in}td.footable-sortable.footable-asc>span.fooicon,td.footable-sortable.footable-desc>span.fooicon,td.footable-sortable:hover>span.fooicon,th.footable-sortable.footable-asc>span.fooicon,th.footable-sortable.footable-desc>span.fooicon,th.footable-sortable:hover>span.fooicon{opacity:1}table.footable-sorting-disabled td.footable-sortable.footable-asc>span.fooicon,table.footable-sorting-disabled td.footable-sortable.footable-desc>span.fooicon,table.footable-sorting-disabled td.footable-sortable:hover>span.fooicon,table.footable-sorting-disabled th.footable-sortable.footable-asc>span.fooicon,table.footable-sorting-disabled th.footable-sortable.footable-desc>span.fooicon,table.footable-sorting-disabled th.footable-sortable:hover>span.fooicon{opacity:0;visibility:hidden}.footable-paging-external ul.pagination,table.footable>tfoot>tr.footable-paging>td>ul.pagination{margin:10px 0 0}.footable-paging-external span.label,table.footable>tfoot>tr.footable-paging>td>span.label{display:inline-block;margin:0 0 10px;padding:4px 10px}.footable-paging-external.footable-paging-left,table.footable-paging-left>tfoot>tr.footable-paging>td{text-align:left}.footable-paging-external.footable-paging-right,table.footable-editing-right td.footable-editing,table.footable-editing-right tr.footable-editing,table.footable-paging-right>tfoot>tr.footable-paging>td{text-align:right}ul.pagination>li.footable-page{display:none}ul.pagination>li.footable-page.visible{display:inline}td.footable-editing{width:90px;max-width:90px}table.footable-editing-no-delete td.footable-editing,table.footable-editing-no-edit td.footable-editing,table.footable-editing-no-view td.footable-editing{width:70px;max-width:70px}table.footable-editing-no-delete.footable-editing-no-view td.footable-editing,table.footable-editing-no-edit.footable-editing-no-delete td.footable-editing,table.footable-editing-no-edit.footable-editing-no-view td.footable-editing{width:50px;max-width:50px}table.footable-editing-no-edit.footable-editing-no-delete.footable-editing-no-view td.footable-editing,table.footable-editing-no-edit.footable-editing-no-delete.footable-editing-no-view th.footable-editing{width:0;max-width:0;display:none!important}table.footable-editing-left td.footable-editing,table.footable-editing-left tr.footable-editing{text-align:left}table.footable-editing button.footable-add,table.footable-editing button.footable-hide,table.footable-editing-show button.footable-show,table.footable-editing.footable-editing-always-show button.footable-hide,table.footable-editing.footable-editing-always-show button.footable-show,table.footable-editing.footable-editing-always-show.footable-editing-no-add tr.footable-editing{display:none}table.footable-editing.footable-editing-always-show button.footable-add,table.footable-editing.footable-editing-show button.footable-add,table.footable-editing.footable-editing-show button.footable-hide{display:inline-block} \ No newline at end of file diff --git a/script/script.js b/script/script.js new file mode 100644 index 0000000..1f7cf8f --- /dev/null +++ b/script/script.js @@ -0,0 +1,109 @@ +/** + * /script/script.js + * @version 2.0 + * @desc Javascript for ajax and for fancy tables + * @author Fándly Gergő Zoltán + * @copy 2017 Fándly Gergő Zoltán + */ + +function ask(q, togo){ + if(confirm(q)){ + window.location=togo; + } +} + +function prompt_go(question, value, todo){ + var reply=prompt(question, value); + if(reply){ + window.location=todo+reply; + } +} + +function disposeMessageOverlay(){ + $("#messageOverlay").html(""); + $("#messageOverlay").css("display", "none"); +} + +jQuery(function($){ + + //loading overlay + $(document).ajaxStart(function(){ + $("#loadingOverlay").css("display", "block"); + }); + $(document).ajaxComplete(function(){ + $("#loadingOverlay").css("display", "none"); + }); + + + //footable + $(".table").footable(); + + + //handle response + function setResponse(response){ + $("#messageOverlay").html(response); + $("#messageOverlay").css("display", "block"); + setTimeout(function(){ + $("#messageOverlay").html(""); + $("#messageOverlay").css("display", "none"); + }, 5000); + } + + //handle form submits + $(".ajaxform").submit(function(e){ + e.preventDefault(); //turn off default handler + + //run ajax request + $.ajax({ + url: e.target.action+"?backend", + type: e.target.method, + data: $(this).serialize(), + success: function(response){ + setResponse(response); + } + }); + + //reset form if data-noreset not specified + if($(this).data("noreset")==undefined){ + e.target.reset(); + } + }); + + + //handle button presses + $(document).on("click", ".ajaxbutton", function(e){ + e.preventDefault(); //turn off default handler + + if($(this).data("confirm")==undefined || confirm($(this).data("confirm"))){ //check if confirmation needed + //prompt for input if needed + var reply=""; + if($(this).data("prompt")!=undefined){ + reply=prompt($(this).data("prompt"), ''); + } + + //build target url + var targetUrl=$(this).data("url")+reply; + if(targetUrl.indexOf("?")){ + targetUrl+="&backend"; + } + else{ + targetUrl+="?backend"; + } + + //run ajax request + $.ajax({ + url: targetUrl, + type: "GET", + success: function(response){ + setResponse(response); + } + }); + + //delete caller button if data-kepp not specified + if($(this).data("keep")==undefined){ + $(this).remove(); + } + } + }); + +}); diff --git a/setup/.htaccess b/setup/.htaccess new file mode 100644 index 0000000..281d5c3 --- /dev/null +++ b/setup/.htaccess @@ -0,0 +1,2 @@ +order allow,deny +deny from all diff --git a/setup/001-generateKey.php b/setup/001-generateKey.php new file mode 100644 index 0000000..c759631 --- /dev/null +++ b/setup/001-generateKey.php @@ -0,0 +1,25 @@ +saveToAsciiSafeString()); +echo "Done! Proceed to step 2!"; +flush(); + +?> diff --git a/setup/002-createAdmin.php b/setup/002-createAdmin.php new file mode 100644 index 0000000..6481548 --- /dev/null +++ b/setup/002-createAdmin.php @@ -0,0 +1,39 @@ +prepare("INSERT INTO users (name, accesslevel, password) VALUES (:name, :accesslevel, :password)"); + $sql->execute(array(":name"=>"Admin", ":accesslevel"=>3, ":password"=>$enc)); + $id=$db->lastInsertId(); + echo "Done!\n\n"; + flush(); + echo "Credintials:\n>username: ".$id."\n>password: ".$passwd; + flush(); + exit(); +} + +?> diff --git a/signupproj.geany b/signupproj.geany new file mode 100644 index 0000000..3d9eac9 --- /dev/null +++ b/signupproj.geany @@ -0,0 +1,67 @@ +[editor] +line_wrapping=false +line_break_column=72 +auto_continue_multiline=true + +[file_prefs] +final_new_line=true +ensure_convert_new_lines=false +strip_trailing_spaces=false +replace_tabs=false + +[indentation] +indent_width=4 +indent_type=0 +indent_hard_tab_width=8 +detect_indent=false +detect_indent_width=false +indent_mode=2 + +[project] +name=SignUp +base_path=H:\\Munkák\\signup +description= + +[long line marker] +long_line_behaviour=1 +long_line_column=72 + +[files] +current_page=35 +FILE_NAME_0=4099;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Clib%5CloginManager%5CloginManager.php;0;4 +FILE_NAME_1=288;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Clib%5CloginManager%5ClmStates.php;0;4 +FILE_NAME_2=207;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Clib%5CloginManager%5ClmHandler.php;0;4 +FILE_NAME_3=469;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Clib%5CloginManager%5ClmConfig.php;0;4 +FILE_NAME_4=1266;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Clib%5CloginManager%5ClmUtils.php;0;4 +FILE_NAME_5=220;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Clib%5CloginManager%5ClmPassword.php;0;4 +FILE_NAME_6=210;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Clib%5CloginManager%5ClmTwoFactor.php;0;4 +FILE_NAME_7=1458;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Cconfig.php;0;4 +FILE_NAME_8=592;Conf;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Cconfig.ini;0;4 +FILE_NAME_9=435;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Clib%5Cfunctions.php;0;4 +FILE_NAME_10=136;None;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Ccryptokey.cnf;0;4 +FILE_NAME_11=1;None;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Callowsignup.cnf;0;4 +FILE_NAME_12=1;None;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Callowlogin.cnf;0;4 +FILE_NAME_13=492;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csetup%5C001-generateKey.php;0;4 +FILE_NAME_14=495;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csetup%5C002-createAdmin.php;0;4 +FILE_NAME_15=33;None;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csetup%5C.htaccess;0;4 +FILE_NAME_16=35;CSS;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cstyle.css;0;4 +FILE_NAME_17=180;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cindex.php;0;4 +FILE_NAME_18=113;None;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5C.htaccess;0;4 +FILE_NAME_19=209;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5C.php;0;4 +FILE_NAME_20=209;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5C.backend.php;0;4 +FILE_NAME_21=11959;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Cprograms.backend.php;0;4 +FILE_NAME_22=2742;SQL;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Cdb.sql;0;4 +FILE_NAME_23=93;Javascript;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cscript%5Cscript.js;0;4 +FILE_NAME_24=42;CSS;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cstyle_mobile.css;0;4 +FILE_NAME_25=31;None;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5C.htaccess;0;4 +FILE_NAME_26=13449;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Cprograms.php;0;4 +FILE_NAME_27=4068;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Ctimetable.php;0;4 +FILE_NAME_28=6651;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Ctimetable.backend.php;0;4 +FILE_NAME_29=2576;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Ctimetable_programs.php;0;4 +FILE_NAME_30=257;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Ctimetable_programs.backend.php;0;4 +FILE_NAME_31=2425;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Cusers.php;0;4 +FILE_NAME_32=4439;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Cusers.backend.php;0;4 +FILE_NAME_33=31;None;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5C.htaccess;0;4 +FILE_NAME_34=2881;Conf;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Cconfig%5Clang%5Chun.ini;0;4 +FILE_NAME_35=1628;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Cadmin.php;0;4 +FILE_NAME_36=170;PHP;0;EUTF-8;0;1;0;H%3A%5CMunkák%5Csignup%5Csubs%5Cadmin.backend.php;0;4 diff --git a/style.css b/style.css new file mode 100644 index 0000000..b4a4749 --- /dev/null +++ b/style.css @@ -0,0 +1,191 @@ +/** + * /style.css + * @version 1.2 + * @desc fancy css + * @author Fándly Gergő Zoltán + * @copy 2017 Fándly Gergő Zoltán + */ + +h1.title{ + text-align: left; + background: rgba(31,73,125,0.8); + color: rgb(255,255,255); + margin: auto; + padding: 0.3em 1em; +} + +button{ + background: rgba(31,73,125,0.8); + color: rgb(255,255,255); + padding: 1em; + border-radius: 0.5em; +} +button:hover{ + background: rgba(31,73,125,1); +} + +fieldset{ + border: 5px solid rgba(31,73,125,0.8); + background: rgb(220,220,220); + border-radius: 1em; + padding: 2em; + width: 60%; + text-align: left; +} +fieldset legend{ + background: rgba(31,73,125,0.8); + color: rgb(255,255,255); + padding: 0.3em; + font-size: 2em; + border-radius: 0.5em; + box-shadow: 0 0 0 5px rgb(220,220,220); + text-align:left; + margin-left: 10%; +} + +footer{ + background: rgb(200,200,200); + border-radius: 1em; + width: 80%; + margin: auto; + font-size: 0.8em; + text-align: center; + padding: 0.3em; +} + +hr.placeholder{ + border: none; + height: 30px; +} + +input{ + border-radius: 5px; + padding: 0.5em; + border: 1px solid solid rgba(31,73,125,0.8); +} +textarea{ + border-radius: 5px; + padding: 0.5em; + border: 1px solid solid rgba(31,73,125,0.8); +} +select{ + border-radius: 5px; + padding: 0.5em; + border: 1px solid solid rgba(31,73,125,0.8); +} + +div.message{ + width: 50%; + padding: 1em; + border: 2px solid rgb(60, 255, 60); + border-radius: 10px; + margin: auto; + margin-top: 1.5em; + margin-bottom: 1.5em; + background: rgba(0, 255, 0, 0.8); + text-align: center; +} +div.message.error{ + border: 2px solid rgb(255, 60, 60); + background: rgba(255, 0, 0, 0.8); +} + +ul.menu{ + list-style:none; + margin: 0; + background: rgba(31,73,125,0.8); + display: flex; + justify-content: space-around; +} +ul.menu li{ + display: block; + padding: 1em; + color: rgb(255,255,255); +} +ul.menu li:hover{ + background: rgba(31,73,125,1); +} +ul.menu a{ + text-decoration: none; +} + +td{ + vertical-align: top; +} + +span.password{ + background: rgb(0,0,0); + font-family: Courier New; +} +span.password:hover{ + background: inherit; +} + +div.overlay{ + position: fixed; + display: none; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 2; +} +div.overlay.loading{ + background: rgba(0,0,0,0.7); +} +div.overlay.loading img{ + position: fixed; + max-width: 50%; + max-height: 50%; + top: 30%; + left: 40%; + padding: 1em; +} +div.overlay.messages{ + height: 30%; +} + +/* the world's fanciest checkbox */ +div.checkbox{ + width: 7em; + height: 2.5em; + background: rgb(140, 140, 140); + border-radius: 1.5em; + position: relative; +} +div.checkbox:before{ + content: 'On'; + position: absolute; + top: 30%; + left: 15%; + color: rgb(35, 200, 40); + font-size: 1em; +} +div.checkbox:after{ + content: 'Off'; + position: absolute; + top: 30%; + right: 15%; + color: rgb(15, 15, 15); + font-size: 1em; +} +div.checkbox label{ + display: block; + width: 45%; + height: 55%; + border-radius: 1.5em; + transition: 0.5s; + cursor: pointer; + position: absolute; + top: 22.5%; + left: 10%; + z-index: 1; + background: rgb(220, 220, 220); +} +div.checkbox input[type=checkbox]:checked + label{ + left: 45%; + background: rgb(35, 200, 40); +} +div.checkbox input[type=checkbox]{ + display: none; +} diff --git a/style_mobile.css b/style_mobile.css new file mode 100644 index 0000000..a6e2280 --- /dev/null +++ b/style_mobile.css @@ -0,0 +1,221 @@ +/** + * /style_mobile.css + * @version 1.2 + * @desc fancy css even for mobile devices! + * @author Fándly Gergő Zoltán + * @copy 2017 Fándly Gergő Zoltán + */ + +h1.title{ + text-align: left; + background: rgba(31,73,125,0.8); + color: rgb(255,255,255); + margin: auto; + padding: 0.3em 1em; +} + +button{ + background: rgba(31,73,125,0.8); + color: rgb(255,255,255); + padding: 1em; + border-radius: 0.5em; + width: 100%; + font-size: 2em; +} +button:hover{ + background: rgba(31,73,125,1); +} + +form{ + width: 100%; +} +fieldset{ + border: 5px solid rgba(31,73,125,0.8); + background: rgb(220,220,220); + border-radius: 1em; + padding: 2em; + width: 90%; + text-align: left; +} +fieldset legend{ + background: rgba(31,73,125,0.8); + color: rgb(255,255,255); + padding: 0.3em; + font-size: 2em; + border-radius: 0.5em; + box-shadow: 0 0 0 5px rgb(220,220,220); + text-align:left; + margin-left: 10%; +} + +footer{ + background: rgb(200,200,200); + border-radius: 1em; + width: 90%; + margin: auto; + font-size: 0.8em; + text-align: center; + padding: 0.3em; +} + +hr.placeholder{ + border: none; + height: 30px; +} + +input{ + border-radius: 5px; + padding: 0.5em; + border: 1px solid solid rgba(31,73,125,0.8); + font-size: 1.5em; +} +textarea{ + border-radius: 5px; + padding: 0.5em; + border: 1px solid solid rgba(31,73,125,0.8); + font-size: 1.5em; +} +select{ + border-radius: 5px; + padding: 0.5em; + border: 1px solid solid rgba(31,73,125,0.8); + font-size: 1.5em; + max-width: 90%; +} + +div.message{ + width: 90%; + padding: 1em; + border: 2px solid rgb(60, 255, 60); + border-radius: 10px; + margin: auto; + margin-top: 1.5em; + margin-bottom: 1.5em; + background: rgba(0, 255, 0, 0.5); + text-align: center; + font-size: 1.5em; +} +div.message.error{ + border: 2px solid rgb(255, 60, 60); + background: rgba(255, 0, 0, 0.5); +} + +ul.menu{ + list-style:none; + margin: 0; + background: rgba(31,73,125,0.8); + display: flex; + justify-content: stretch; + flex-wrap: wrap; + font-size: 2em; +} +ul.menu li{ + display: block; + padding: 1em; + color: rgb(255,255,255); + width; 95%; +} +ul.menu li:hover{ + background: rgba(31,73,125,1); +} +ul.menu a{ + text-decoration: none; + width: 95%; +} + +td{ + vertical-align: top; +} + +span.password{ + background: rgb(0,0,0); + font-family: Courier New; +} +span.password:hover{ + background: inherit; +} + +table:not(.table) td{ + display: block; +} + +label{ + font-size: 1.5em; +} + +table{ + font-size: 1.5em; +} + +p{ + font-size: 1.5em; +} + +div.overlay{ + position: fixed; + display: none; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 2; +} +div.overlay.loading{ + background: rgba(0,0,0,0.7); +} +div.overlay.loading img{ + position: fixed; + max-width: 50%; + max-height: 50%; + top: 30%; + left: 40%; + padding: 1em; +} +div.overlay.messages{ + height: 30%; +} + +/* the world's fanciest checkbox */ +div.checkbox{ + width: 7em; + height: 2.5em; + background: rgb(140, 140, 140); + border-radius: 1.5em; + position: relative; +} +div.checkbox:before{ + content: 'On'; + position: absolute; + top: 30%; + left: 15%; + color: rgb(35, 200, 40); + font-size: 1em; +} +div.checkbox:after{ + content: 'Off'; + position: absolute; + top: 30%; + right: 15%; + color: rgb(15, 15, 15); + font-size: 1em; +} +div.checkbox label{ + display: block; + width: 45%; + height: 55%; + border-radius: 1.5em; + transition: 0.5s; + cursor: pointer; + position: absolute; + top: 22.5%; + left: 10%; + z-index: 1; + background: rgb(220, 220, 220); +} +div.checkbox input[type=checkbox]:checked + label{ + left: 45%; + background: rgb(35, 200, 40); +} +div.checkbox input[type=checkbox]{ + display: none; +} diff --git a/subs/.backend.php b/subs/.backend.php new file mode 100644 index 0000000..ffa58e1 --- /dev/null +++ b/subs/.backend.php @@ -0,0 +1,8 @@ + + +
+

+
diff --git a/subs/admin.backend.php b/subs/admin.backend.php new file mode 100644 index 0000000..4780f18 --- /dev/null +++ b/subs/admin.backend.php @@ -0,0 +1,44 @@ +=3){ + if(isset($_POST['ms_post'])){ + if(!file_put_contents("./config/allowlogin.cnf", (isset($_POST['allow_login'])?1:0)) || !file_put_contents("./config/allowsignup.cnf", (isset($_POST['allow_signup'])?1:0))){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./admin"); + } + else{ + functions::setMessage(7); + if(!isset($_GET['backend'])) header("Location: ./admin"); + } + } + + if(isset($_POST['set_tsas_id'])){ + $sql=$db->prepare("SELECT COUNT(id) AS count FROM time_sequences WHERE id=:id"); + $sql->execute(array(":id"=>$_POST['set_tsas_id'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + if($res['count']<1){ + functions::setError(7); + if(!isset($_GET['backend'])) header("Location: ./admin"); + } + else{ + $sql=$db->prepare("UPDATE time_sequences SET allow_signup=:as WHERE id=:id"); + $sql->execute(array(":as"=>(isset($_POST['set_tsas'])?1:0), ":id"=>$_POST['set_tsas_id'])); + $res=$sql->rowCount(); + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./admin"); + } + else{ + functions::setMessage(7); + if(!isset($_GET['backend'])) header("Location: ./admin"); + } + } + } +} diff --git a/subs/admin.php b/subs/admin.php new file mode 100644 index 0000000..1a0d0c5 --- /dev/null +++ b/subs/admin.php @@ -0,0 +1,74 @@ + + +
+

+
+
+ + +
+ +
+

+
+ id="o_" onchange="$('#master_switch_form').submit()"> + +
+
+
+

+
+ id="o_" onchange="$('#master_switch_form').submit()"> + +
+
+
+ +
+
+
+ +
+ + + + + + + + + + prepare("SELECT id, name, allow_signup FROM time_sequences ORDER BY id ASC"); + $sql->execute(); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + $oid++; + } + ?> + +
".$row['id']."".$row['name'].""; + echo "
"; + echo ""; + echo "
"; + echo ""; + echo ""; + echo "
"; + echo "
"; + echo "
+
+
+
diff --git a/subs/programs.backend.php b/subs/programs.backend.php new file mode 100644 index 0000000..5a5cf3d --- /dev/null +++ b/subs/programs.backend.php @@ -0,0 +1,299 @@ +=2){ //just for elevated users + /* + * Add new entries + */ + if(isset($_POST['nts_name'])){ + $sql=$db->prepare("SELECT COUNT(id) AS count FROM time_sequences WHERE name=:name"); + $sql->execute(array(":name"=>$_POST['nts_name'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']>0){ + functions::setError(5); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + $sql=$db->prepare("INSERT INTO time_sequences (name) VALUES (:name)"); + $sql->execute(array(":name"=>$_POST['nts_name'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + functions::setMessage(3); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + } + } + if(isset($_POST['ntb_name']) && isset($_POST['ntb_timesequence'])){ + $sql=$db->prepare("SELECT COUNT(id) AS count FROM time_blocks WHERE name=:name and sequence=:seq"); + $sql->execute(array(":name"=>$_POST['ntb_name'], ":seq"=>$_POST['ntb_timesequence'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']>0){ + functions::setError(5); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + $sql=$db->prepare("INSERT INTO time_blocks (name, sequence) VALUES (:name, :seq)"); + $sql->execute(array(":name"=>$_POST['ntb_name'], ":seq"=>$_POST['ntb_timesequence'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + functions::setMessage(3); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + } + } + if(isset($_POST['n_name']) && isset($_POST['n_description']) && isset($_POST['n_instructor']) && isset($_POST['n_location']) && isset($_POST['n_category']) && isset($_POST['n_timeblock']) && isset($_POST['n_maxpart'])){ + $sql=$db->prepare("INSERT INTO programs (name, description, instructor, location, category, time_block, max_participants) VALUES (:name, :desc, :inst, :loc, :cat, :tb, :maxpart)"); + $sql->execute(array(":name"=>$_POST['n_name'], ":desc"=>$_POST['n_description'], ":inst"=>$_POST['n_instructor'], ":loc"=>$_POST['n_location'], ":cat"=>$_POST['n_category'], ":tb"=>$_POST['n_timeblock'], ":maxpart"=>$_POST['n_maxpart'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + functions::setMessage(3); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + } + + + /* + * delete entry + */ + if(isset($_GET['ts_delete'])){ + $sql=$db->prepare("DELETE FROM time_sequences WHERE id=:id"); + $sql->execute(array(":id"=>$_GET['ts_delete'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + functions::setMessage(4); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + } + if(isset($_GET['tb_delete'])){ + $sql=$db->prepare("DELETE FROM time_blocks WHERE id=:id"); + $sql->execute(array(":id"=>$_GET['tb_delete'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + functions::setMessage(4); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + } + if(isset($_GET['delete'])){ + $sql=$db->prepare("DELETE FROM programs WHERE id=:id"); + $sql->execute(array(":id"=>$_GET['delete'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + functions::setMessage(4); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + } +} + + +/* + * Subscribe/unsubscribe + */ +if($_SESSION['accesslevel']==0){ //only they need it + if(isset($_GET['sub'])){ + if((!$config['allowsignup'] && $_SESSION['except_signup']!=1) || $_SESSION['except_signup']==2){ //check if signup allowed + functions::setError(11); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + $sql=$db->prepare("SELECT COUNT(p.id) AS count, p.category, p.time_block, p.max_participants, (SELECT COUNT(r.id) FROM registrations AS r WHERE r.program=p.id) AS cur_participants, ts.allow_signup FROM programs AS p INNER JOIN time_blocks AS tb ON (tb.id=p.time_block) INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence) WHERE p.id=:id"); + $sql->execute(array(":id"=>$_GET['sub'])); + $prog=$sql->fetch(PDO::FETCH_ASSOC); + + if($prog['count']<1){ //check if exists + functions::setError(7); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + if($prog['cur_participants']>=$prog['max_participants']){ //check if not full + functions::setError(8); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + $sql=$db->prepare("SELECT COUNT(r.id) AS count FROM registrations AS r INNER JOIN programs AS p ON (p.id=r.program) WHERE r.user=:uid and p.time_block=:tb"); + $sql->execute(array(":uid"=>$_SESSION['id'], ":tb"=>$prog['time_block'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']>0){ //check if not occupied on that time + functions::setError(9); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + if($prog['category']!=$cat1 && $prog['category']!=$cat2 && $prog['category']!=$cat3){ //check if category coresponds + functions::setError(10); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + if($prog['allow_signup']!=1){ //check if it is actually possible to sign up to this + functions::setError(13); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + //subscribe + $sql=$db->prepare("INSERT INTO registrations(user, program) VALUES (:uid, :pid)"); + $sql->execute(array(":uid"=>$_SESSION['id'], ":pid"=>$_GET['sub'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + //add to history + $sql=$db->prepare("INSERT INTO registration_log (user, date, action, program) VALUES (:uid, :date, :act, :pid)"); + $sql->execute(array(":uid"=>$_SESSION['id'], ":date"=>date("Y-m-d H:i:s"), ":act"=>1, ":pid"=>$_GET['sub'])); + functions::setMessage(5); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + } + } + } + } + } + } + } + if(isset($_GET['unsub'])){ + if((!$config['allowsignup'] && $_SESSION['except_signup']!=1) || $_SESSION['except_signup']==2){ //check if signup allowed + functions::setError(11); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + $sql=$db->prepare("SELECT COUNT(id) AS count FROM registrations WHERE user=:uid and program=:pid"); + $sql->execute(array(":uid"=>$_SESSION['id'], ":pid"=>$_GET['unsub'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']<1){ //check if signed up + functions::setError(7); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + $sql=$db->prepare("SELECT ts.allow_signup FROM registrations AS r INNER JOIN programs AS p ON (p.id=r.program) INNER JOIN time_blocks AS tb ON (tb.id=p.time_block) INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence) WHERE user=:uid and program=:pid"); + $sql->execute(array(":uid"=>$_SESSION['id'], ":pid"=>$_GET['unsub'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + if($res['allow_signup']!=1){ //check if signup/down allowed + functions::setError(13); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + //unsubscribe + $sql=$db->prepare("DELETE FROM registrations WHERE user=:uid and program=:pid"); + $sql->execute(array(":uid"=>$_SESSION['id'], ":pid"=>$_GET['unsub'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + else{ + //add to history + $sql=$db->prepare("INSERT INTO registration_log (user, date, action, program) VALUES (:uid, :date, :act, :pid)"); + $sql->execute(array(":uid"=>$_SESSION['id'], ":date"=>date("Y-m-d H:i:s"), ":act"=>0, ":pid"=>$_GET['unsub'])); + functions::setMessage(6); + if(!isset($_GET['backend'])) header("Location: ./programs"); + } + } + } + } + } +} + + +/* + * Main query + */ +$msql=$db->prepare("SELECT p.id, p.name, p.description, p.instructor, p.location, p.category, tb.name AS time_block, ts.name AS time_sequence, p.max_participants, (SELECT COUNT(r.id) FROM registrations AS r WHERE r.program=p.id) AS cur_participants FROM programs AS p INNER JOIN time_blocks AS tb ON (tb.id=p.time_block) INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence) ".$where." GROUP BY(p.id) ORDER BY p.name ASC"); +$msql->execute(); + +/* + * EXPORT + */ +if(isset($_GET['export'])){ + $csv=$BOM; + $csv.=$config['general']['org']."\n".$config['general']['title']."\n\n"; + $csv.=$lang['id'].";".$lang['name'].";".$lang['description'].";".$lang['instructor'].";".$lang['location'].";".$lang['category'].";".$lang['timeblock'].";".$lang['maxpart'].";".$lang['curpart']."\n"; + + while($row=$msql->fetch(PDO::FETCH_ASSOC)){ + $csv.=$row['id'].";".$row['name'].";".$row['description'].";".$row['instructor'].";".$row['location'].";".$lang['cat'][$row['category']].";".$row['time_sequence']."/".$row['time_block'].";".$row['max_participants'].";".$row['cur_participants']."\n"; + } + + //print + header("Content-type: application/octet-stream"); + //header("Content-length: ".mb_strlen($csv)); + header("Content-disposition: attachment; filename='".$config['general']['title']."_programs_export_".date("Y-m-d H-i-s").".csv'"); + echo $csv; + die(); +} diff --git a/subs/programs.php b/subs/programs.php new file mode 100644 index 0000000..63f3931 --- /dev/null +++ b/subs/programs.php @@ -0,0 +1,245 @@ + + +
+ =2): ?> +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
" required>
" required>
" required>
+
+
+
+
+
+
+
+
+
+
+
+ +
+ prepare("SELECT tb.id, ts.name AS ts_name, tb.name AS tb_name FROM time_blocks AS tb INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence)"); + $sql->execute(); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + echo "
"; + $oid++; + } + ?> +
" required min=1>
+
+
+ +
+
+
+
+
+
+
+
+ +
+ + + + + +
" required>
+
+
+ +
+
+
+
+ + + + + + + + + + prepare("SELECT id, name FROM time_sequences ORDER BY name ASC"); + $sql->execute(); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + ?> + +
".$row['id']."".$row['name'].""; + echo ""; + echo "
+
+
+
+
+
+ +
+ + + + + + + + + +
+ +
+ +
" required>
+ prepare("SELECT id, name FROM time_sequences ORDER BY name ASC"); + $sql->execute(); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + echo "
"; + $oid++; + } + ?> +
+
+
+ +
+
+
+
+ + + + + + + + + + + prepare("SELECT tb.id, tb.name, ts.name AS time_sequence FROM time_blocks AS tb INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence) ORDER BY ts.name ASC, tb.name ASC"); + $sql->execute(); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + ?> + +
".$row['id']."".$row['time_sequence']."".$row['name'].""; + echo ""; + echo "
+
+
+
+ +

+
+ + + + + + + + + + + + + + + + + fetch(PDO::FETCH_ASSOC)){ + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + + echo ""; + echo ""; + } + ?> + +
".$row['id']."".$row['name']."".$row['description']."".$row['instructor']."".$row['location']."".$lang['cat'][$row['category']]."".$row['time_sequence']."/".$row['time_block']."".$row['max_participants']."".$row['cur_participants'].""; + if($_SESSION['accesslevel']<1){ + if($row['cur_participants']<$row['max_participants']){ + echo ""; + } + else{ + echo "-"; + } + } + else if($_SESSION['accesslevel']>=2){ + echo ""; + } + else{ + echo "-"; + } + echo "
+
+ +
diff --git a/subs/timetable.backend.php b/subs/timetable.backend.php new file mode 100644 index 0000000..35b8f77 --- /dev/null +++ b/subs/timetable.backend.php @@ -0,0 +1,292 @@ +=2){ + if(isset($_GET['delete'])){ + $sql=$db->prepare("SELECT COUNT(id) AS count, user, program FROM registrations WHERE id=:id"); + $sql->execute(array(":id"=>$_GET['delete'])); + $reg=$sql->fetch(PDO::FETCH_ASSOC); + + if($reg['count']<1){ + functions::setError(7); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ + $sql=$db->prepare("DELETE FROM registrations WHERE id=:id"); + $sql->execute(array(":id"=>$_GET['delete'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ + //keep history integrity + $sql=$db->prepare("INSERT INTO registration_log (user, date, action, program) VALUES (:uid, :date, :act, :pid)"); + $sql->execute(array(":uid"=>$reg['user'], ":date"=>date("Y-m-d H:i:s"), ":act"=>10, ":pid"=>$reg['program'])); + + functions::setMessage(4); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + } + } + + //force add + if(isset($_POST['fa_user']) && isset($_POST['fa_program'])){ + $sql=$db->prepare("SELECT COUNT(id) AS count FROM users WHERE id=:uid"); + $sql->execute(array(":uid"=>$_POST['fa_user'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']<1){ //check if user exists + functions::setError(7); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ + $sql=$db->prepare("SELECT COUNT(id) AS count, time_block FROM programs WHERE id=:pid"); + $sql->execute(array(":pid"=>$_POST['fa_program'])); + $prog=$sql->fetch(PDO::FETCH_ASSOC); + + if($prog['count']<1){ //check if program exists + functions::setError(7); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ + $sql=$db->prepare("SELECT COUNT(r.id) AS count FROM registrations AS r INNER JOIN programs AS p ON (p.id=r.program) WHERE r.user=:uid and p.time_block=:tb"); + $sql->execute(array(":uid"=>$_POST['fa_user'], ":tb"=>$prog['time_block'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']>0){ //check if not occupied + functions::setError(12); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ //do this! + $sql=$db->prepare("INSERT INTO registrations (user, program) VALUES (:uid, :pid)"); + $sql->execute(array(":uid"=>$_POST['fa_user'], ":pid"=>$_POST['fa_program'])); + $res=$sql->rowCount(); + + if($res<1){ //check insert failure + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ + //keep history integrity + $sql=$db->prepare("INSERT INTO registration_log (user, date, action, program) VALUES (:uid, :date, :act, :pid)"); + $sql->execute(array(":uid"=>$_POST['fa_user'], ":date"=>date("Y-m-d H:i:s"), ":act"=>11, ":pid"=>$_POST['fa_program'])); + + functions::setMessage(3); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + } + } + } + } + if(isset($_POST['fa_class']) && isset($_POST['fa_program'])){ + $sql=$db->prepare("SELECT COUNT(id) AS count FROM users WHERE class=:c"); + $sql->execute(array(":c"=>$_POST['fa_class'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']<1){ //check if class exists + functions::setError(7); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ + $sql=$db->prepare("SELECT COUNT(id) AS count, time_block FROM programs WHERE id=:pid"); + $sql->execute(array(":pid"=>$_POST['fa_program'])); + $prog=$sql->fetch(PDO::FETCH_ASSOC); + + if($prog['count']<1){ //check if program exists + functions::setError(7); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ + $sql=$db->prepare("SELECT COUNT(r.id) AS count, r.id FROM registrations AS r INNER JOIN programs AS p ON (p.id=r.program) INNER JOIN users AS u ON (u.id=r.user) WHERE u.class=:c and u.accesslevel=0 and p.time_block=:tb"); + $sql->execute(array(":c"=>$_POST['fa_class'], ":tb"=>$prog['time_block'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']>0){ //check if not occupied + functions::setError(12); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ //do this! + $sql=$db->prepare("INSERT INTO registrations (user, program) SELECT id, :pid FROM users WHERE class=:c and accesslevel=0"); + $sql->execute(array(":c"=>$_POST['fa_class'], ":pid"=>$_POST['fa_program'])); + $res=$sql->rowCount(); + + if($res<1){ //check insert failure + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + else{ + //keep history integrity + $sql=$db->prepare("INSERT INTO registration_log (user, date, action, program) SELECT id, :date, :act, :pid FROM users WHERE class=:c and accesslevel=0"); + $sql->execute(array(":c"=>$_POST['fa_class'], ":date"=>date("Y-m-d H:i:s"), ":act"=>11, ":pid"=>$_POST['fa_program'])); + + functions::setMessage(3); + if(!isset($_GET['backend'])) header("Location: ./timetable"); + } + } + } + } + } + + $msql=$db->prepare("SELECT id, name, class FROM users WHERE id<>1 and accesslevel=0 ORDER BY class ASC, name ASC"); + $msql->execute(); +} + +if($_SESSION['accesslevel']==1){ + $msql=$db->prepare("SELECT id, name, class FROM users WHERE id<>1 and accesslevel=0 and class=:class ORDER BY name ASC"); + $msql->execute(array(":class"=>$_SESSION['class'])); +} + +if($_SESSION['accesslevel']<1){ + $msql=$db->prepare("SELECT p.id, p.name, p.description, p.instructor, p.location, tb.name AS time_block, ts.name AS time_sequence FROM registrations AS r INNER JOIN programs AS p ON (p.id=r.program) INNER JOIN time_blocks AS tb ON (tb.id=p.time_block) INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence) WHERE r.user=:uid ORDER BY ts.id ASC, tb.name ASC, p.name ASC"); + $msql->execute(array(":uid"=>$_SESSION['id'])); +} + +/* + * EXPORT + */ +if(isset($_GET['export']) && $_SESSION['accesslevel']>=1){ + $csv=$BOM; + $csv.=$config['general']['org']."\n".$config['general']['title']."\n\n"; + + $prog=""; + $sql=$db->prepare("SELECT tb.id, ts.name AS time_sequence, tb.name AS time_block FROM time_blocks AS tb INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence) ORDER BY ts.id ASC, tb.name ASC"); + $sql->execute(); + $tbs=array(); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + $prog.=$row['time_sequence']."/".$row['time_block'].";"; + array_push($tbs, $row['id']); + } + $prog=rtrim($prog, ";"); + + $csv.=$lang['uid'].";".$lang['name'].";".$lang['class'].";".$prog."\n"; + + while($row=$msql->fetch(PDO::FETCH_ASSOC)){ + $i=0; + $prog=""; + $sql=$db->prepare("SELECT r.id AS regid, tb.id AS time_block, p.name FROM registrations AS r INNER JOIN programs AS p ON (p.id=r.program) INNER JOIN time_blocks AS tb ON (tb.id=p.time_block) WHERE r.user=:uid ORDER BY tb.sequence ASC, tb.name ASC"); + $sql->execute(array(":uid"=>$row['id'])); + while($row2=$sql->fetch(PDO::FETCH_ASSOC)){ + while($row2['time_block']!=$tbs[$i]){ + $prog.="-;"; + $i++; + } + $prog.=$row2['name'].";"; + $i++; + } + for(;$i"; + $html.="
"; + $html.="

".$config['general']['title']."

"; + $html.="

".$config['general']['org']."

"; + $html.="
"; + $html.="

".$lang['name'].": ".$_SESSION['name']." | ".$lang['class'].": ".$_SESSION['class']." | ".$lang['studentprinted']."

"; + + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + + while($row=$msql->fetch(PDO::FETCH_ASSOC)){ + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + } + + $html.="
".$lang['timeblock']."".$lang['progname']."".$lang['instructor']."".$lang['signature']."
".$row['time_sequence']."
".$row['time_block']."
".$row['name']."".$row['instructor']."
"; + + $html.="
"; + + echo "
".$html."
"; + die(); + } + else{ + $html=""; + $second=false; + + while($row=$msql->fetch(PDO::FETCH_ASSOC)){ + //header + if(!$second){ + $html.=""; + } + //content + $html.=""; + $html.=""; + $html.=""; + + if($second){ + $html.="
"; + $html.="

".$config['general']['title']."

"; + $html.="

".$config['general']['org']."

"; + $html.="
"; + $html.="

".$lang['name'].": ".$row['name']." | ".$lang['class'].": ".$row['class']."

"; + + //programs + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + + //subquerry + $sql=$db->prepare("SELECT tb.name AS time_block, ts.name AS time_sequence, p.instructor, p.name FROM registrations AS r INNER JOIN programs AS p ON (p.id=r.program) INNER JOIN time_blocks AS tb ON (tb.id=p.time_block) INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence) WHERE r.user=:uid ORDER BY ts.id ASC, tb.name ASC"); + $sql->execute(array(":uid"=>$row['id'])); + while($row2=$sql->fetch(PDO::FETCH_ASSOC)){ + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + $html.=""; + } + + $html.="
".$lang['timeblock']."".$lang['progname']."".$lang['instructor']."".$lang['signature']."
".$row2['time_sequence']."
".$row2['time_block']."
".$row2['name']."".$row2['instructor']."
"; + $html.="
"; + } + + $second=!$second; + } + + echo "
".$html."
"; + die(); + } +} diff --git a/subs/timetable.php b/subs/timetable.php new file mode 100644 index 0000000..0351537 --- /dev/null +++ b/subs/timetable.php @@ -0,0 +1,186 @@ + + +
+ =2): ?> +
+
+
+ +
+

+ + + + + + + + + + + + + +
+ +
".$lang['orthis']." ".$lang['class'].": " ?> + +
+ +
+
+
+ +
+
+
+
+
+ +

+
+ + + + + + + + + + + + + + + fetch(PDO::FETCH_ASSOC)){ + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + ?> + +
".$row['id']."".$row['name']."".$row['description']."".$row['instructor']."".$row['location']."".$row['time_sequence']."/".$row['time_block']."
+ =1): ?> + + + + + + + prepare("SELECT tb.id, ts.name AS time_sequence, tb.name AS time_block FROM time_blocks AS tb INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence) ORDER BY ts.id ASC, tb.name ASC"); + $sql->execute(); + $tbs=array(); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + echo ""; + array_push($tbs, $row['id']); + } + ?> + + + + fetch(PDO::FETCH_ASSOC)){ + echo ""; + echo ""; + echo ""; + echo ""; + $i=0; + $sql=$db->prepare("SELECT r.id AS regid, tb.id AS time_block, p.name FROM registrations AS r INNER JOIN programs AS p ON (p.id=r.program) INNER JOIN time_blocks AS tb ON (tb.id=p.time_block) WHERE r.user=:uid ORDER BY tb.sequence ASC, tb.name ASC"); + $sql->execute(array(":uid"=>$row['id'])); + while($row2=$sql->fetch(PDO::FETCH_ASSOC)){ + while($row2['time_block']!=$tbs[$i]){ + echo ""; + $i++; + } + echo ""; + $i++; + } + for(;$i-"; + } + echo ""; + } + ?> + +
".$row['time_sequence']."
".$row['time_block']."
".$row['id']."".$row['name']."".$row['class']."-"; + echo $row2['name']; + if($_SESSION['accesslevel']>=2){ + echo ""; + } + echo "
+ +
+ + =2 && $config['general']['programs_needed']!=0): ?> +
+

+ + + + + + + + + + prepare("SELECT u.id, u.name, u.class, (SELECT COUNT(r.id) AS count FROM registrations AS r WHERE r.user=u.id) AS progcount FROM users AS u WHERE u.accesslevel=0 and u.id<>1 and (SELECT COUNT(r.id) AS count FROM registrations AS r WHERE r.user=u.id)<:pc GROUP BY (u.id)"); + $sql->execute(array(":pc"=>$config['general']['programs_needed'])); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + ?> + +
".$row['id']."".$row['name']."".$row['class']."".$row['progcount']."
+ +
diff --git a/subs/timetable_programs.backend.php b/subs/timetable_programs.backend.php new file mode 100644 index 0000000..049fddc --- /dev/null +++ b/subs/timetable_programs.backend.php @@ -0,0 +1,13 @@ + + +
+

+
+
+
+
+ prepare("SELECT p.id, p.name, p.instructor, p.location, ts.name AS time_sequence, tb.name AS time_block FROM programs AS p INNER JOIN time_blocks AS tb ON (tb.id=p.time_block) INNER JOIN time_sequences AS ts ON (ts.id=tb.sequence) ORDER BY p.name ASC, ts.id ASC, tb.name ASC"); + $sql->execute(); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + echo "
"; + echo "

".$row['name']."

"; + echo "
"; + echo "

".$lang['instructor'].": ".$row['instructor']." | ".$lang['location'].": ".$row['location']." | ".$lang['timeblock'].": ".$row['time_sequence']."/".$row['time_block']."

"; + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + + $num=1; + $sql2=$db->prepare("SELECT u.name, u.class FROM registrations AS r INNER JOIN users AS u ON (u.id=r.user) WHERE r.program=:pid ".$whereand." ORDER BY u.name ASC"); + $sql2->execute(array(":pid"=>$row['id'])); + while($row2=$sql2->fetch(PDO::FETCH_ASSOC)){ + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + + echo ""; + echo "
".$lang['num']."".$lang['name']."".$lang['class']."
".$num."".$row2['name']."".$row2['class']."
"; + echo "
"; + } + ?> +
+
+
+
+ + + + + +
diff --git a/subs/users.backend.php b/subs/users.backend.php new file mode 100644 index 0000000..dd1072a --- /dev/null +++ b/subs/users.backend.php @@ -0,0 +1,144 @@ +=3){ + if(isset($_POST['n_name']) && isset($_POST['n_class']) && isset($_POST['n_al']) && isset($_POST['n_password'])){ + $sql=$db->prepare("INSERT INTO users (name, class, accesslevel, password) VALUES (:name, :class, :al, :passwd)"); + $sql->execute(array(":name"=>$_POST['n_name'], ":class"=>$_POST['n_class'], ":al"=>$_POST['n_al'], ":passwd"=>\Defuse\Crypto\Crypto::encrypt($_POST['n_password'], $crypto))); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + else{ + functions::setMessage(3); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + } + if(isset($_GET['all'])){ + set_time_limit(120); + if($_GET['all']=="passwd"){ + $sql=$db->prepare("SELECT id FROM users WHERE id<>1 and accesslevel<2"); + $sql->execute(); + while($row=$sql->fetch(PDO::FETCH_ASSOC)){ + $sql2=$db->prepare("UPDATE users SET password=:passwd WHERE id=:id"); + $sql2->execute(array(":passwd"=>\Defuse\Crypto\Crypto::encrypt(functions::randomString(6, functions::RAND_SMALL), $crypto), ":id"=>$row['id'])); + } + functions::setMessage(7); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + else if($_GET['all']=="reset"){ + $sql=$db->prepare("UPDATE users SET except_login=0, except_signup=0 WHERE id<>1"); + $sql->execute(); + functions::setMessage(7); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + } + if(isset($_GET['delete'])){ + $sql=$db->prepare("SELECT COUNT(id) AS count FROM users WHERE id=:id"); + $sql->execute(array(":id"=>$_GET['delete'])); + $res=$sql->fetch(PDO::FETCH_ASSOC); + + if($res['count']<1){ + functions::setError(7); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + else{ + $sql=$db->prepare("DELETE FROM users WHERE id=:id"); + $sql->execute(array(":id"=>$_GET['delete'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + else{ + functions::setMessage(4); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + } + } + if(isset($_GET['np_uid']) && isset($_GET['np_passwd'])){ + $sql=$db->prepare("UPDATE users SET password=:passwd WHERE id=:uid"); + $sql->execute(array(":passwd"=>\Defuse\Crypto\Crypto::encrypt($_GET['np_passwd'], $crypto), ":uid"=>$_GET['np_uid'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + else{ + functions::setMessage(7); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + } + if(isset($_GET['el_uid']) && isset($_GET['el_param'])){ + $sql=$db->prepare("UPDATE users SET except_login=:el WHERE id=:uid"); + $sql->execute(array(":el"=>$_GET['el_param'], ":uid"=>$_GET['el_uid'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + else{ + functions::setMessage(7); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + } + if(isset($_GET['es_uid']) && isset($_GET['es_param'])){ + $sql=$db->prepare("UPDATE users SET except_signup=:es WHERE id=:uid"); + $sql->execute(array(":es"=>$_GET['es_param'], ":uid"=>$_GET['es_uid'])); + $res=$sql->rowCount(); + + if($res<1){ + functions::setError(6); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + else{ + functions::setMessage(7); + if(!isset($_GET['backend'])) header("Location: ./users"); + } + } +} + +$msql=$db->prepare("SELECT id, name, class, accesslevel, password, except_login, except_signup FROM users WHERE id<>1 ORDER BY class ASC, accesslevel DESC, name ASC"); +$msql->execute(); + +/* + * Export + */ +if(isset($_GET['export'])){ + $csv=$BOM; + $csv.=$config['general']['org']."\n".$config['general']['title']."\n\n"; + + if($_SESSION['accesslevel']==2){ + $csv.=$lang['id'].";".$lang['name'].";".$lang['class'].";".$lang['accesslevel']."\n"; + } + else{ + $csv.=$lang['id'].";".$lang['name'].";".$lang['class'].";".$lang['accesslevel'].";".$lang['password'].";".$lang['except_login'].";".$lang['except_signup']."\n"; + } + + while($row=$msql->fetch(PDO::FETCH_ASSOC)){ + if($_SESSION['accesslevel']==2){ + $csv.=$row['id'].";".$row['name'].";".$row['class'].";".$lang['al'][$row['accesslevel']]."\n"; + } + else{ + $csv.=$row['id'].";".$row['name'].";".$row['class'].";".$lang['al'][$row['accesslevel']].";".\Defuse\Crypto\Crypto::decrypt($row['password'], $crypto).";".$row['except_login'].";".$row['except_signup']."\n"; + } + } + + //print + header("Content-type: application/octet-stream"); + //header("Content-length: ".mb_strlen($csv)); + header("Content-disposition: attachment; filename='".$config['general']['title']."_users_export_".date("Y-m-d H-i-s").".csv'"); + echo $csv; + die(); +} diff --git a/subs/users.php b/subs/users.php new file mode 100644 index 0000000..6ff6a53 --- /dev/null +++ b/subs/users.php @@ -0,0 +1,99 @@ + + +
+ =3): ?> +
+
+
+ +
+ + + + + + + + + + + + + + + + + +
" required>
">
+
"; + $oid++; + } + ?> +
" required>
+
+
+ +
+
+
+
+
+
+ + +
+
+ +

+
+ + + + + + + + =3): ?> + =3): ?> + =3): ?> + =3): ?> + + + + fetch(PDO::FETCH_ASSOC)){ + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + if($_SESSION['accesslevel']>=3){ + echo ""; + echo ""; + echo ""; + echo ""; + } + ?> + +
".$row['id']."".$row['name']."".$row['class']."".$lang['al'][$row['accesslevel']]."".\Defuse\Crypto\Crypto::decrypt($row['password'], $crypto)."".$row['except_login']."".$row['except_signup'].""; + echo ""; + echo ""; + echo ""; + echo ""; + } + echo "
+
+ +