├── Demo1.png ├── Demo2.png ├── Demo3.png ├── LICENSE ├── README.md ├── config.json ├── data.json ├── lib ├── isu │ ├── isu.js │ ├── isuClass.js │ ├── isuJar.js │ ├── isuMoodle.js │ └── survey.js └── logger │ ├── data.json │ ├── logger.js │ └── logger.ls ├── main.js ├── node_modules └── .bin │ ├── acorn │ ├── cleancss │ ├── dateformat │ ├── har-validator │ ├── jade │ ├── mime │ ├── mkdirp │ ├── semver │ ├── sshpk-conv │ ├── sshpk-sign │ ├── sshpk-verify │ ├── strip-indent │ ├── uglifyjs │ └── uuid ├── package.json ├── public └── css │ ├── animate.min.css │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── bootstrap.min.css │ └── font.css ├── router └── main.js └── views ├── login.jade ├── mainPage.jade ├── moodle.jade ├── survey.jade └── template └── bootstrap.jade /Demo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaaddress1/isuMaster-NodeJS/b480f9481a3ea4d433add414172cfd8e0c48bdbc/Demo1.png -------------------------------------------------------------------------------- /Demo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaaddress1/isuMaster-NodeJS/b480f9481a3ea4d433add414172cfd8e0c48bdbc/Demo2.png -------------------------------------------------------------------------------- /Demo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaaddress1/isuMaster-NodeJS/b480f9481a3ea4d433add414172cfd8e0c48bdbc/Demo3.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node-isuSurvey 2 | ========= 3 | ![](Demo3.png) 4 | ![](Demo2.png) 5 | ![](Demo1.png) 6 | 7 | 這是什麼? 8 | --------- 9 | 這是基於 Node.js 開發的專案,整合義守大學的應用資訊系統、Moodle系統為統一第三方雲端服務,目前部署於 isu.30cm.tw 供義守大學學生使用。 10 | 11 | 功能 12 | --------- 13 | 14 | * 今明兩日課表彙整(時間/日期/教室/選必修) 15 | * Moodle 小考資訊/作業狀況即時彙整/公告彙整 16 | * 自動填寫期中/期末問卷 17 | * 自動替瀏覽本服務的用戶跨域名登入學校 Moodle 18 | 19 | 如何使用? 20 | --------- 21 | 如果您正在尋找網頁版本,請至 義守管家 ([isu.30cm.tw](https://isu.30cm.tw)) 22 | 如有特殊需求也可下載此份專案自行部署使用。 -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "config_version" : 1, 3 | "port" : 1337 4 | } -------------------------------------------------------------------------------- /data.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 4 3 | } -------------------------------------------------------------------------------- /lib/isu/isu.js: -------------------------------------------------------------------------------- 1 | // require Modules 2 | fs = require('fs'); 3 | var request = require('request'); 4 | var iconv = require('iconv-lite'); 5 | var isuJar = require('./isuJar'); 6 | var moment = require('moment'); 7 | 8 | 9 | var login = function( usr, pass, req, res, callback) { 10 | "use strict"; 11 | 12 | let j = isuJar.getJar(req); 13 | request({ 14 | url: 'http://netreg.isu.edu.tw/Wapp/wap_check.asp', 15 | method: 'POST', 16 | encoding: null, 17 | followAllRedirects: true, 18 | jar: j, 19 | headers: { 20 | referer: 'http://netreg.isu.edu.tw/Wapp/wap_indexmain.asp?call_from=logout' 21 | }, 22 | form: { 23 | logon_id: usr, 24 | txtpasswd: pass 25 | } 26 | }, function (e, r, b) { 27 | 28 | request.get({ 29 | url: 'http://netreg.isu.edu.tw/Wapp/left.asp', 30 | encoding: null, 31 | jar: j, 32 | }, function(ee ,rr ,bb) 33 | { 34 | 35 | let body = iconv.decode(bb, 'Big5'); 36 | let usrName = body.match(/登出<\/font>.*?]+>([^<]+)<\/span>/); 37 | 38 | res.cookie('name', ( usrName == null ? '' : usrName[1])); 39 | res.cookie('loginMail', usr); 40 | res.cookie('loginPass', pass); 41 | res.cookie('isuAppCookie', j.getCookieString('http://netreg.isu.edu.tw') ); 42 | 43 | if (usrName) 44 | savUsrPwToDB( usr, pass, usrName[1] ); 45 | 46 | callback(); 47 | } 48 | ); 49 | }); 50 | } 51 | 52 | 53 | // export modules 54 | module.exports.login = login; -------------------------------------------------------------------------------- /lib/isu/isuClass.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | var iconv = require('iconv-lite'); 3 | var isuJar = require('./isuJar'); 4 | var cheerio = require('cheerio'); 5 | var getIndexOfToday = function( addOffset ) { 6 | "use strict"; 7 | 8 | let date = new Date(); 9 | let retn = date.getDay(); 10 | retn = (retn+addOffset) % 7; 11 | return (retn == 0 ? 7 : retn); 12 | } 13 | 14 | var getDetailClassRoom = function( classRoomID ) { 15 | if (classRoomID.startsWith('01')) 16 | return '行政大樓 ' + classRoomID.slice(-3); 17 | else if (classRoomID.startsWith('02')) 18 | return '理工大樓 ' + classRoomID.slice(-3); 19 | else if (classRoomID.startsWith('03')) 20 | return '科技大樓 ' + classRoomID.slice(-3); 21 | else if (classRoomID.startsWith('5')) 22 | return '綜合大樓 ' + classRoomID.slice(-3); 23 | else if (classRoomID.startsWith('6')) 24 | return '國際學院 ' + classRoomID.slice(-3); 25 | else if (classRoomID.startsWith('A')) 26 | return '燕巢校區 A 棟 ' + classRoomID.slice(-3); 27 | else if (classRoomID.startsWith('B')) 28 | return '燕巢校區 B 棟 ' + classRoomID.slice(-3); 29 | else if (classRoomID.startsWith('C')) 30 | return '燕巢校區 C 棟 ' + classRoomID.slice(-3); 31 | 32 | return classRoomID; 33 | } 34 | 35 | /** 36 | * Body: Isu class html source 37 | * Index: Mon = 1, Tue = 2, Wed = 3, ..., Sat = 6, Sun = 7 38 | */ 39 | var getClassOfDayByIndex = function( body , index ) { 40 | "use strict"; 41 | 42 | let timeArr = ['08:20', '09:20', '10:20', '11:20', '13:30', '14:30', '15:30', '16:30', '17:30', '18:50', '19:40', '20:30', '21:20']; 43 | let classListArr = []; 44 | 45 | body = body.replace(/\n/gi,'').replace(/\r/gi,'').replace(/\t/gi,''); 46 | let $ = cheerio.load(body); 47 | 48 | $("tr[onmouseover='this.style.backgroundColor=\'yellow\';this.style.cursor=\'hand\';']").each( 49 | function(i, elemi) { 50 | 51 | let childArr = $(elemi).find('td'); 52 | let classID = $(childArr[0]).text(); 53 | let className = $(childArr[1]).text().split('\x20')[0].replace(/[\x20\xa0]/g,''); 54 | let classGrade = $(childArr[2]).text(); 55 | let classElective = $(childArr[5]).text().replace(/[\x20\xa0]/g,''); 56 | let classTeacher = $(childArr[6]).text().replace(/[\x20\xa0]/g,''); 57 | let classRoomID = $(childArr[7]).text().replace(/\x20/g,''); 58 | let extraMessage = $(childArr[16]).text(); 59 | let classTimeSequence = $(childArr[(7+index)]).text(); 60 | 61 | if (classTimeSequence != '\xA0') { 62 | classTimeSequence = classTimeSequence.replace(/\xa0/g,''); 63 | 64 | for(let j in classTimeSequence) { 65 | let p = -1; 66 | if (/^\d+$/.test(classTimeSequence[j])) 67 | p = parseInt(classTimeSequence[j]); 68 | 69 | classListArr.push([ p < 0 ? '' :timeArr[p-1], 70 | classElective, 71 | classTeacher, 72 | classGrade, 73 | className, 74 | getDetailClassRoom(classRoomID) 75 | ]); 76 | } 77 | 78 | } 79 | 80 | }); 81 | return classListArr; 82 | } 83 | 84 | 85 | var displayDay = function( req, res, callback ) { 86 | "use strict"; 87 | 88 | let j = isuJar.getJar(req); 89 | request.get({ 90 | url: 'http://netreg.isu.edu.tw/wapp/wap_13/wap_130430.asp', 91 | encoding: null, 92 | jar: j, 93 | }, function(e ,r ,b) { 94 | 95 | let body = iconv.decode(b, 'Big5'); 96 | 97 | if (body.indexOf('登入') > -1) { 98 | callback( null, null, null, null, true ); 99 | return; 100 | } 101 | 102 | let arr = ['一','二','三','四','五','六','日']; 103 | let currDay = getIndexOfToday(0); 104 | let tommDay = getIndexOfToday(1); 105 | callback( arr[currDay-1], 106 | getClassOfDayByIndex( body, currDay ), 107 | arr[tommDay-1], 108 | getClassOfDayByIndex( body, tommDay ), 109 | false ); 110 | 111 | }); 112 | 113 | }; 114 | 115 | 116 | var displyNowAbsenteeism = function( req, res, callback ) { 117 | "use strict"; 118 | 119 | let vacationArr = []; 120 | let absenceArr = []; 121 | let j = isuJar.getJar(req); 122 | 123 | request.get( 124 | { 125 | url: 'http://netreg.isu.edu.tw/wapp/wap_13/wap_130040.asp', 126 | encoding: null, 127 | jar: j, 128 | }, 129 | function(e, r, b) 130 | { 131 | let body = iconv.decode(b, 'Big5'); 132 | if (body.indexOf('登入') > -1) { 133 | callback(null, null); 134 | return; 135 | } 136 | 137 | 138 | let $ = cheerio.load(body); 139 | /* absence */ 140 | $($("table")[1]).find("tr[align='middle']").each(function(i,elem) 141 | { 142 | let itemArr = $(elem).find('td'); 143 | 144 | let classId = $(itemArr[0]).text(); 145 | let className = $(itemArr[1]).text().replace(/[\r\n\t ]/g,''); 146 | let date = $(itemArr[2]).text().replace(/[\r\n\t ]/g,''); 147 | let classTime = $(itemArr[3]).text(); 148 | absenceArr.push( 149 | [ 150 | classId, 151 | className, 152 | date, 153 | classTime 154 | ]); 155 | }); 156 | 157 | /* vacation */ 158 | $($("table")[2]).find("tr[align='middle']").each(function(i,elem) 159 | { 160 | let itemArr = $(elem).find('td'); 161 | 162 | let classId = $(itemArr[0]).text(); 163 | let className = $(itemArr[1]).text().replace(/[\r\n\t ]/g,''); 164 | let date = $(itemArr[2]).text().replace(/[\r\n\t ]/g,''); 165 | let classTime = $(itemArr[3]).text(); 166 | let classType = $(itemArr[4]).text(); 167 | vacationArr.push( 168 | [ 169 | classId, 170 | className, 171 | date, 172 | classTime, 173 | classType 174 | ]); 175 | }); 176 | callback(absenceArr, vacationArr); 177 | return; 178 | }); 179 | } 180 | 181 | 182 | 183 | // export modules 184 | module.exports.displayDay = displayDay; 185 | module.exports.displyNowAbsenteeism = displyNowAbsenteeism; 186 | -------------------------------------------------------------------------------- /lib/isu/isuJar.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | 3 | 4 | var getJar = function(req) { 5 | "use strict"; 6 | 7 | let jar = request.jar(); 8 | 9 | if (req 10 | && req.cookies 11 | && req.cookies.isuAppCookie 12 | && (req.cookies.isuAppCookie != '') ) { 13 | 14 | req.cookies.isuAppCookie.split(';').map(function (val) { 15 | jar.setCookie( request.cookie(val), 'http://netreg.isu.edu.tw' ); 16 | }); 17 | } 18 | 19 | return jar; 20 | } 21 | 22 | var getMoodleJar = function(req) { 23 | "use strict"; 24 | 25 | let jar = request.jar(); 26 | 27 | if (req 28 | && req.cookies 29 | && req.cookies.isuMoodleCookie 30 | && (req.cookies.isuMoodleCookie != '') ) { 31 | 32 | req.cookies.isuMoodleCookie.split(';').map(function (val) { 33 | jar.setCookie( request.cookie(val), 'http://moodle.isu.edu.tw' ); 34 | }); 35 | } 36 | 37 | return jar; 38 | } 39 | 40 | module.exports.getJar = getJar; 41 | module.exports.getMoodleJar = getMoodleJar; -------------------------------------------------------------------------------- /lib/isu/isuMoodle.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | var iconv = require('iconv-lite'); 3 | var cheerio = require('cheerio'); 4 | var moment = require('moment'); 5 | var isuJar = require('./isuJar'); 6 | 7 | var login = function( req, res, usr, pass, callback) { 8 | "use strict"; 9 | 10 | let j = isuJar.getMoodleJar(req); 11 | 12 | request({ 13 | url: 'http://moodle.isu.edu.tw/login/index.php', 14 | method: 'POST', 15 | encoding: 'utf-8', 16 | followAllRedirects: true, 17 | jar: j, 18 | form: { 19 | username: usr, 20 | password: pass 21 | } 22 | }, function (e, r, b) { 23 | 24 | let sucessed = /logout.php.*?登出/.test(b); 25 | if (sucessed) 26 | res.cookie('isuMoodleCookie', j.getCookieString('http://moodle.isu.edu.tw') ); 27 | else 28 | res.cookie('isuMoodleCookie', '' ); 29 | callback(sucessed); 30 | 31 | }); 32 | } 33 | 34 | var analyzerMoodle = function( source , callback ) { 35 | "use strict"; 36 | 37 | let hwAliveArr = [], hwDeadArr = [], hwInfoArr = [], quizArr = [], totalClassArr = []; 38 | let today = moment().startOf('day'); 39 | 40 | let $ = cheerio.load(source); 41 | 42 | $("div[class='box coursebox']").each(function(i, elemi) { 43 | 44 | let className = $(elemi).find(".title").text().split('_')[1]; 45 | let classLink = $(elemi).find("a").attr('href'); 46 | let classActivity = $(elemi).find(".activity_info"); 47 | 48 | totalClassArr.push([className, classLink]); 49 | 50 | if (classActivity != '') { 51 | 52 | classActivity.find("div[class='assign overview']").each( function(j, elemj) { 53 | let hwName = $(elemj).find("a").text(); 54 | let hwInfo = $(elemj).find(".info").text(); 55 | let hwLink = $(elemj).find("a").attr('href'); 56 | let hwDetl = $(elemj).find(".details").text(); 57 | 58 | let m = moment(hwInfo,'YYYYMMDD'); 59 | let days = Math.round(moment.duration(m - today).asDays()); 60 | 61 | if (days >= 0) { 62 | hwAliveArr.push([className,hwName,days + ' 天',hwDetl,hwDetl,hwLink]); 63 | } 64 | else { 65 | hwDeadArr.push([className,hwName,-days + ' 天',hwDetl,hwInfo,hwLink]); 66 | 67 | } 68 | 69 | }); 70 | 71 | classActivity.find("div[class='overview forum']").each( function(j, elemj) { 72 | let alertName = $(elemj).find("a").text(); 73 | let alertInfo = $(elemj).find(".info").text(); 74 | let alertLink = $(elemj).find("a").attr('href'); 75 | hwInfoArr.push([className,alertName,alertInfo,alertLink]); 76 | }); 77 | 78 | classActivity.find("div[class='quiz overview']").each( function(j, elemj) { 79 | 80 | let quizName = $(elemj).find("a").text(); 81 | let quizInfo = $(elemj).find(".info").text(); 82 | let quizLink = $(elemj).find("a").attr('href'); 83 | 84 | let m = moment(quizInfo,'YYYYMMDD'); 85 | let days = Math.round(moment.duration(m - today).asDays()); 86 | 87 | if (days >= 0) { 88 | quizArr.push([className,quizName, days + ' 天',quizInfo,quizLink]); 89 | } else { 90 | quizArr.push([className,quizName, '已過期 ' + (-days) + ' 天',quizInfo,quizLink]); 91 | } 92 | 93 | }); 94 | } 95 | }); 96 | callback( hwAliveArr, hwDeadArr, hwInfoArr, quizArr, totalClassArr, false ); 97 | } 98 | 99 | 100 | var displyNowClass = function( req, res, callback ) { 101 | "use strict"; 102 | 103 | let j = isuJar.getMoodleJar(req); 104 | request.get({ 105 | url: 'http://moodle.isu.edu.tw/my/index.php?mynumber=0', 106 | encoding: 'utf-8', 107 | jar: j, 108 | }, function(e ,r ,b) { 109 | if (!(/logout.php.*?登出/.test(b))) { 110 | 111 | callback( null, null, null, null, null, true ); 112 | return; 113 | //res.cookie('isuMoodleCookie', '' ); 114 | //res.redirect('/isuMoodle'); 115 | } 116 | analyzerMoodle( b, callback ); 117 | 118 | } 119 | ); 120 | } 121 | 122 | module.exports.login = login; 123 | module.exports.displyNowClass = displyNowClass; 124 | -------------------------------------------------------------------------------- /lib/isu/survey.js: -------------------------------------------------------------------------------- 1 | // require Modules 2 | var request = require('request'); 3 | var iconv = require('iconv-lite'); 4 | var isuJar = require('./isuJar'); 5 | 6 | var getSurveyBody = function( classCode, cmdCode, req, callback ) { 7 | "use strict"; 8 | 9 | request({ 10 | url: 'http://netreg.isu.edu.tw/wapp/wap_13/wap_130100.asp', 11 | method: 'POST', 12 | encoding: null, 13 | followAllRedirects: true, 14 | jar: isuJar.getJar(req), 15 | headers: { 16 | referer: 'http://netreg.isu.edu.tw/wapp/wap_13/wap_130100.asp' 17 | }, 18 | form: { 19 | crcode: classCode, 20 | command: cmdCode, 21 | submit1: '%AD%D7%A7%EF%B0%DD%A8%F7', 22 | surtype: 0 23 | } 24 | }, function (e, r, b) { 25 | 26 | let body = iconv.decode(b, 'Big5'); 27 | callback(body); 28 | }); 29 | } 30 | 31 | var pattenRadio = /name=\x22([^\x22]+)\x22 type=radio value=\x22([^\x22]+)\x22>非常同意/g 32 | var pattenInput = /name=\x22([^\x22]+)\x22 type=input value=\x22(.*?)\x22/g 33 | var pattenHiden = /name=([^ ]+) type=hidden value=\x22(.*?)\x22/g 34 | 35 | var sendSurvey = function( classCode, cmdCode, req, callback) { 36 | "use strict"; 37 | 38 | getSurveyBody( classCode, cmdCode, req, function(surveyBody) { 39 | let param = {}; 40 | param['cr_code'] = classCode; 41 | param['X01X06M1/Y'] = 'Y'; 42 | param['X01X04M1/Y'] = 'Y'; 43 | param['X08X10M17/Y'] = 'Y'; 44 | 45 | //期末 46 | param['X01X03/Y'] = 'L1'; 47 | param['X01X07M4/Y'] = 'Y'; 48 | param['X08X05/Y'] = 'L1'; 49 | param['X08X06/Y'] = 'L1'; 50 | param['X08X07/Y'] = 'L1'; 51 | param['X08X08/Y'] = 'L1'; 52 | 53 | param['submit1'] = '%B6%F1%A6n%B0e%A5X'; 54 | 55 | let m; 56 | do { 57 | m = pattenRadio.exec(surveyBody); 58 | if (m) param[ m[1] ] = m[2]; 59 | } while (m); 60 | do { 61 | m = pattenInput.exec(surveyBody); 62 | if (m) param[ m[1] ] = m[2]; 63 | } while (m); 64 | do { 65 | m = pattenHiden.exec(surveyBody); 66 | if (m) param[ m[1] ] = m[2]; 67 | } while (m); 68 | 69 | request({ 70 | url: 'http://netreg.isu.edu.tw/wapp/wap_13/wap_130100.asp', 71 | method: 'POST', 72 | encoding: null, 73 | followAllRedirects: true, 74 | jar: isuJar.getJar(req), 75 | headers: { 76 | referer: 'http://netreg.isu.edu.tw/wapp/wap_13/wap_130100.asp' 77 | }, 78 | form: param 79 | }, function (e, r, b) { 80 | let body = iconv.decode(b, 'Big5'); 81 | callback(body); 82 | }); 83 | }); 84 | } 85 | 86 | 87 | var displayAll = function( req, res, callback) { 88 | "use strict"; 89 | 90 | let j = isuJar.getJar(req); 91 | request({ 92 | url: 'http://netreg.isu.edu.tw/wapp/wap_13/wap_130100.asp', 93 | method: 'GET', 94 | encoding: null, 95 | jar: j 96 | }, function(e, r, b) { 97 | let body = iconv.decode(b, 'Big5'); 98 | body = body.replace(/\x09/g,'').replace(/\r\n/g,''); 99 | 100 | 101 | if (body.indexOf('登入') > -1) { 102 | res.redirect('./?act=logout'); 103 | return; 104 | } 105 | 106 | 107 | let patten = /]+>([^<]+)<\/td>([^<]+)<\/td>([^<]+)<\/td>([^<]+)<\/td> 24 | data.count++ 25 | write ={ count: data.count } 26 | fs.writeFile path, (JSON.stringify write, null, 4), (err) -> 27 | if err 28 | console.log '[*] 錯誤!無法寫入 json' 29 | data.count 30 | 31 | # Logger 32 | logger = morgan format, { 33 | skip: (req, res) -> res.statusCode ~= 404 34 | } 35 | 36 | 37 | # Exports 38 | exports.logger = logger; -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | // Require Modules 2 | var express = require('express'); 3 | //var proxiedRequest = request.defaults({'proxy': 'http://127.0.0.1:8888'}); 4 | var config = require(__dirname + '/config.json'); 5 | var logger = require(__dirname + '/lib/logger/logger') 6 | var bodyParser = require('body-parser'); 7 | 8 | // Require apps 9 | var app = express(); 10 | 11 | // App Settings 12 | process.env.TZ = 'Asia/Taipei' 13 | app.set('port', process.env.PORT || config.port); //設定 PORT 14 | app.set('views', __dirname + '/views'); // 設定 view 路徑及 jade 模板系統 15 | app.set('view engine', 'jade'); 16 | app.use(express.static(__dirname + '/public')); 17 | app.use(logger.logger); // 啟用記錄輸出 18 | app.use(bodyParser()); // 啟用 body parser 以處理 post 資料 19 | 20 | var cookieParser = require('cookie-parser') 21 | app.use(cookieParser()) 22 | 23 | console.log('[*] 初始化完畢') 24 | 25 | // Routers 26 | r_main = require(__dirname + '/router/main'); 27 | 28 | app.use('/', r_main); 29 | 30 | // Listen to port 31 | app.listen(app.get('port'), '127.0.0.1' ,function(){ 32 | console.log('[*] 伺服器監聽於連接埠' + app.get('port')); 33 | }); -------------------------------------------------------------------------------- /node_modules/.bin/acorn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | "use strict"; 3 | 4 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } } 5 | 6 | var _path = require("path"); 7 | 8 | var _fs = require("fs"); 9 | 10 | var _distAcornJs = require("../dist/acorn.js"); 11 | 12 | var acorn = _interopRequireWildcard(_distAcornJs); 13 | 14 | var infile = undefined, 15 | forceFile = undefined, 16 | silent = false, 17 | compact = false, 18 | tokenize = false; 19 | var options = {}; 20 | 21 | function help(status) { 22 | var print = status == 0 ? console.log : console.error; 23 | print("usage: " + (0, _path.basename)(process.argv[1]) + " [--ecma3|--ecma5|--ecma6]"); 24 | print(" [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]"); 25 | process.exit(status); 26 | } 27 | 28 | for (var i = 2; i < process.argv.length; ++i) { 29 | var arg = process.argv[i]; 30 | if ((arg == "-" || arg[0] != "-") && !infile) infile = arg;else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i];else if (arg == "--ecma3") options.ecmaVersion = 3;else if (arg == "--ecma5") options.ecmaVersion = 5;else if (arg == "--ecma6") options.ecmaVersion = 6;else if (arg == "--locations") options.locations = true;else if (arg == "--allow-hash-bang") options.allowHashBang = true;else if (arg == "--silent") silent = true;else if (arg == "--compact") compact = true;else if (arg == "--help") help(0);else if (arg == "--tokenize") tokenize = true;else if (arg == "--module") options.sourceType = 'module';else help(1); 31 | } 32 | 33 | function run(code) { 34 | var result = undefined; 35 | if (!tokenize) { 36 | try { 37 | result = acorn.parse(code, options); 38 | } catch (e) { 39 | console.error(e.message);process.exit(1); 40 | } 41 | } else { 42 | result = []; 43 | var tokenizer = acorn.tokenizer(code, options), 44 | token = undefined; 45 | while (true) { 46 | try { 47 | token = tokenizer.getToken(); 48 | } catch (e) { 49 | console.error(e.message);process.exit(1); 50 | } 51 | result.push(token); 52 | if (token.type == acorn.tokTypes.eof) break; 53 | } 54 | } 55 | if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2)); 56 | } 57 | 58 | if (forceFile || infile && infile != "-") { 59 | run((0, _fs.readFileSync)(infile, "utf8")); 60 | } else { 61 | (function () { 62 | var code = ""; 63 | process.stdin.resume(); 64 | process.stdin.on("data", function (chunk) { 65 | return code += chunk; 66 | }); 67 | process.stdin.on("end", function () { 68 | return run(code); 69 | }); 70 | })(); 71 | } -------------------------------------------------------------------------------- /node_modules/.bin/cleancss: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var CleanCSS = require('../index'); 6 | 7 | var commands = require('commander'); 8 | 9 | var packageConfig = fs.readFileSync(path.join(path.dirname(fs.realpathSync(process.argv[1])), '../package.json')); 10 | var buildVersion = JSON.parse(packageConfig).version; 11 | 12 | var isWindows = process.platform == 'win32'; 13 | 14 | // Specify commander options to parse command line params correctly 15 | commands 16 | .version(buildVersion, '-v, --version') 17 | .usage('[options] source-file, [source-file, ...]') 18 | .option('-b, --keep-line-breaks', 'Keep line breaks') 19 | .option('-c, --compatibility [ie7|ie8]', 'Force compatibility mode (see Readme for advanced examples)') 20 | .option('-d, --debug', 'Shows debug information (minification time & compression efficiency)') 21 | .option('-o, --output [output-file]', 'Use [output-file] as output instead of STDOUT') 22 | .option('-r, --root [root-path]', 'Set a root path to which resolve absolute @import rules') 23 | .option('-s, --skip-import', 'Disable @import processing') 24 | .option('-t, --timeout [seconds]', 'Per connection timeout when fetching remote @imports (defaults to 5 seconds)') 25 | .option('--rounding-precision [n]', 'Rounds to `N` decimal places. Defaults to 2. -1 disables rounding', parseInt) 26 | .option('--s0', 'Remove all special comments, i.e. /*! comment */') 27 | .option('--s1', 'Remove all special comments but the first one') 28 | .option('--semantic-merging', 'Enables unsafe mode by assuming BEM-like semantic stylesheets (warning, this may break your styling!)') 29 | .option('--skip-advanced', 'Disable advanced optimizations - ruleset reordering & merging') 30 | .option('--skip-aggressive-merging', 'Disable properties merging based on their order') 31 | .option('--skip-import-from [rules]', 'Disable @import processing for specified rules', function (val) { return val.split(','); }, []) 32 | .option('--skip-media-merging', 'Disable @media merging') 33 | .option('--skip-rebase', 'Disable URLs rebasing') 34 | .option('--skip-restructuring', 'Disable restructuring optimizations') 35 | .option('--skip-shorthand-compacting', 'Disable shorthand compacting') 36 | .option('--source-map', 'Enables building input\'s source map') 37 | .option('--source-map-inline-sources', 'Enables inlining sources inside source maps'); 38 | 39 | commands.on('--help', function () { 40 | console.log(' Examples:\n'); 41 | console.log(' %> cleancss one.css'); 42 | console.log(' %> cleancss -o one-min.css one.css'); 43 | if (isWindows) { 44 | console.log(' %> type one.css two.css three.css | cleancss -o merged-and-minified.css'); 45 | } else { 46 | console.log(' %> cat one.css two.css three.css | cleancss -o merged-and-minified.css'); 47 | console.log(' %> cat one.css two.css three.css | cleancss | gzip -9 -c > merged-minified-and-gzipped.css.gz'); 48 | } 49 | console.log(''); 50 | process.exit(); 51 | }); 52 | 53 | commands.parse(process.argv); 54 | 55 | // If no sensible data passed in just print help and exit 56 | var fromStdin = !process.env.__DIRECT__ && !process.stdin.isTTY; 57 | if (!fromStdin && commands.args.length === 0) { 58 | commands.outputHelp(); 59 | return 0; 60 | } 61 | 62 | // Now coerce commands into CleanCSS configuration... 63 | var options = { 64 | advanced: commands.skipAdvanced ? false : true, 65 | aggressiveMerging: commands.skipAggressiveMerging ? false : true, 66 | compatibility: commands.compatibility, 67 | debug: commands.debug, 68 | inliner: commands.timeout ? { timeout: parseFloat(commands.timeout) * 1000 } : undefined, 69 | keepBreaks: !!commands.keepLineBreaks, 70 | keepSpecialComments: commands.s0 ? 0 : (commands.s1 ? 1 : '*'), 71 | mediaMerging: commands.skipMediaMerging ? false : true, 72 | processImport: commands.skipImport ? false : true, 73 | processImportFrom: processImportFrom(commands.skipImportFrom), 74 | rebase: commands.skipRebase ? false : true, 75 | restructuring: commands.skipRestructuring ? false : true, 76 | root: commands.root, 77 | roundingPrecision: commands.roundingPrecision, 78 | semanticMerging: commands.semanticMerging ? true : false, 79 | shorthandCompacting: commands.skipShorthandCompacting ? false : true, 80 | sourceMap: commands.sourceMap, 81 | sourceMapInlineSources: commands.sourceMapInlineSources, 82 | target: commands.output 83 | }; 84 | 85 | if (options.root || commands.args.length > 0) 86 | options.relativeTo = path.dirname(path.resolve(options.root || commands.args[0])); 87 | 88 | if (options.sourceMap && !options.target) { 89 | outputFeedback(['Source maps will not be built because you have not specified an output file.'], true); 90 | options.sourceMap = false; 91 | } 92 | 93 | // ... and do the magic! 94 | if (commands.args.length > 0) { 95 | minify(commands.args); 96 | } else { 97 | var stdin = process.openStdin(); 98 | stdin.setEncoding('utf-8'); 99 | var data = ''; 100 | stdin.on('data', function (chunk) { 101 | data += chunk; 102 | }); 103 | stdin.on('end', function () { 104 | minify(data); 105 | }); 106 | } 107 | 108 | function processImportFrom(rules) { 109 | if (rules.length === 0) { 110 | return ['all']; 111 | } else if (rules.length == 1 && rules[0] == 'all') { 112 | return []; 113 | } else { 114 | return rules.map(function (rule) { 115 | if (rule == 'local') 116 | return 'remote'; 117 | else if (rule == 'remote') 118 | return 'local'; 119 | else 120 | return '!' + rule; 121 | }); 122 | } 123 | } 124 | 125 | function minify(data) { 126 | new CleanCSS(options).minify(data, function (errors, minified) { 127 | if (options.debug) { 128 | console.error('Original: %d bytes', minified.stats.originalSize); 129 | console.error('Minified: %d bytes', minified.stats.minifiedSize); 130 | console.error('Efficiency: %d%', ~~(minified.stats.efficiency * 10000) / 100.0); 131 | console.error('Time spent: %dms', minified.stats.timeSpent); 132 | } 133 | 134 | outputFeedback(minified.errors, true); 135 | outputFeedback(minified.warnings); 136 | 137 | if (minified.errors.length > 0) 138 | process.exit(1); 139 | 140 | if (minified.sourceMap) { 141 | var mapFilename = path.basename(options.target) + '.map'; 142 | output(minified.styles + '/*# sourceMappingURL=' + mapFilename + ' */'); 143 | outputMap(minified.sourceMap, mapFilename); 144 | } else { 145 | output(minified.styles); 146 | } 147 | }); 148 | } 149 | 150 | function output(minified) { 151 | if (options.target) 152 | fs.writeFileSync(options.target, minified, 'utf8'); 153 | else 154 | process.stdout.write(minified); 155 | } 156 | 157 | function outputMap(sourceMap, mapFilename) { 158 | var mapPath = path.join(path.dirname(options.target), mapFilename); 159 | fs.writeFileSync(mapPath, sourceMap.toString(), 'utf-8'); 160 | } 161 | 162 | function outputFeedback(messages, isError) { 163 | var prefix = isError ? '\x1B[31mERROR\x1B[39m:' : 'WARNING:'; 164 | 165 | messages.forEach(function (message) { 166 | console.error('%s %s', prefix, message); 167 | }); 168 | } 169 | -------------------------------------------------------------------------------- /node_modules/.bin/dateformat: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /** 3 | * dateformat 4 | * 5 | * Copyright (c) 2014 Charlike Mike Reagent (cli), contributors. 6 | * Released under the MIT license. 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | */ 14 | 15 | var dateFormat = require('../lib/dateformat'); 16 | var meow = require('meow'); 17 | var stdin = require('get-stdin'); 18 | 19 | var cli = meow({ 20 | pkg: '../package.json', 21 | help: [ 22 | 'Options', 23 | ' --help Show this help', 24 | ' --version Current version of package', 25 | ' -d | --date Date that want to format (Date object as Number or String)', 26 | ' -m | --mask Mask that will use to format the date', 27 | ' -u | --utc Convert local time to UTC time or use `UTC:` prefix in mask', 28 | ' -g | --gmt You can use `GMT:` prefix in mask', 29 | '', 30 | 'Usage', 31 | ' dateformat [date] [mask]', 32 | ' dateformat "Nov 26 2014" "fullDate"', 33 | ' dateformat 1416985417095 "dddd, mmmm dS, yyyy, h:MM:ss TT"', 34 | ' dateformat 1315361943159 "W"', 35 | ' dateformat "UTC:h:MM:ss TT Z"', 36 | ' dateformat "longTime" true', 37 | ' dateformat "longTime" false true', 38 | ' dateformat "Jun 9 2007" "fullDate" true', 39 | ' date +%s | dateformat', 40 | '' 41 | ].join('\n') 42 | }) 43 | 44 | var date = cli.input[0] || cli.flags.d || cli.flags.date || Date.now(); 45 | var mask = cli.input[1] || cli.flags.m || cli.flags.mask || dateFormat.masks.default; 46 | var utc = cli.input[2] || cli.flags.u || cli.flags.utc || false; 47 | var gmt = cli.input[3] || cli.flags.g || cli.flags.gmt || false; 48 | 49 | utc = utc === 'true' ? true : false; 50 | gmt = gmt === 'true' ? true : false; 51 | 52 | if (!cli.input.length) { 53 | stdin(function(date) { 54 | console.log(dateFormat(date, dateFormat.masks.default, utc, gmt)); 55 | }); 56 | return; 57 | } 58 | 59 | if (cli.input.length === 1 && date) { 60 | mask = date; 61 | date = Date.now(); 62 | console.log(dateFormat(date, mask, utc, gmt)); 63 | return; 64 | } 65 | 66 | if (cli.input.length >= 2 && date && mask) { 67 | if (mask === 'true' || mask === 'false') { 68 | utc = mask === 'true' ? true : false; 69 | gmt = !utc; 70 | mask = date 71 | date = Date.now(); 72 | } 73 | console.log(dateFormat(date, mask, utc, gmt)); 74 | return; 75 | } 76 | -------------------------------------------------------------------------------- /node_modules/.bin/har-validator: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict' 4 | 5 | var chalk = require('chalk') 6 | var cmd = require('commander') 7 | var fs = require('fs') 8 | var path = require('path') 9 | var pkg = require('../package.json') 10 | var Promise = require('pinkie-promise') 11 | var validate = require('..') 12 | var ValidationError = require('../lib/error') 13 | 14 | cmd 15 | .version(pkg.version) 16 | .usage('[options] ') 17 | .option('-s, --schema [name]', 'validate schema name (log, request, response, etc ...)') 18 | .parse(process.argv) 19 | 20 | if (!cmd.args.length) { 21 | cmd.help() 22 | } 23 | 24 | cmd.args.map(function (fileName) { 25 | var file = chalk.yellow.italic(path.basename(fileName)) 26 | 27 | new Promise(function (resolve, reject) { 28 | fs.readFile(fileName, function (err, data) { 29 | return err === null ? resolve(data) : reject(err) 30 | }) 31 | }) 32 | 33 | .then(JSON.parse) 34 | 35 | .then(cmd.schema ? validate[cmd.schema] : validate) 36 | 37 | .then(function (data) { 38 | console.log('%s [%s] is valid', chalk.green('✓'), file) 39 | }) 40 | 41 | .catch(function (err) { 42 | if (err instanceof SyntaxError) { 43 | return console.error('%s [%s] failed to read JSON: %s', chalk.red('✖'), file, chalk.red(err.message)) 44 | } 45 | 46 | if (err instanceof ValidationError) { 47 | err.errors.forEach(function (details) { 48 | console.error('%s [%s] failed validation: (%s: %s) %s', chalk.red('✖'), file, chalk.cyan.italic(details.field), chalk.magenta.italic(details.value), chalk.red(details.message)) 49 | }) 50 | 51 | return 52 | } 53 | 54 | console.error('%s [%s] an unknown error has occured: %s', chalk.red('✖'), file, chalk.red(err.message)) 55 | }) 56 | }) 57 | -------------------------------------------------------------------------------- /node_modules/.bin/jade: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var fs = require('fs') 8 | , program = require('commander') 9 | , path = require('path') 10 | , basename = path.basename 11 | , dirname = path.dirname 12 | , resolve = path.resolve 13 | , normalize = path.normalize 14 | , join = path.join 15 | , mkdirp = require('mkdirp') 16 | , jade = require('../'); 17 | 18 | // jade options 19 | 20 | var options = {}; 21 | 22 | // options 23 | 24 | program 25 | .version(require('../package.json').version) 26 | .usage('[options] [dir|file ...]') 27 | .option('-O, --obj ', 'JavaScript options object or JSON file containing it') 28 | .option('-o, --out ', 'output the compiled html to ') 29 | .option('-p, --path ', 'filename used to resolve includes') 30 | .option('-P, --pretty', 'compile pretty html output') 31 | .option('-c, --client', 'compile function for client-side runtime.js') 32 | .option('-n, --name ', 'The name of the compiled template (requires --client)') 33 | .option('-D, --no-debug', 'compile without debugging (smaller functions)') 34 | .option('-w, --watch', 'watch files for changes and automatically re-render') 35 | .option('-E, --extension ', 'specify the output file extension') 36 | .option('-H, --hierarchy', 'keep directory hierarchy when a directory is specified') 37 | .option('--name-after-file', 'Name the template after the last section of the file path (requires --client and overriden by --name)') 38 | .option('--doctype ', 'Specify the doctype on the command line (useful if it is not specified by the template)') 39 | 40 | 41 | program.on('--help', function(){ 42 | console.log(' Examples:'); 43 | console.log(''); 44 | console.log(' # translate jade the templates dir'); 45 | console.log(' $ jade templates'); 46 | console.log(''); 47 | console.log(' # create {foo,bar}.html'); 48 | console.log(' $ jade {foo,bar}.jade'); 49 | console.log(''); 50 | console.log(' # jade over stdio'); 51 | console.log(' $ jade < my.jade > my.html'); 52 | console.log(''); 53 | console.log(' # jade over stdio'); 54 | console.log(' $ echo \'h1 Jade!\' | jade'); 55 | console.log(''); 56 | console.log(' # foo, bar dirs rendering to /tmp'); 57 | console.log(' $ jade foo bar --out /tmp '); 58 | console.log(''); 59 | }); 60 | 61 | program.parse(process.argv); 62 | 63 | // options given, parse them 64 | 65 | if (program.obj) { 66 | options = parseObj(program.obj); 67 | } 68 | 69 | /** 70 | * Parse object either in `input` or in the file called `input`. The latter is 71 | * searched first. 72 | */ 73 | function parseObj (input) { 74 | var str, out; 75 | try { 76 | str = fs.readFileSync(program.obj); 77 | } catch (e) { 78 | return eval('(' + program.obj + ')'); 79 | } 80 | // We don't want to catch exceptions thrown in JSON.parse() so have to 81 | // use this two-step approach. 82 | return JSON.parse(str); 83 | } 84 | 85 | // --path 86 | 87 | if (program.path) options.filename = program.path; 88 | 89 | // --no-debug 90 | 91 | options.compileDebug = program.debug; 92 | 93 | // --client 94 | 95 | options.client = program.client; 96 | 97 | // --pretty 98 | 99 | options.pretty = program.pretty; 100 | 101 | // --watch 102 | 103 | options.watch = program.watch; 104 | 105 | // --name 106 | 107 | if (typeof program.name === 'string') { 108 | options.name = program.name; 109 | } 110 | 111 | // --doctype 112 | 113 | options.doctype = program.doctype; 114 | 115 | // left-over args are file paths 116 | 117 | var files = program.args; 118 | 119 | // array of paths that are being watched 120 | 121 | var watchList = []; 122 | 123 | // function for rendering 124 | var render = program.watch ? tryRender : renderFile; 125 | 126 | // compile files 127 | 128 | if (files.length) { 129 | console.log(); 130 | if (options.watch) { 131 | process.on('SIGINT', function() { 132 | process.exit(1); 133 | }); 134 | } 135 | files.forEach(function (file) { 136 | render(file); 137 | }); 138 | process.on('exit', function () { 139 | console.log(); 140 | }); 141 | // stdio 142 | } else { 143 | stdin(); 144 | } 145 | 146 | /** 147 | * Watch for changes on path 148 | * 149 | * Renders `base` if specified, otherwise renders `path`. 150 | */ 151 | function watchFile(path, base, rootPath) { 152 | path = normalize(path); 153 | if (watchList.indexOf(path) !== -1) return; 154 | console.log(" \033[90mwatching \033[36m%s\033[0m", path); 155 | fs.watchFile(path, {persistent: true, interval: 200}, 156 | function (curr, prev) { 157 | // File doesn't exist anymore. Keep watching. 158 | if (curr.mtime.getTime() === 0) return; 159 | // istanbul ignore if 160 | if (curr.mtime.getTime() === prev.mtime.getTime()) return; 161 | tryRender(base || path, rootPath); 162 | }); 163 | watchList.push(path); 164 | } 165 | 166 | /** 167 | * Convert error to string 168 | */ 169 | function errorToString(e) { 170 | return e.stack || /* istanbul ignore next */ (e.message || e); 171 | } 172 | 173 | /** 174 | * Try to render `path`; if an exception is thrown it is printed to stderr and 175 | * otherwise ignored. 176 | * 177 | * This is used in watch mode. 178 | */ 179 | function tryRender(path, rootPath) { 180 | try { 181 | renderFile(path, rootPath); 182 | } catch (e) { 183 | // keep watching when error occured. 184 | console.error(errorToString(e)); 185 | } 186 | } 187 | 188 | /** 189 | * Compile from stdin. 190 | */ 191 | 192 | function stdin() { 193 | var buf = ''; 194 | process.stdin.setEncoding('utf8'); 195 | process.stdin.on('data', function(chunk){ buf += chunk; }); 196 | process.stdin.on('end', function(){ 197 | var output; 198 | if (options.client) { 199 | output = jade.compileClient(buf, options); 200 | } else { 201 | var fn = jade.compile(buf, options); 202 | var output = fn(options); 203 | } 204 | process.stdout.write(output); 205 | }).resume(); 206 | 207 | process.on('SIGINT', function() { 208 | process.stdout.write('\n'); 209 | process.stdin.emit('end'); 210 | process.stdout.write('\n'); 211 | process.exit(); 212 | }) 213 | } 214 | 215 | var hierarchyWarned = false; 216 | 217 | /** 218 | * Process the given path, compiling the jade files found. 219 | * Always walk the subdirectories. 220 | * 221 | * @param path path of the file, might be relative 222 | * @param rootPath path relative to the directory specified in the command 223 | */ 224 | 225 | function renderFile(path, rootPath) { 226 | var re = /\.jade$/; 227 | var stat = fs.lstatSync(path); 228 | // Found jade file/\.jade$/ 229 | if (stat.isFile() && re.test(path)) { 230 | // Try to watch the file if needed. watchFile takes care of duplicates. 231 | if (options.watch) watchFile(path, null, rootPath); 232 | if (program.nameAfterFile) { 233 | options.name = getNameFromFileName(path); 234 | } 235 | var fn = options.client 236 | ? jade.compileFileClient(path, options) 237 | : jade.compileFile(path, options); 238 | if (options.watch && fn.dependencies) { 239 | // watch dependencies, and recompile the base 240 | fn.dependencies.forEach(function (dep) { 241 | watchFile(dep, path, rootPath); 242 | }); 243 | } 244 | 245 | // --extension 246 | var extname; 247 | if (program.extension) extname = '.' + program.extension; 248 | else if (options.client) extname = '.js'; 249 | else extname = '.html'; 250 | 251 | // path: foo.jade -> foo. 252 | path = path.replace(re, extname); 253 | if (program.out) { 254 | // prepend output directory 255 | if (rootPath && program.hierarchy) { 256 | // replace the rootPath of the resolved path with output directory 257 | path = resolve(path).replace(new RegExp('^' + resolve(rootPath)), ''); 258 | path = join(program.out, path); 259 | } else { 260 | if (rootPath && !hierarchyWarned) { 261 | console.warn('In Jade 2.0.0 --hierarchy will become the default.'); 262 | hierarchyWarned = true; 263 | } 264 | // old behavior or if no rootPath handling is needed 265 | path = join(program.out, basename(path)); 266 | } 267 | } 268 | var dir = resolve(dirname(path)); 269 | mkdirp.sync(dir, 0755); 270 | var output = options.client ? fn : fn(options); 271 | fs.writeFileSync(path, output); 272 | console.log(' \033[90mrendered \033[36m%s\033[0m', normalize(path)); 273 | // Found directory 274 | } else if (stat.isDirectory()) { 275 | var files = fs.readdirSync(path); 276 | files.map(function(filename) { 277 | return path + '/' + filename; 278 | }).forEach(function (file) { 279 | render(file, rootPath || path); 280 | }); 281 | } 282 | } 283 | 284 | /** 285 | * Get a sensible name for a template function from a file path 286 | * 287 | * @param {String} filename 288 | * @returns {String} 289 | */ 290 | function getNameFromFileName(filename) { 291 | var file = basename(filename, '.jade'); 292 | return file.toLowerCase().replace(/[^a-z0-9]+([a-z])/g, function (_, character) { 293 | return character.toUpperCase(); 294 | }) + 'Template'; 295 | } 296 | -------------------------------------------------------------------------------- /node_modules/.bin/mime: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var mime = require('./mime.js'); 4 | var file = process.argv[2]; 5 | var type = mime.lookup(file); 6 | 7 | process.stdout.write(type + '\n'); 8 | 9 | -------------------------------------------------------------------------------- /node_modules/.bin/mkdirp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var mkdirp = require('../'); 4 | var minimist = require('minimist'); 5 | var fs = require('fs'); 6 | 7 | var argv = minimist(process.argv.slice(2), { 8 | alias: { m: 'mode', h: 'help' }, 9 | string: [ 'mode' ] 10 | }); 11 | if (argv.help) { 12 | fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout); 13 | return; 14 | } 15 | 16 | var paths = argv._.slice(); 17 | var mode = argv.mode ? parseInt(argv.mode, 8) : undefined; 18 | 19 | (function next () { 20 | if (paths.length === 0) return; 21 | var p = paths.shift(); 22 | 23 | if (mode === undefined) mkdirp(p, cb) 24 | else mkdirp(p, mode, cb) 25 | 26 | function cb (err) { 27 | if (err) { 28 | console.error(err.message); 29 | process.exit(1); 30 | } 31 | else next(); 32 | } 33 | })(); 34 | -------------------------------------------------------------------------------- /node_modules/.bin/semver: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // Standalone semver comparison program. 3 | // Exits successfully and prints matching version(s) if 4 | // any supplied version is valid and passes all tests. 5 | 6 | var argv = process.argv.slice(2) 7 | , versions = [] 8 | , range = [] 9 | , gt = [] 10 | , lt = [] 11 | , eq = [] 12 | , inc = null 13 | , version = require("../package.json").version 14 | , loose = false 15 | , identifier = undefined 16 | , semver = require("../semver") 17 | , reverse = false 18 | 19 | main() 20 | 21 | function main () { 22 | if (!argv.length) return help() 23 | while (argv.length) { 24 | var a = argv.shift() 25 | var i = a.indexOf('=') 26 | if (i !== -1) { 27 | a = a.slice(0, i) 28 | argv.unshift(a.slice(i + 1)) 29 | } 30 | switch (a) { 31 | case "-rv": case "-rev": case "--rev": case "--reverse": 32 | reverse = true 33 | break 34 | case "-l": case "--loose": 35 | loose = true 36 | break 37 | case "-v": case "--version": 38 | versions.push(argv.shift()) 39 | break 40 | case "-i": case "--inc": case "--increment": 41 | switch (argv[0]) { 42 | case "major": case "minor": case "patch": case "prerelease": 43 | case "premajor": case "preminor": case "prepatch": 44 | inc = argv.shift() 45 | break 46 | default: 47 | inc = "patch" 48 | break 49 | } 50 | break 51 | case "--preid": 52 | identifier = argv.shift() 53 | break 54 | case "-r": case "--range": 55 | range.push(argv.shift()) 56 | break 57 | case "-h": case "--help": case "-?": 58 | return help() 59 | default: 60 | versions.push(a) 61 | break 62 | } 63 | } 64 | 65 | versions = versions.filter(function (v) { 66 | return semver.valid(v, loose) 67 | }) 68 | if (!versions.length) return fail() 69 | if (inc && (versions.length !== 1 || range.length)) 70 | return failInc() 71 | 72 | for (var i = 0, l = range.length; i < l ; i ++) { 73 | versions = versions.filter(function (v) { 74 | return semver.satisfies(v, range[i], loose) 75 | }) 76 | if (!versions.length) return fail() 77 | } 78 | return success(versions) 79 | } 80 | 81 | function failInc () { 82 | console.error("--inc can only be used on a single version with no range") 83 | fail() 84 | } 85 | 86 | function fail () { process.exit(1) } 87 | 88 | function success () { 89 | var compare = reverse ? "rcompare" : "compare" 90 | versions.sort(function (a, b) { 91 | return semver[compare](a, b, loose) 92 | }).map(function (v) { 93 | return semver.clean(v, loose) 94 | }).map(function (v) { 95 | return inc ? semver.inc(v, inc, loose, identifier) : v 96 | }).forEach(function (v,i,_) { console.log(v) }) 97 | } 98 | 99 | function help () { 100 | console.log(["SemVer " + version 101 | ,"" 102 | ,"A JavaScript implementation of the http://semver.org/ specification" 103 | ,"Copyright Isaac Z. Schlueter" 104 | ,"" 105 | ,"Usage: semver [options] [ [...]]" 106 | ,"Prints valid versions sorted by SemVer precedence" 107 | ,"" 108 | ,"Options:" 109 | ,"-r --range " 110 | ," Print versions that match the specified range." 111 | ,"" 112 | ,"-i --increment []" 113 | ," Increment a version by the specified level. Level can" 114 | ," be one of: major, minor, patch, premajor, preminor," 115 | ," prepatch, or prerelease. Default level is 'patch'." 116 | ," Only one version may be specified." 117 | ,"" 118 | ,"--preid " 119 | ," Identifier to be used to prefix premajor, preminor," 120 | ," prepatch or prerelease version increments." 121 | ,"" 122 | ,"-l --loose" 123 | ," Interpret versions and ranges loosely" 124 | ,"" 125 | ,"Program exits successfully if any valid version satisfies" 126 | ,"all supplied ranges, and prints all satisfying versions." 127 | ,"" 128 | ,"If no satisfying versions are found, then exits failure." 129 | ,"" 130 | ,"Versions are printed in ascending order, so supplying" 131 | ,"multiple versions to the utility will just sort them." 132 | ].join("\n")) 133 | } 134 | -------------------------------------------------------------------------------- /node_modules/.bin/sshpk-conv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // -*- mode: js -*- 3 | // vim: set filetype=javascript : 4 | // Copyright 2015 Joyent, Inc. All rights reserved. 5 | 6 | var dashdash = require('dashdash'); 7 | var sshpk = require('../lib/index'); 8 | var fs = require('fs'); 9 | var path = require('path'); 10 | 11 | var options = [ 12 | { 13 | names: ['outformat', 't'], 14 | type: 'string', 15 | help: 'Output format' 16 | }, 17 | { 18 | names: ['informat', 'T'], 19 | type: 'string', 20 | help: 'Input format' 21 | }, 22 | { 23 | names: ['file', 'f'], 24 | type: 'string', 25 | help: 'Input file name (default stdin)' 26 | }, 27 | { 28 | names: ['out', 'o'], 29 | type: 'string', 30 | help: 'Output file name (default stdout)' 31 | }, 32 | { 33 | names: ['private', 'p'], 34 | type: 'bool', 35 | help: 'Produce a private key as output' 36 | }, 37 | { 38 | names: ['derive', 'd'], 39 | type: 'string', 40 | help: 'Output a new key derived from this one, with given algo' 41 | }, 42 | { 43 | names: ['identify', 'i'], 44 | type: 'bool', 45 | help: 'Print key metadata instead of converting' 46 | }, 47 | { 48 | names: ['comment', 'c'], 49 | type: 'string', 50 | help: 'Set key comment, if output format supports' 51 | }, 52 | { 53 | names: ['help', 'h'], 54 | type: 'bool', 55 | help: 'Shows this help text' 56 | } 57 | ]; 58 | 59 | if (require.main === module) { 60 | var parser = dashdash.createParser({ 61 | options: options 62 | }); 63 | 64 | try { 65 | var opts = parser.parse(process.argv); 66 | } catch (e) { 67 | console.error('sshpk-conv: error: %s', e.message); 68 | process.exit(1); 69 | } 70 | 71 | if (opts.help || opts._args.length > 1) { 72 | var help = parser.help({}).trimRight(); 73 | console.error('sshpk-conv: converts between SSH key formats\n'); 74 | console.error(help); 75 | console.error('\navailable formats:'); 76 | console.error(' - pem, pkcs1 eg id_rsa'); 77 | console.error(' - ssh eg id_rsa.pub'); 78 | console.error(' - pkcs8 format you want for openssl'); 79 | console.error(' - openssh like output of ssh-keygen -o'); 80 | console.error(' - rfc4253 raw OpenSSH wire format'); 81 | process.exit(1); 82 | } 83 | 84 | /* 85 | * Key derivation can only be done on private keys, so use of the -d 86 | * option necessarily implies -p. 87 | */ 88 | if (opts.derive) 89 | opts.private = true; 90 | 91 | var inFile = process.stdin; 92 | var inFileName = 'stdin'; 93 | 94 | var inFilePath; 95 | if (opts.file) { 96 | inFilePath = opts.file; 97 | } else if (opts._args.length === 1) { 98 | inFilePath = opts._args[0]; 99 | } 100 | 101 | if (inFilePath) 102 | inFileName = path.basename(inFilePath); 103 | 104 | try { 105 | if (inFilePath) { 106 | fs.accessSync(inFilePath, fs.R_OK); 107 | inFile = fs.createReadStream(inFilePath); 108 | } 109 | } catch (e) { 110 | console.error('sshpk-conv: error opening input file' + 111 | ': ' + e.name + ': ' + e.message); 112 | process.exit(1); 113 | } 114 | 115 | var outFile = process.stdout; 116 | 117 | try { 118 | if (opts.out && !opts.identify) { 119 | fs.accessSync(path.dirname(opts.out), fs.W_OK); 120 | outFile = fs.createWriteStream(opts.out); 121 | } 122 | } catch (e) { 123 | console.error('sshpk-conv: error opening output file' + 124 | ': ' + e.name + ': ' + e.message); 125 | process.exit(1); 126 | } 127 | 128 | var bufs = []; 129 | inFile.on('readable', function () { 130 | var data; 131 | while ((data = inFile.read())) 132 | bufs.push(data); 133 | }); 134 | inFile.on('end', function () { 135 | var buf = Buffer.concat(bufs); 136 | var fmt = 'auto'; 137 | if (opts.informat) 138 | fmt = opts.informat; 139 | var f = sshpk.parseKey; 140 | if (opts.private) 141 | f = sshpk.parsePrivateKey; 142 | try { 143 | var key = f(buf, fmt, inFileName); 144 | } catch (e) { 145 | console.error('sshpk-conv: ' + 146 | e.name + ': ' + e.message); 147 | process.exit(1); 148 | } 149 | 150 | if (opts.derive) 151 | key = key.derive(opts.derive); 152 | 153 | if (opts.comment) 154 | key.comment = opts.comment; 155 | 156 | if (!opts.identify) { 157 | fmt = undefined; 158 | if (opts.outformat) 159 | fmt = opts.outformat; 160 | outFile.write(key.toBuffer(fmt)); 161 | if (fmt === 'ssh' || 162 | (!opts.private && fmt === undefined)) 163 | outFile.write('\n'); 164 | outFile.once('drain', function () { 165 | process.exit(0); 166 | }); 167 | } else { 168 | var kind = 'public'; 169 | if (sshpk.PrivateKey.isPrivateKey(key)) 170 | kind = 'private'; 171 | console.log('%s: a %d bit %s %s key', inFileName, 172 | key.size, key.type.toUpperCase(), kind); 173 | if (key.type === 'ecdsa') 174 | console.log('ECDSA curve: %s', key.curve); 175 | if (key.comment) 176 | console.log('Comment: %s', key.comment); 177 | console.log('Fingerprint:'); 178 | console.log(' ' + key.fingerprint().toString()); 179 | console.log(' ' + key.fingerprint('md5').toString()); 180 | process.exit(0); 181 | } 182 | }); 183 | } 184 | -------------------------------------------------------------------------------- /node_modules/.bin/sshpk-sign: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // -*- mode: js -*- 3 | // vim: set filetype=javascript : 4 | // Copyright 2015 Joyent, Inc. All rights reserved. 5 | 6 | var dashdash = require('dashdash'); 7 | var sshpk = require('../lib/index'); 8 | var fs = require('fs'); 9 | var path = require('path'); 10 | 11 | var options = [ 12 | { 13 | names: ['hash', 'H'], 14 | type: 'string', 15 | help: 'Hash algorithm (sha1, sha256, sha384, sha512)' 16 | }, 17 | { 18 | names: ['verbose', 'v'], 19 | type: 'bool', 20 | help: 'Display verbose info about key and hash used' 21 | }, 22 | { 23 | names: ['identity', 'i'], 24 | type: 'string', 25 | help: 'Path to key to use' 26 | }, 27 | { 28 | names: ['file', 'f'], 29 | type: 'string', 30 | help: 'Input filename' 31 | }, 32 | { 33 | names: ['out', 'o'], 34 | type: 'string', 35 | help: 'Output filename' 36 | }, 37 | { 38 | names: ['format', 't'], 39 | type: 'string', 40 | help: 'Signature format (asn1, ssh, raw)' 41 | }, 42 | { 43 | names: ['binary', 'b'], 44 | type: 'bool', 45 | help: 'Output raw binary instead of base64' 46 | }, 47 | { 48 | names: ['help', 'h'], 49 | type: 'bool', 50 | help: 'Shows this help text' 51 | } 52 | ]; 53 | 54 | if (require.main === module) { 55 | var parser = dashdash.createParser({ 56 | options: options 57 | }); 58 | 59 | try { 60 | var opts = parser.parse(process.argv); 61 | } catch (e) { 62 | console.error('sshpk-sign: error: %s', e.message); 63 | process.exit(1); 64 | } 65 | 66 | if (opts.help || opts._args.length > 1) { 67 | var help = parser.help({}).trimRight(); 68 | console.error('sshpk-sign: sign data using an SSH key\n'); 69 | console.error(help); 70 | process.exit(1); 71 | } 72 | 73 | if (!opts.identity) { 74 | var help = parser.help({}).trimRight(); 75 | console.error('sshpk-sign: the -i or --identity option ' + 76 | 'is required\n'); 77 | console.error(help); 78 | process.exit(1); 79 | } 80 | 81 | var keyData = fs.readFileSync(opts.identity); 82 | 83 | var key; 84 | try { 85 | key = sshpk.parsePrivateKey(keyData); 86 | } catch (e) { 87 | console.error('sshpk-sign: error loading private key "' + 88 | opts.identity + '": ' + e.name + ': ' + e.message); 89 | process.exit(1); 90 | } 91 | 92 | var hash = opts.hash || key.defaultHashAlgorithm(); 93 | 94 | var signer; 95 | try { 96 | signer = key.createSign(hash); 97 | } catch (e) { 98 | console.error('sshpk-sign: error creating signer: ' + 99 | e.name + ': ' + e.message); 100 | process.exit(1); 101 | } 102 | 103 | if (opts.verbose) { 104 | console.error('sshpk-sign: using %s-%s with a %d bit key', 105 | key.type, hash, key.size); 106 | } 107 | 108 | var inFile = process.stdin; 109 | var inFileName = 'stdin'; 110 | 111 | var inFilePath; 112 | if (opts.file) { 113 | inFilePath = opts.file; 114 | } else if (opts._args.length === 1) { 115 | inFilePath = opts._args[0]; 116 | } 117 | 118 | if (inFilePath) 119 | inFileName = path.basename(inFilePath); 120 | 121 | try { 122 | if (inFilePath) { 123 | fs.accessSync(inFilePath, fs.R_OK); 124 | inFile = fs.createReadStream(inFilePath); 125 | } 126 | } catch (e) { 127 | console.error('sshpk-sign: error opening input file' + 128 | ': ' + e.name + ': ' + e.message); 129 | process.exit(1); 130 | } 131 | 132 | var outFile = process.stdout; 133 | 134 | try { 135 | if (opts.out && !opts.identify) { 136 | fs.accessSync(path.dirname(opts.out), fs.W_OK); 137 | outFile = fs.createWriteStream(opts.out); 138 | } 139 | } catch (e) { 140 | console.error('sshpk-sign: error opening output file' + 141 | ': ' + e.name + ': ' + e.message); 142 | process.exit(1); 143 | } 144 | 145 | inFile.pipe(signer); 146 | inFile.on('end', function () { 147 | var sig; 148 | try { 149 | sig = signer.sign(); 150 | } catch (e) { 151 | console.error('sshpk-sign: error signing data: ' + 152 | e.name + ': ' + e.message); 153 | process.exit(1); 154 | } 155 | 156 | var fmt = opts.format || 'asn1'; 157 | var output; 158 | try { 159 | output = sig.toBuffer(fmt); 160 | if (!opts.binary) 161 | output = output.toString('base64'); 162 | } catch (e) { 163 | console.error('sshpk-sign: error converting signature' + 164 | ' to ' + fmt + ' format: ' + e.name + ': ' + 165 | e.message); 166 | process.exit(1); 167 | } 168 | 169 | outFile.write(output); 170 | if (!opts.binary) 171 | outFile.write('\n'); 172 | outFile.once('drain', function () { 173 | process.exit(0); 174 | }); 175 | }); 176 | } 177 | -------------------------------------------------------------------------------- /node_modules/.bin/sshpk-verify: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // -*- mode: js -*- 3 | // vim: set filetype=javascript : 4 | // Copyright 2015 Joyent, Inc. All rights reserved. 5 | 6 | var dashdash = require('dashdash'); 7 | var sshpk = require('../lib/index'); 8 | var fs = require('fs'); 9 | var path = require('path'); 10 | 11 | var options = [ 12 | { 13 | names: ['hash', 'H'], 14 | type: 'string', 15 | help: 'Hash algorithm (sha1, sha256, sha384, sha512)' 16 | }, 17 | { 18 | names: ['verbose', 'v'], 19 | type: 'bool', 20 | help: 'Display verbose info about key and hash used' 21 | }, 22 | { 23 | names: ['identity', 'i'], 24 | type: 'string', 25 | help: 'Path to (public) key to use' 26 | }, 27 | { 28 | names: ['file', 'f'], 29 | type: 'string', 30 | help: 'Input filename' 31 | }, 32 | { 33 | names: ['format', 't'], 34 | type: 'string', 35 | help: 'Signature format (asn1, ssh, raw)' 36 | }, 37 | { 38 | names: ['signature', 's'], 39 | type: 'string', 40 | help: 'base64-encoded signature data' 41 | }, 42 | { 43 | names: ['help', 'h'], 44 | type: 'bool', 45 | help: 'Shows this help text' 46 | } 47 | ]; 48 | 49 | if (require.main === module) { 50 | var parser = dashdash.createParser({ 51 | options: options 52 | }); 53 | 54 | try { 55 | var opts = parser.parse(process.argv); 56 | } catch (e) { 57 | console.error('sshpk-verify: error: %s', e.message); 58 | process.exit(3); 59 | } 60 | 61 | if (opts.help || opts._args.length > 1) { 62 | var help = parser.help({}).trimRight(); 63 | console.error('sshpk-verify: sign data using an SSH key\n'); 64 | console.error(help); 65 | process.exit(3); 66 | } 67 | 68 | if (!opts.identity) { 69 | var help = parser.help({}).trimRight(); 70 | console.error('sshpk-verify: the -i or --identity option ' + 71 | 'is required\n'); 72 | console.error(help); 73 | process.exit(3); 74 | } 75 | 76 | if (!opts.signature) { 77 | var help = parser.help({}).trimRight(); 78 | console.error('sshpk-verify: the -s or --signature option ' + 79 | 'is required\n'); 80 | console.error(help); 81 | process.exit(3); 82 | } 83 | 84 | var keyData = fs.readFileSync(opts.identity); 85 | 86 | var key; 87 | try { 88 | key = sshpk.parseKey(keyData); 89 | } catch (e) { 90 | console.error('sshpk-verify: error loading key "' + 91 | opts.identity + '": ' + e.name + ': ' + e.message); 92 | process.exit(2); 93 | } 94 | 95 | var fmt = opts.format || 'asn1'; 96 | var sigData = new Buffer(opts.signature, 'base64'); 97 | 98 | var sig; 99 | try { 100 | sig = sshpk.parseSignature(sigData, key.type, fmt); 101 | } catch (e) { 102 | console.error('sshpk-verify: error parsing signature: ' + 103 | e.name + ': ' + e.message); 104 | process.exit(2); 105 | } 106 | 107 | var hash = opts.hash || key.defaultHashAlgorithm(); 108 | 109 | var verifier; 110 | try { 111 | verifier = key.createVerify(hash); 112 | } catch (e) { 113 | console.error('sshpk-verify: error creating verifier: ' + 114 | e.name + ': ' + e.message); 115 | process.exit(2); 116 | } 117 | 118 | if (opts.verbose) { 119 | console.error('sshpk-verify: using %s-%s with a %d bit key', 120 | key.type, hash, key.size); 121 | } 122 | 123 | var inFile = process.stdin; 124 | var inFileName = 'stdin'; 125 | 126 | var inFilePath; 127 | if (opts.file) { 128 | inFilePath = opts.file; 129 | } else if (opts._args.length === 1) { 130 | inFilePath = opts._args[0]; 131 | } 132 | 133 | if (inFilePath) 134 | inFileName = path.basename(inFilePath); 135 | 136 | try { 137 | if (inFilePath) { 138 | fs.accessSync(inFilePath, fs.R_OK); 139 | inFile = fs.createReadStream(inFilePath); 140 | } 141 | } catch (e) { 142 | console.error('sshpk-verify: error opening input file' + 143 | ': ' + e.name + ': ' + e.message); 144 | process.exit(2); 145 | } 146 | 147 | inFile.pipe(verifier); 148 | inFile.on('end', function () { 149 | var ret; 150 | try { 151 | ret = verifier.verify(sig); 152 | } catch (e) { 153 | console.error('sshpk-verify: error verifying data: ' + 154 | e.name + ': ' + e.message); 155 | process.exit(1); 156 | } 157 | 158 | if (ret) { 159 | console.error('OK'); 160 | process.exit(0); 161 | } 162 | 163 | console.error('NOT OK'); 164 | process.exit(1); 165 | }); 166 | } 167 | -------------------------------------------------------------------------------- /node_modules/.bin/strip-indent: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | var fs = require('fs'); 4 | var stdin = require('get-stdin'); 5 | var pkg = require('./package.json'); 6 | var stripIndent = require('./'); 7 | var argv = process.argv.slice(2); 8 | var input = argv[0]; 9 | 10 | function help() { 11 | console.log([ 12 | '', 13 | ' ' + pkg.description, 14 | '', 15 | ' Usage', 16 | ' strip-indent ', 17 | ' echo | strip-indent', 18 | '', 19 | ' Example', 20 | ' echo \'\\tunicorn\\n\\t\\tcake\' | strip-indent', 21 | ' unicorn', 22 | ' \tcake' 23 | ].join('\n')); 24 | } 25 | 26 | function init(data) { 27 | console.log(stripIndent(data)); 28 | } 29 | 30 | if (argv.indexOf('--help') !== -1) { 31 | help(); 32 | return; 33 | } 34 | 35 | if (argv.indexOf('--version') !== -1) { 36 | console.log(pkg.version); 37 | return; 38 | } 39 | 40 | if (process.stdin.isTTY) { 41 | if (!input) { 42 | help(); 43 | return; 44 | } 45 | 46 | init(fs.readFileSync(input, 'utf8')); 47 | } else { 48 | stdin(init); 49 | } 50 | -------------------------------------------------------------------------------- /node_modules/.bin/uglifyjs: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | // -*- js -*- 3 | 4 | "use strict"; 5 | 6 | var UglifyJS = require("../tools/node"); 7 | var sys = require("util"); 8 | var yargs = require("yargs"); 9 | var fs = require("fs"); 10 | var path = require("path"); 11 | var async = require("async"); 12 | var acorn; 13 | var ARGS = yargs 14 | .usage("$0 input1.js [input2.js ...] [options]\n\ 15 | Use a single dash to read input from the standard input.\ 16 | \n\n\ 17 | NOTE: by default there is no mangling/compression.\n\ 18 | Without [options] it will simply parse input files and dump the AST\n\ 19 | with whitespace and comments discarded. To achieve compression and\n\ 20 | mangling you need to use `-c` and `-m`.\ 21 | ") 22 | .describe("source-map", "Specify an output file where to generate source map.") 23 | .describe("source-map-root", "The path to the original source to be included in the source map.") 24 | .describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.") 25 | .describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.") 26 | .describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.") 27 | .describe("screw-ie8", "Pass this flag if you don't care about full compliance with Internet Explorer 6-8 quirks (by default UglifyJS will try to be IE-proof).") 28 | .describe("expr", "Parse a single expression, rather than a program (for parsing JSON)") 29 | .describe("p", "Skip prefix for original filenames that appear in source maps. \ 30 | For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \ 31 | You can also specify -p relative, which will make UglifyJS figure out itself the relative paths between original sources, \ 32 | the source map and the output file.") 33 | .describe("o", "Output file (default STDOUT).") 34 | .describe("b", "Beautify output/specify output options.") 35 | .describe("m", "Mangle names/pass mangler options.") 36 | .describe("r", "Reserved names to exclude from mangling.") 37 | .describe("c", "Enable compressor/pass compressor options. \ 38 | Pass options like -c hoist_vars=false,if_return=false. \ 39 | Use -c with no argument to use the default compression options.") 40 | .describe("d", "Global definitions") 41 | .describe("e", "Embed everything in a big function, with a configurable parameter/argument list.") 42 | 43 | .describe("comments", "Preserve copyright comments in the output. \ 44 | By default this works like Google Closure, keeping JSDoc-style comments that contain \"@license\" or \"@preserve\". \ 45 | You can optionally pass one of the following arguments to this flag:\n\ 46 | - \"all\" to keep all comments\n\ 47 | - a valid JS regexp (needs to start with a slash) to keep only comments that match.\n\ 48 | \ 49 | Note that currently not *all* comments can be kept when compression is on, \ 50 | because of dead code removal or cascading statements into sequences.") 51 | 52 | .describe("preamble", "Preamble to prepend to the output. You can use this to insert a \ 53 | comment, for example for licensing information. This will not be \ 54 | parsed, but the source map will adjust for its presence.") 55 | 56 | .describe("stats", "Display operations run time on STDERR.") 57 | .describe("acorn", "Use Acorn for parsing.") 58 | .describe("spidermonkey", "Assume input files are SpiderMonkey AST format (as JSON).") 59 | .describe("self", "Build itself (UglifyJS2) as a library (implies --wrap=UglifyJS --export-all)") 60 | .describe("wrap", "Embed everything in a big function, making the “exports” and “global” variables available. \ 61 | You need to pass an argument to this option to specify the name that your module will take when included in, say, a browser.") 62 | .describe("export-all", "Only used when --wrap, this tells UglifyJS to add code to automatically export all globals.") 63 | .describe("lint", "Display some scope warnings") 64 | .describe("v", "Verbose") 65 | .describe("V", "Print version number and exit.") 66 | .describe("noerr", "Don't throw an error for unknown options in -c, -b or -m.") 67 | .describe("bare-returns", "Allow return outside of functions. Useful when minifying CommonJS modules.") 68 | .describe("keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.") 69 | .describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)") 70 | .describe("reserved-file", "File containing reserved names") 71 | .describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props") 72 | .describe("mangle-props", "Mangle property names") 73 | .describe("mangle-regex", "Only mangle property names matching the regex") 74 | .describe("name-cache", "File to hold mangled names mappings") 75 | .describe("pure-funcs", "List of functions that can be safely removed if their return value is not used") 76 | .describe("dump-spidermonkey-ast", "Dump SpiderMonkey AST to stdout.") 77 | 78 | .alias("p", "prefix") 79 | .alias("o", "output") 80 | .alias("v", "verbose") 81 | .alias("b", "beautify") 82 | .alias("m", "mangle") 83 | .alias("c", "compress") 84 | .alias("d", "define") 85 | .alias("r", "reserved") 86 | .alias("V", "version") 87 | .alias("e", "enclose") 88 | .alias("q", "quotes") 89 | 90 | .string("source-map") 91 | .string("source-map-root") 92 | .string("source-map-url") 93 | .string("b") 94 | .string("beautify") 95 | .string("m") 96 | .string("mangle") 97 | .string("c") 98 | .string("compress") 99 | .string("d") 100 | .string("define") 101 | .string("e") 102 | .string("enclose") 103 | .string("comments") 104 | .string("wrap") 105 | .string("p") 106 | .string("prefix") 107 | .string("name-cache") 108 | .array("reserved-file") 109 | .array("pure-funcs") 110 | 111 | .boolean("expr") 112 | .boolean("source-map-include-sources") 113 | .boolean("screw-ie8") 114 | .boolean("export-all") 115 | .boolean("self") 116 | .boolean("v") 117 | .boolean("verbose") 118 | .boolean("stats") 119 | .boolean("acorn") 120 | .boolean("spidermonkey") 121 | .boolean("dump-spidermonkey-ast") 122 | .boolean("lint") 123 | .boolean("V") 124 | .boolean("version") 125 | .boolean("noerr") 126 | .boolean("bare-returns") 127 | .boolean("keep-fnames") 128 | .boolean("mangle-props") 129 | .boolean("reserve-domprops") 130 | 131 | .wrap(80) 132 | 133 | .argv 134 | ; 135 | 136 | normalize(ARGS); 137 | 138 | if (ARGS.noerr) { 139 | UglifyJS.DefaultsError.croak = function(msg, defs) { 140 | print_error("WARN: " + msg); 141 | }; 142 | } 143 | 144 | if (ARGS.version || ARGS.V) { 145 | var json = require("../package.json"); 146 | print(json.name + ' ' + json.version); 147 | process.exit(0); 148 | } 149 | 150 | if (ARGS.ast_help) { 151 | var desc = UglifyJS.describe_ast(); 152 | print(typeof desc == "string" ? desc : JSON.stringify(desc, null, 2)); 153 | process.exit(0); 154 | } 155 | 156 | if (ARGS.h || ARGS.help) { 157 | print(yargs.help()); 158 | process.exit(0); 159 | } 160 | 161 | if (ARGS.acorn) { 162 | acorn = require("acorn"); 163 | } 164 | 165 | var COMPRESS = getOptions("c", true); 166 | var MANGLE = getOptions("m", true); 167 | var BEAUTIFY = getOptions("b", true); 168 | var RESERVED = null; 169 | 170 | if (ARGS.reserved_file) ARGS.reserved_file.forEach(function(filename){ 171 | RESERVED = UglifyJS.readReservedFile(filename, RESERVED); 172 | }); 173 | 174 | if (ARGS.reserve_domprops) { 175 | RESERVED = UglifyJS.readDefaultReservedFile(RESERVED); 176 | } 177 | 178 | if (ARGS.d) { 179 | if (COMPRESS) COMPRESS.global_defs = getOptions("d"); 180 | } 181 | 182 | if (ARGS.pure_funcs) { 183 | if (COMPRESS) COMPRESS.pure_funcs = ARGS.pure_funcs; 184 | } 185 | 186 | if (ARGS.r) { 187 | if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/); 188 | } 189 | 190 | if (RESERVED && MANGLE) { 191 | if (!MANGLE.except) MANGLE.except = RESERVED.vars; 192 | else MANGLE.except = MANGLE.except.concat(RESERVED.vars); 193 | } 194 | 195 | function readNameCache(key) { 196 | return UglifyJS.readNameCache(ARGS.name_cache, key); 197 | } 198 | 199 | function writeNameCache(key, cache) { 200 | return UglifyJS.writeNameCache(ARGS.name_cache, key, cache); 201 | } 202 | 203 | function extractRegex(str) { 204 | if (/^\/.*\/[a-zA-Z]*$/.test(str)) { 205 | var regex_pos = str.lastIndexOf("/"); 206 | return new RegExp(str.substr(1, regex_pos - 1), str.substr(regex_pos + 1)); 207 | } else { 208 | throw new Error("Invalid regular expression: " + str); 209 | } 210 | } 211 | 212 | if (ARGS.quotes === true) { 213 | ARGS.quotes = 3; 214 | } 215 | 216 | var OUTPUT_OPTIONS = { 217 | beautify : BEAUTIFY ? true : false, 218 | preamble : ARGS.preamble || null, 219 | quote_style : ARGS.quotes != null ? ARGS.quotes : 0 220 | }; 221 | 222 | if (ARGS.screw_ie8) { 223 | if (COMPRESS) COMPRESS.screw_ie8 = true; 224 | if (MANGLE) MANGLE.screw_ie8 = true; 225 | OUTPUT_OPTIONS.screw_ie8 = true; 226 | } 227 | 228 | if (ARGS.keep_fnames) { 229 | if (COMPRESS) COMPRESS.keep_fnames = true; 230 | if (MANGLE) MANGLE.keep_fnames = true; 231 | } 232 | 233 | if (BEAUTIFY) 234 | UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY); 235 | 236 | if (ARGS.comments != null) { 237 | if (/^\/.*\/[a-zA-Z]*$/.test(ARGS.comments)) { 238 | try { 239 | OUTPUT_OPTIONS.comments = extractRegex(ARGS.comments); 240 | } catch (e) { 241 | print_error("ERROR: Invalid --comments: " + e.message); 242 | } 243 | } else if (ARGS.comments == "all") { 244 | OUTPUT_OPTIONS.comments = true; 245 | } else { 246 | OUTPUT_OPTIONS.comments = function(node, comment) { 247 | var text = comment.value; 248 | var type = comment.type; 249 | if (type == "comment2") { 250 | // multiline comment 251 | return /@preserve|@license|@cc_on/i.test(text); 252 | } 253 | } 254 | } 255 | } 256 | 257 | var files = ARGS._.slice(); 258 | 259 | if (ARGS.self) { 260 | if (files.length > 0) { 261 | print_error("WARN: Ignoring input files since --self was passed"); 262 | } 263 | files = UglifyJS.FILES; 264 | if (!ARGS.wrap) ARGS.wrap = "UglifyJS"; 265 | } 266 | 267 | var ORIG_MAP = ARGS.in_source_map; 268 | 269 | if (ORIG_MAP) { 270 | ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP)); 271 | if (files.length == 0) { 272 | print_error("INFO: Using file from the input source map: " + ORIG_MAP.file); 273 | files = [ ORIG_MAP.file ]; 274 | } 275 | if (ARGS.source_map_root == null) { 276 | ARGS.source_map_root = ORIG_MAP.sourceRoot; 277 | } 278 | } 279 | 280 | if (files.length == 0) { 281 | files = [ "-" ]; 282 | } 283 | 284 | if (files.indexOf("-") >= 0 && ARGS.source_map) { 285 | print_error("ERROR: Source map doesn't work with input from STDIN"); 286 | process.exit(1); 287 | } 288 | 289 | if (files.filter(function(el){ return el == "-" }).length > 1) { 290 | print_error("ERROR: Can read a single file from STDIN (two or more dashes specified)"); 291 | process.exit(1); 292 | } 293 | 294 | var STATS = {}; 295 | var OUTPUT_FILE = ARGS.o; 296 | var TOPLEVEL = null; 297 | var P_RELATIVE = ARGS.p && ARGS.p == "relative"; 298 | var SOURCES_CONTENT = {}; 299 | 300 | var SOURCE_MAP = ARGS.source_map ? UglifyJS.SourceMap({ 301 | file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE, 302 | root: ARGS.source_map_root, 303 | orig: ORIG_MAP, 304 | }) : null; 305 | 306 | OUTPUT_OPTIONS.source_map = SOURCE_MAP; 307 | 308 | try { 309 | var output = UglifyJS.OutputStream(OUTPUT_OPTIONS); 310 | var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS); 311 | } catch(ex) { 312 | if (ex instanceof UglifyJS.DefaultsError) { 313 | print_error(ex.msg); 314 | print_error("Supported options:"); 315 | print_error(sys.inspect(ex.defs)); 316 | process.exit(1); 317 | } 318 | } 319 | 320 | async.eachLimit(files, 1, function (file, cb) { 321 | read_whole_file(file, function (err, code) { 322 | if (err) { 323 | print_error("ERROR: can't read file: " + file); 324 | process.exit(1); 325 | } 326 | if (ARGS.p != null) { 327 | if (P_RELATIVE) { 328 | file = path.relative(path.dirname(ARGS.source_map), file).replace(/\\/g, '/'); 329 | } else { 330 | var p = parseInt(ARGS.p, 10); 331 | if (!isNaN(p)) { 332 | file = file.replace(/^\/+/, "").split(/\/+/).slice(ARGS.p).join("/"); 333 | } 334 | } 335 | } 336 | SOURCES_CONTENT[file] = code; 337 | time_it("parse", function(){ 338 | if (ARGS.spidermonkey) { 339 | var program = JSON.parse(code); 340 | if (!TOPLEVEL) TOPLEVEL = program; 341 | else TOPLEVEL.body = TOPLEVEL.body.concat(program.body); 342 | } 343 | else if (ARGS.acorn) { 344 | TOPLEVEL = acorn.parse(code, { 345 | locations : true, 346 | sourceFile : file, 347 | program : TOPLEVEL 348 | }); 349 | } 350 | else { 351 | try { 352 | TOPLEVEL = UglifyJS.parse(code, { 353 | filename : file, 354 | toplevel : TOPLEVEL, 355 | expression : ARGS.expr, 356 | bare_returns : ARGS.bare_returns, 357 | }); 358 | } catch(ex) { 359 | if (ex instanceof UglifyJS.JS_Parse_Error) { 360 | print_error("Parse error at " + file + ":" + ex.line + "," + ex.col); 361 | print_error(ex.message); 362 | print_error(ex.stack); 363 | process.exit(1); 364 | } 365 | throw ex; 366 | } 367 | }; 368 | }); 369 | cb(); 370 | }); 371 | }, function () { 372 | if (ARGS.acorn || ARGS.spidermonkey) time_it("convert_ast", function(){ 373 | TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL); 374 | }); 375 | 376 | if (ARGS.wrap != null) { 377 | TOPLEVEL = TOPLEVEL.wrap_commonjs(ARGS.wrap, ARGS.export_all); 378 | } 379 | 380 | if (ARGS.enclose != null) { 381 | var arg_parameter_list = ARGS.enclose; 382 | if (arg_parameter_list === true) { 383 | arg_parameter_list = []; 384 | } 385 | else if (!(arg_parameter_list instanceof Array)) { 386 | arg_parameter_list = [arg_parameter_list]; 387 | } 388 | TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list); 389 | } 390 | 391 | if (ARGS.mangle_props || ARGS.name_cache) (function(){ 392 | var reserved = RESERVED ? RESERVED.props : null; 393 | var cache = readNameCache("props"); 394 | var regex; 395 | 396 | try { 397 | regex = ARGS.mangle_regex ? extractRegex(ARGS.mangle_regex) : null; 398 | } catch (e) { 399 | print_error("ERROR: Invalid --mangle-regex: " + e.message); 400 | process.exit(1); 401 | } 402 | 403 | TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, { 404 | reserved : reserved, 405 | cache : cache, 406 | only_cache : !ARGS.mangle_props, 407 | regex : regex 408 | }); 409 | writeNameCache("props", cache); 410 | })(); 411 | 412 | var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint 413 | var TL_CACHE = readNameCache("vars"); 414 | 415 | if (SCOPE_IS_NEEDED) { 416 | time_it("scope", function(){ 417 | TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE }); 418 | if (ARGS.lint) { 419 | TOPLEVEL.scope_warnings(); 420 | } 421 | }); 422 | } 423 | 424 | if (COMPRESS) { 425 | time_it("squeeze", function(){ 426 | TOPLEVEL = TOPLEVEL.transform(compressor); 427 | }); 428 | } 429 | 430 | if (SCOPE_IS_NEEDED) { 431 | time_it("scope", function(){ 432 | TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE }); 433 | if (MANGLE && !TL_CACHE) { 434 | TOPLEVEL.compute_char_frequency(MANGLE); 435 | } 436 | }); 437 | } 438 | 439 | if (MANGLE) time_it("mangle", function(){ 440 | MANGLE.cache = TL_CACHE; 441 | TOPLEVEL.mangle_names(MANGLE); 442 | }); 443 | 444 | writeNameCache("vars", TL_CACHE); 445 | 446 | if (ARGS.source_map_include_sources) { 447 | for (var file in SOURCES_CONTENT) { 448 | if (SOURCES_CONTENT.hasOwnProperty(file)) { 449 | SOURCE_MAP.get().setSourceContent(file, SOURCES_CONTENT[file]); 450 | } 451 | } 452 | } 453 | 454 | if (ARGS.dump_spidermonkey_ast) { 455 | print(JSON.stringify(TOPLEVEL.to_mozilla_ast(), null, 2)); 456 | } else { 457 | time_it("generate", function(){ 458 | TOPLEVEL.print(output); 459 | }); 460 | 461 | output = output.get(); 462 | 463 | if (SOURCE_MAP) { 464 | fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8"); 465 | var source_map_url = ARGS.source_map_url || ( 466 | P_RELATIVE 467 | ? path.relative(path.dirname(OUTPUT_FILE), ARGS.source_map) 468 | : ARGS.source_map 469 | ); 470 | output += "\n//# sourceMappingURL=" + source_map_url; 471 | } 472 | 473 | if (OUTPUT_FILE) { 474 | fs.writeFileSync(OUTPUT_FILE, output, "utf8"); 475 | } else { 476 | print(output); 477 | } 478 | } 479 | 480 | if (ARGS.stats) { 481 | print_error(UglifyJS.string_template("Timing information (compressed {count} files):", { 482 | count: files.length 483 | })); 484 | for (var i in STATS) if (STATS.hasOwnProperty(i)) { 485 | print_error(UglifyJS.string_template("- {name}: {time}s", { 486 | name: i, 487 | time: (STATS[i] / 1000).toFixed(3) 488 | })); 489 | } 490 | } 491 | }); 492 | 493 | /* -----[ functions ]----- */ 494 | 495 | function normalize(o) { 496 | for (var i in o) if (o.hasOwnProperty(i) && /-/.test(i)) { 497 | o[i.replace(/-/g, "_")] = o[i]; 498 | delete o[i]; 499 | } 500 | } 501 | 502 | function getOptions(flag, constants) { 503 | var x = ARGS[flag]; 504 | if (x == null || x === false) return null; 505 | var ret = {}; 506 | if (x !== "") { 507 | if (Array.isArray(x)) x = x.map(function (v) { return "(" + v + ")"; }).join(", "); 508 | 509 | var ast; 510 | try { 511 | ast = UglifyJS.parse(x, { expression: true }); 512 | } catch(ex) { 513 | if (ex instanceof UglifyJS.JS_Parse_Error) { 514 | print_error("Error parsing arguments for flag `" + flag + "': " + x); 515 | process.exit(1); 516 | } 517 | } 518 | ast.walk(new UglifyJS.TreeWalker(function(node){ 519 | if (node instanceof UglifyJS.AST_Seq) return; // descend 520 | if (node instanceof UglifyJS.AST_Assign) { 521 | var name = node.left.print_to_string({ beautify: false }).replace(/-/g, "_"); 522 | var value = node.right; 523 | if (constants) 524 | value = new Function("return (" + value.print_to_string() + ")")(); 525 | ret[name] = value; 526 | return true; // no descend 527 | } 528 | if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_Binary) { 529 | var name = node.print_to_string({ beautify: false }).replace(/-/g, "_"); 530 | ret[name] = true; 531 | return true; // no descend 532 | } 533 | print_error(node.TYPE) 534 | print_error("Error parsing arguments for flag `" + flag + "': " + x); 535 | process.exit(1); 536 | })); 537 | } 538 | return ret; 539 | } 540 | 541 | function read_whole_file(filename, cb) { 542 | if (filename == "-") { 543 | var chunks = []; 544 | process.stdin.setEncoding('utf-8'); 545 | process.stdin.on('data', function (chunk) { 546 | chunks.push(chunk); 547 | }).on('end', function () { 548 | cb(null, chunks.join("")); 549 | }); 550 | process.openStdin(); 551 | } else { 552 | fs.readFile(filename, "utf-8", cb); 553 | } 554 | } 555 | 556 | function time_it(name, cont) { 557 | var t1 = new Date().getTime(); 558 | var ret = cont(); 559 | if (ARGS.stats) { 560 | var spent = new Date().getTime() - t1; 561 | if (STATS[name]) STATS[name] += spent; 562 | else STATS[name] = spent; 563 | } 564 | return ret; 565 | } 566 | 567 | function print_error(msg) { 568 | console.error("%s", msg); 569 | } 570 | 571 | function print(txt) { 572 | console.log("%s", txt); 573 | } 574 | -------------------------------------------------------------------------------- /node_modules/.bin/uuid: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var path = require('path'); 4 | var uuid = require(path.join(__dirname, '..')); 5 | 6 | var arg = process.argv[2]; 7 | 8 | if ('--help' === arg) { 9 | console.log('\n USAGE: uuid [version] [options]\n\n'); 10 | console.log(' options:\n'); 11 | console.log(' --help Display this message and exit\n'); 12 | process.exit(0); 13 | } 14 | 15 | if (null == arg) { 16 | console.log(uuid()); 17 | process.exit(0); 18 | } 19 | 20 | if ('v1' !== arg && 'v4' !== arg) { 21 | console.error('Version must be RFC4122 version 1 or version 4, denoted as "v1" or "v4"'); 22 | process.exit(1); 23 | } 24 | 25 | console.log(uuid[arg]()); 26 | process.exit(0); 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "isu-survey", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "main.js", 6 | "dependencies": { 7 | "body-parser": "^1.15.0", 8 | "dateformat": "^1.0.12", 9 | "express": "^4.13.4", 10 | "express-session": "^1.13.0", 11 | "iconv-lite": "^0.4.13", 12 | "jade": "^1.11.0", 13 | "morgan": "^1.7.0", 14 | "request": "^2.69.0", 15 | "tough-cookie-filestore": "0.0.1" 16 | }, 17 | "devDependencies": {}, 18 | "scripts": { 19 | "test": "echo \"Error: no test specified\" && exit 1" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/aaaddress1/isuSurvey-NodeJS.git" 24 | }, 25 | "keywords": [ 26 | "isu", 27 | "survey" 28 | ], 29 | "author": "aaaddress1 ", 30 | "license": "ISC", 31 | "bugs": { 32 | "url": "https://github.com/aaaddress1/isuSurvey-NodeJS/issues" 33 | }, 34 | "homepage": "https://github.com/aaaddress1/isuSurvey-NodeJS#readme" 35 | } 36 | -------------------------------------------------------------------------------- /public/css/animate.min.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";/*! 2 | Animate.css - http://daneden.me/animate 3 | Licensed under the MIT license - http://opensource.org/licenses/MIT 4 | 5 | Copyright (c) 2015 Daniel Eden 6 | */.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{0%,100%,20%,53%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,100%,20%,53%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-transition-timing-function:cubic-bezier(0.755,.050,.855,.060);transition-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{0%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes bounceIn{0%,100%,20%,40%,60%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{0%,100%,20%,40%,60%,80%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{0%,100%,60%,75%,90%{-webkit-transition-timing-function:cubic-bezier(0.215,.61,.355,1);transition-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{0%{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp} -------------------------------------------------------------------------------- /public/css/font.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Ubuntu); 2 | @font-face { 3 | font-family: 'cwTexHei'; 4 | font-style: normal; 5 | font-weight: 500; 6 | src: url(//fonts.gstatic.com/ea/cwtexhei/v3/cwTeXHei-zhonly.eot); 7 | src: url(//fonts.gstatic.com/ea/cwtexhei/v3/cwTeXHei-zhonly.eot?#iefix) format('embedded-opentype'), 8 | url(//fonts.gstatic.com/ea/cwtexhei/v3/cwTeXHei-zhonly.woff2) format('woff2'), 9 | url(//fonts.gstatic.com/ea/cwtexhei/v3/cwTeXHei-zhonly.woff) format('woff'), 10 | url(//fonts.gstatic.com/ea/cwtexhei/v3/cwTeXHei-zhonly.ttf) format('truetype'); 11 | } 12 | 13 | h1, 14 | h2, 15 | h3, 16 | h4, 17 | h5, 18 | h6, 19 | body, 20 | .h1, 21 | .h2, 22 | .h3, 23 | .h4, 24 | .h5, 25 | .h6 { 26 | font-family: "cwTexHei","Ubuntu", "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; 27 | font-weight: 500; 28 | } 29 | 30 | .head{ 31 | font-family: "cwTexHei","Ubuntu", "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; 32 | font-size: 14px; 33 | color: #aaa; 34 | } 35 | 36 | .footer { 37 | position: absolute; 38 | bottom: 0; 39 | width: 100%; 40 | /* Set the fixed height of the footer here */ 41 | height: auto; 42 | background-color: #47314E; 43 | padding-top: 20px; 44 | padding-bottom: 20px; 45 | } 46 | 47 | html { 48 | position: relative; 49 | min-height: 100%; 50 | } 51 | 52 | body { 53 | margin-bottom: 60px; 54 | } -------------------------------------------------------------------------------- /router/main.js: -------------------------------------------------------------------------------- 1 | // require Modules 2 | var isu = require('../lib/isu/isu'); 3 | var survey = require('../lib/isu/survey'); 4 | var isuClass = require('../lib/isu/isuClass'); 5 | var moodle = require('../lib/isu/isuMoodle'); 6 | var moment = require('moment'); 7 | var express = require('express'); 8 | var router = express.Router(); 9 | 10 | // Routers 11 | router.route('/getAbsenteeism') 12 | .get(function(req, res){ 13 | 14 | res.set({ 'content-type': 'application/json; charset=utf-8' }); 15 | 16 | isuClass.displyNowAbsenteeism( req, res, function(absenceArr, vacationArr){ 17 | res.end( JSON.stringify({absenceArr, vacationArr},null,10) ); 18 | } ); 19 | 20 | }); 21 | 22 | router.route('/getTodayClasses') 23 | .get(function(req, res){ 24 | isuClass.displayDay( req, res, function( today, list, tommow, tommowList, error ) { 25 | res.set({ 'content-type': 'application/json; charset=utf-8' }); 26 | res.end( JSON.stringify({today,list,tommow,tommowList,error:error},null,10) ); 27 | }); 28 | }); 29 | 30 | router.route('/getTodayMoodle') 31 | .get(function(req,res) { 32 | moodle.displyNowClass(req, res, function( alivArr, deadArr, infoArr, quizArr, totalClassArr, error ) { 33 | res.set({ 'content-type': 'application/json; charset=utf-8' }); 34 | res.end( JSON.stringify({alivArr, deadArr, infoArr, quizArr, totalClassArr, error:error},null,10) ); 35 | 36 | }); 37 | }); 38 | 39 | router.route('/about') 40 | .get(function(req, res){ 41 | res.end('安安!尼好!
我是作者馬聖豪!由於我現在懶得寫這頁所以很粗略隨便寫了下這頁
我也是義守學生 & 這支網站採 node.js 撰寫
如果遇到任何問題可發信至 aaaaddress1@gmail.com 給我唷 O_<') 42 | }); 43 | 44 | router.route('/isuSurvey') 45 | .get(function(req, res){ 46 | survey.displayAll(req, res, function(classNameAll) { 47 | "use strict"; 48 | let NewMessage = '' 49 | 50 | res.render('survey.jade', { 51 | list: classNameAll, 52 | usrName: req.cookies.name, 53 | NewMessage: NewMessage 54 | }); 55 | }); 56 | }); 57 | 58 | router.route('/isuSurvey') 59 | .post(function(req, res) { 60 | "use strict"; 61 | let NewMessage = ''; 62 | let sucessed = false; 63 | 64 | survey.sendSurvey( req.body.classId, req.body.cmd, req, function(sendSurveyRes) { 65 | 66 | if ( sendSurveyRes.indexOf('您可填寫的課程意見評量表') > -1 ) { 67 | NewMessage = req.body.className + ' 填寫成功'; 68 | sucessed = true; 69 | } 70 | else { 71 | NewMessage = req.body.className + ' 填寫失敗O_Q...'; 72 | sucessed = false; 73 | } 74 | res.set({ 'content-type': 'application/json; charset=utf-8' }); 75 | res.end( JSON.stringify({NewMessage,sucessed},null,10) ); 76 | }); 77 | }); 78 | 79 | router.route('/isuMoodle') 80 | .get(function(req, res) { 81 | 82 | if ( req.cookies && req.cookies.isuMoodleCookie && (req.cookies.isuMoodleCookie != '')){ 83 | res.render('moodle.jade',{ usrName: req.cookies.name, 84 | moodleUsr: req.cookies.loginMail, 85 | moodlePass: req.cookies.loginPass }); 86 | } 87 | else { 88 | 89 | moodle.login( req, res, req.cookies.loginMail, req.cookies.loginPass, function(s) { 90 | if (s) 91 | res.redirect('/isuMoodle'); 92 | else 93 | res.redirect('./?act=logout'); 94 | //res.end('機器人嘗試以' + req.cookies.loginMail + ' 身份登入 Moodle 系統失敗了!'); 95 | }); 96 | } 97 | 98 | // 99 | }); 100 | 101 | router.route('/') 102 | .get(function(req, res){ 103 | 104 | if ( req.query.act == 'logout' ) { 105 | res.cookie('name',''); 106 | res.cookie('isuAppCookie', '' ); 107 | res.cookie('isuMoodleCookie', '' ); 108 | res.redirect('/?act=nope'); 109 | } 110 | else if ( req.query.act == 'login' ) { 111 | 112 | if ( req.cookies && (req.cookies.name != '') ) { 113 | res.redirect('./'); 114 | } 115 | else 116 | res.render('login.jade', { defaultUsr:'', defaultPass: '', errorMsg: '登入失敗, 帳號密碼不正確?' }); 117 | } 118 | else { 119 | 120 | if ( req.cookies && req.cookies.name && (req.cookies.name != '') ) 121 | res.render('mainPage.jade', { usrName: req.cookies.name }); 122 | 123 | else { 124 | 125 | if (req.cookies.loginMail && req.cookies.loginPass ) 126 | res.render('login.jade', { defaultUsr:req.cookies.loginMail, 127 | defaultPass:req.cookies.loginPass }); 128 | else 129 | res.render('login.jade', { defaultUsr:'', defaultPass: '' }); 130 | } 131 | 132 | } 133 | }); 134 | 135 | router.route('/') 136 | .post(function(req, res) { 137 | isu.login( req.body.usrId, req.body.usrPass, req, res, function(){ 138 | res.redirect('./?act=login'); 139 | }); 140 | }); 141 | 142 | // export module 143 | module.exports = router; -------------------------------------------------------------------------------- /views/login.jade: -------------------------------------------------------------------------------- 1 | extends ./template/bootstrap 2 | 3 | block title 4 | title= '義守管家' 5 | block content 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | .navbar-header 9 | button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#mynav', aria-expanded='false', aria-controls='mynav') 10 | span.sr-only Toggle navigation 11 | span.icon-bar 12 | span.icon-bar 13 | span.icon-bar 14 | 15 | a.navbar-brand(href=".") 義守管家 16 | 17 | .collapse.navbar-collapse(id='mynav') 18 | 19 | ul.nav.navbar-nav.navbar-right 20 | li 21 | a(href='/about') 關於 22 | 23 | div(class ='panel panel',style='margin: auto; ') 24 | center 25 | div(class='panel-heading') 26 | h1(class='panel-title') 27 | | 義守管家 28 | 29 | div(class='panel-body') 30 | form(name= 'eachClass', action='/', method= 'POST') 31 | div.input(class='input-group') 32 | span(class="input-group-addon") 義守大學帳號 33 | input(class= "form-control", type="text", name="usrId", placeholder='isu********', value= '' + defaultUsr ) 34 | div.input(class='input-group') 35 | span(class="input-group-addon") 義守大學密碼 36 | input(class= "form-control", type="password", name="usrPass", placeholder='password',value= '' + defaultPass ) 37 | h5(style= "color: orange;")= errorMsg 38 | div.input 39 | input.btn.btn-success.btn-block(type="submit",value= '登入帳號') 40 | div(class='panel-footer') 41 | |帳號密碼為您登入義守大學應用資訊系統之帳號密碼組合。 42 | 43 | -------------------------------------------------------------------------------- /views/mainPage.jade: -------------------------------------------------------------------------------- 1 | extends ./template/bootstrap 2 | 3 | block title 4 | title 義守管家 (#{usrName}) 5 | 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | .navbar-header 9 | button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#mynav', aria-expanded='false', aria-controls='mynav') 10 | span.sr-only Toggle navigation 11 | span.icon-bar 12 | span.icon-bar 13 | span.icon-bar 14 | 15 | a.navbar-brand(href=".") 義守管家 16 | 17 | .collapse.navbar-collapse(id='mynav') 18 | ul.nav.navbar-nav 19 | li 20 | a(href='/') 總覽 21 | li 22 | a(href='/isuMoodle') Moodle管理 23 | li 24 | a(href='/isuSurvey') 問卷機器人 25 | ul.nav.navbar-nav.navbar-right 26 | li 27 | a(href='/?act=logout') 登出 (#{usrName}) 28 | 29 | 30 | 31 | 32 | 33 | block content 34 | .container 35 | script. 36 | $(document).ready(function() { 37 | RefreshTable(); 38 | RefreshVacation(); 39 | }); 40 | 41 | function RefreshVacation() { 42 | $.ajax({ 43 | url: '/getAbsenteeism', 44 | success: function(data) { 45 | 46 | if (data['absenceArr'] == null || data['vacationArr'] == null) { 47 | window.location.replace('/?act=logout'); 48 | return; 49 | } 50 | $('#vacationHeader').html('出缺席狀況'); 51 | 52 | var currTableBody = $("#vacationTable").find("tbody"); 53 | for(var i in data['absenceArr']) { 54 | var curClass = data['absenceArr'][i]; 55 | currTableBody.append( '' + 56 | '' + curClass[1] + '' + 57 | '' + curClass[2] + '' + 58 | '' + curClass[3] + '' + 59 | '曠課' + 60 | ''); 61 | } 62 | for(var i in data['vacationArr']) { 63 | var curClass = data['vacationArr'][i]; 64 | currTableBody.append( '' + 65 | '' + curClass[1] + '' + 66 | '' + curClass[2] + '' + 67 | '' + curClass[3] + '' + 68 | '' + curClass[4] + '' + 69 | ''); 70 | } 71 | } 72 | }); 73 | } 74 | 75 | function RefreshTable() { 76 | 77 | $.ajax({ 78 | url: '/getTodayClasses', 79 | success: function(data) { 80 | 81 | if (data['error']) { 82 | window.location.replace('/?act=logout'); 83 | return; 84 | } 85 | $('#todayHeader').html('今天 星期' + data['today']); 86 | $('#tommoHeader').html('明天 星期' + data['tommow']); 87 | 88 | var currTableBody = $("#todayTable").find("tbody"); 89 | for(var i in data['list']) { 90 | var curClass = data['list'][i]; 91 | currTableBody.append( '' + 92 | '' + curClass[0] + '' + 93 | '' + curClass[1] + '' + 94 | '' + curClass[2] + '' + 95 | '' + curClass[3] + '' + 96 | '' + curClass[4] + '' + 97 | '' + curClass[5] + '' + 98 | ''); 99 | } 100 | 101 | var currTableBody = $("#tommowTable").find("tbody"); 102 | for(var i in data['tommowList']) { 103 | var curClass = data['tommowList'][i]; 104 | currTableBody.append( '' + 105 | '' + curClass[0] + '' + 106 | '' + curClass[1] + '' + 107 | '' + curClass[2] + '' + 108 | '' + curClass[3] + '' + 109 | '' + curClass[4] + '' + 110 | '' + curClass[5] + '' + 111 | ''); 112 | } 113 | } 114 | }); 115 | } 116 | 117 | 118 | h1 總覽 119 | 120 | 121 | div(class ='panel panel-warning') 122 | div(class='panel-heading', id='todayHeader' ,data-toggle='collapse', data-parent='#accordion', href='#collapseOne',aria-expanded='true', aria-controls='collapseOne') 123 | #collapseOne.panel-collapse.collapse.in(role='tabpanel', aria-labelledby='collapseOne') 124 | 125 | table.table.table-striped.table-hover(id='todayTable') 126 | thead 127 | tr 128 | th 時間 129 | th 是否可翹 130 | th 教授 131 | th 系級 132 | th 科目 133 | th 教室 134 | tbody 135 | 136 | 137 | div(class ='panel panel-default') 138 | div(class='panel-heading',id='tommoHeader', data-toggle='collapse', data-parent='#accordion', href='#collapseTwo', aria-expanded='true', aria-controls='collapseTwo') 139 | 140 | #collapseTwo.panel-collapse.collapse.in(role='tabpanel', aria-labelledby='') 141 | table.table.table-striped.table-hover(id='tommowTable') 142 | thead 143 | tr 144 | th 時間 145 | th 是否可翹 146 | th 教授 147 | th 系級 148 | th 科目 149 | th 教室 150 | tbody 151 | 152 | 153 | div(class ='panel panel-success') 154 | div(class='panel-heading',id='vacationHeader', data-toggle='collapse', data-parent='#accordion', href='#collapseThree', aria-expanded='true', aria-controls='collapseThree') 155 | 156 | #collapseThree.panel-collapse.collapse.in(role='tabpanel', aria-labelledby='') 157 | table.table.table-striped.table-hover(id='vacationTable') 158 | thead 159 | tr 160 | th 課名 161 | th 日期 162 | th 節數 163 | th 狀態 164 | tbody 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /views/moodle.jade: -------------------------------------------------------------------------------- 1 | extends ./template/bootstrap 2 | 3 | block title 4 | title 義守管家 (#{usrName}) 5 | 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | .navbar-header 9 | button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#mynav', aria-expanded='false', aria-controls='mynav') 10 | span.sr-only Toggle navigation 11 | span.icon-bar 12 | span.icon-bar 13 | span.icon-bar 14 | 15 | a.navbar-brand(href=".") 義守管家 16 | 17 | .collapse.navbar-collapse(id='mynav') 18 | ul.nav.navbar-nav 19 | li 20 | a(href='/') 總覽 21 | li 22 | a(href='/isuMoodle') Moodle管理 23 | li 24 | a(href='/isuSurvey') 問卷機器人 25 | ul.nav.navbar-nav.navbar-right 26 | li 27 | a(href='/?act=logout') 登出 (#{usrName}) 28 | 29 | block content 30 | .container 31 | script. 32 | function endUsrLoginMoodle(){ 33 | var script = '' 34 | 35 | var iframe = document.createElement('iframe'); 36 | document.body.appendChild(iframe); 37 | iframe.hidden = true; 38 | iframe.contentWindow.document.open(); 39 | iframe.contentWindow.document.write(script); 40 | iframe.contentWindow.document.close(); 41 | } 42 | 43 | $(document).ready(function() { 44 | endUsrLoginMoodle(); 45 | RefreshTable(); 46 | }); 47 | function RefreshTable() { 48 | 49 | $.ajax({ 50 | url: '/getTodayMoodle', 51 | success: function(data) 52 | { 53 | if (data['error']) 54 | window.location.replace('/?act=logout'); 55 | 56 | var currTableBody = $("#alertTable").find("tbody"); 57 | for (var i in data['infoArr']) { 58 | var curClass = data['infoArr'][i]; 59 | currTableBody.append( '' + 60 | '' + curClass[0] + '' + 61 | '' + curClass[1] + '' + 62 | '' + curClass[2] + '' + 63 | '' + curClass[1] + '' + 64 | ''); 65 | } 66 | 67 | currTableBody = $("#aliveTable").find("tbody"); 68 | for (var i in data['alivArr']) { 69 | var curClass = data['alivArr'][i]; 70 | currTableBody.append( '' + 71 | '' + curClass[0] + '' + 72 | '' + curClass[1] + '' + 73 | '' + curClass[2] + '' + 74 | '' + curClass[3] + '' + 75 | '' + curClass[4] + '' + 76 | '作業' + curClass[1] + '' + 77 | ''); 78 | } 79 | 80 | currTableBody = $("#deadTable").find("tbody"); 81 | for (var i in data['deadArr']) { 82 | var curClass = data['deadArr'][i]; 83 | currTableBody.append( '' + 84 | '' + curClass[0] + '' + 85 | '' + curClass[1] + '' + 86 | '' + curClass[2] + '' + 87 | '' + curClass[3] + '' + 88 | '' + curClass[4] + '' + 89 | '作業' + curClass[1] + '' + 90 | ''); 91 | } 92 | 93 | currTableBody = $("#quizTable").find("tbody"); 94 | for (var i in data['quizArr']) { 95 | var curClass = data['quizArr'][i]; 96 | currTableBody.append( '' + 97 | '' + curClass[0] + '' + 98 | '' + curClass[1] + '' + 99 | '' + curClass[2] + '' + 100 | '' + curClass[3] + '' + 101 | '作業' + curClass[1] + '' + 102 | ''); 103 | } 104 | 105 | currTableBody = $("#totalTable").find("tbody"); 106 | for (var i in data['totalClassArr']) { 107 | var curClass = data['totalClassArr'][i]; 108 | currTableBody.append( '' + 109 | '' + curClass[0] + '' + 110 | '前往 ' + curClass[0] + '' + 111 | ''); 112 | } 113 | 114 | } 115 | }); 116 | } 117 | h1 Moodle管理 118 | 119 | 120 | div(class ='panel') 121 | div(class='panel-heading', data-toggle='collapse', data-parent='#accordion', href='#collapseZero', aria-expanded='true', aria-controls='collapseOne') 所有科目列表 122 | 123 | #collapseZero.panel-collapse.collapse.in(role='tabpanel', aria-labelledby='collapseZero') 124 | 125 | div(class='panel-body') 126 | table.table.table-striped.table-hover(id='totalTable') 127 | thead 128 | tr 129 | th 科目 130 | th 前往 Moodle 131 | tbody 132 | 133 | 134 | div(class ='panel panel-warning') 135 | div(class='panel-heading', data-toggle='collapse', data-parent='#accordion', href='#collapseOne', aria-expanded='true', aria-controls='collapseOne') 課程通知 136 | 137 | #collapseOne.panel-collapse.collapse.in(role='tabpanel', aria-labelledby='collapseOne') 138 | 139 | div(class='panel-body') 140 | table.table.table-striped.table-hover(id='alertTable') 141 | thead 142 | tr 143 | th 科目 144 | th 通知標題 145 | th 通知詳情 146 | th 前往 Moodle 147 | tbody 148 | 149 | 150 | div(class ='panel panel-info') 151 | 152 | div(class='panel-heading', data-toggle='collapse', data-parent='#accordion', href='#collapseQuiz', aria-expanded='true', aria-controls='collapseQuiz') 線上測驗 153 | 154 | #collapseQuiz.panel-collapse.collapse.in(role='tabpanel', aria-labelledby='collapseQuiz') 155 | 156 | div(class='panel-body') 157 | table.table.table-striped.table-hover(id='quizTable') 158 | thead 159 | tr 160 | th 科目 161 | th 測驗名稱 162 | th 剩餘天數 163 | th 詳細 164 | th 前往 Moodle 165 | tbody 166 | 167 | 168 | div(class ='panel panel-danger') 169 | 170 | div(class='panel-heading', data-toggle='collapse', data-parent='#accordion', href='#collapseTwo', aria-expanded='true', aria-controls='collapseTwo') 尚未過期 171 | 172 | #collapseTwo.panel-collapse.collapse.in(role='tabpanel', aria-labelledby='collapseTwo') 173 | 174 | div(class='panel-body') 175 | table.table.table-striped.table-hover(id='aliveTable') 176 | thead 177 | tr 178 | th 科目 179 | th 作業名稱 180 | th 剩餘天數 181 | th 狀態 182 | th 詳細 183 | th 前往 Moodle 184 | tbody 185 | 186 | 187 | div(class ='panel panel-success') 188 | div(class='panel-heading', data-toggle='collapse', data-parent='#accordion', href='#collapseThree', aria-expanded='true', aria-controls='collapseThree') 已過期 189 | 190 | #collapseThree.panel-collapse.collapse.in(role='tabpanel',aria-labelledby='collapseThree') 191 | 192 | div(class='panel-body') 193 | table.table.table-striped.table-hover(id='deadTable') 194 | thead 195 | tr 196 | th 科目 197 | th 作業名稱 198 | th 已過期天數 199 | th 狀態 200 | th 詳細 201 | th 前往 Moodle 202 | tbody 203 | -------------------------------------------------------------------------------- /views/survey.jade: -------------------------------------------------------------------------------- 1 | extends ./template/bootstrap 2 | 3 | block title 4 | title 義守管家 (#{usrName}) 5 | 6 | nav.navbar.navbar-default 7 | .container-fluid 8 | .navbar-header 9 | button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#mynav', aria-expanded='false', aria-controls='mynav') 10 | span.sr-only Toggle navigation 11 | span.icon-bar 12 | span.icon-bar 13 | span.icon-bar 14 | 15 | a.navbar-brand(href=".") 義守管家 16 | 17 | .collapse.navbar-collapse(id='mynav') 18 | ul.nav.navbar-nav 19 | li 20 | a(href='/') 總覽 21 | li 22 | a(href='/isuMoodle') Moodle管理 23 | li 24 | a(href='/isuSurvey') 問卷機器人 25 | ul.nav.navbar-nav.navbar-right 26 | li 27 | a(href='/?act=logout') 登出 (#{usrName}) 28 | block content 29 | .container 30 | 31 | h1 問卷機器人 32 | #notifyObj.h2= NewMessage 33 | 34 | script. 35 | function something($this, classId, cmd, className) { 36 | $($this).text('填寫中'); 37 | 38 | $.ajax({ 39 | type: 'POST', 40 | url: '/isuSurvey', 41 | data: 'cmd=' + cmd + '&classId=' + classId + '&className=' + className, 42 | success: function(data) { 43 | if (data['sucessed']) 44 | $($this).text('填寫問卷成功!'); 45 | else 46 | $($this).text('填寫問卷失敗!'); 47 | 48 | $($this).closest('td').prev('td').text(data['NewMessage']); 49 | $("#notifyObj").text(data['NewMessage']); 50 | 51 | } 52 | }); 53 | } 54 | 55 | div(class ='panel panel-warning') 56 | 57 | div(class='panel-heading', data-toggle='collapse', data-parent='#accordion', href='#collapseSurvey', aria-expanded='true', aria-controls='collapseSurvey') 所有問卷 58 | 59 | #collapseSurvey.panel-collapse.collapse.in(role='tabpanel', aria-labelledby='collapseSurvey') 60 | 61 | div(class='panel-body') 62 | table.table.table-striped.table-hover 63 | thead 64 | tr 65 | th 代號 66 | th 科目 67 | th 老師 68 | th 詳細 69 | th 問卷機器人 70 | tbody 71 | 72 | each item, i in list 73 | tr 74 | td= list[i][0] 75 | td= list[i][1] 76 | td= list[i][2] 77 | td= list[i][3] 78 | td 79 | a(onclick='something( this, \ 80 | \'#{list[i][0]}\', \ 81 | \'#{list[i][4]}\', \ 82 | \'#{list[i][1]}\')') 填寫 83 | 84 | -------------------------------------------------------------------------------- /views/template/bootstrap.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | 3 | html(lang="zh_tw") 4 | head 5 | meta(http-equiv="X-UA-Compatible", 6 | name="viewport", 7 | content="width=device-width, initial-scale=1, IE=edge", 8 | charset="utf-8") 9 | 10 | meta(property="og:type", content="article") 11 | meta(property="og:url", content="http://isu.30cm.tw") 12 | meta(property="og:image", content="https://media.licdn.com/mpr/mpr/shrink_200_200/p/6/005/077/3d3/39ef9bb.png") 13 | meta(property="og:title", content="isuMaster 義守管家") 14 | meta(property="og:description", content="整合學校各項功能並優化使用者體驗的網頁服務,提供自動填寫期中末問卷機器人、自動整理課表、Moodle作業分析等服務的完美整合。") 15 | 16 | 17 | block title 18 | title Default Title 19 | 20 | //- jquery 21 | script(src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js") 22 | 23 | //- Bootstrap CSS 24 | 25 | link(href="https://bootswatch.com/darkly/bootstrap.css", rel="stylesheet") 26 | script(src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js") 27 | 28 | //-Google 字體 29 | link(rel="stylesheet", href="http://fonts.googleapis.com/earlyaccess/cwtexhei.css") 30 | link(rel="stylesheet", href="http://fonts.googleapis.com/earlyaccess/cwtexming.css") 31 | 32 | //- 修正字體 33 | link(rel="stylesheet", href="/css/font.css") 34 | 35 | 36 | 37 | 38 | 42 | 43 | style. 44 | .navbar { background-color: transparent; } 45 | 46 | body() 47 | 48 | block content 49 | h1.text-center Default Post 50 | 51 | .foot 52 | div(style='position:absolute; bottom: 0px; right: 0px;') 53 | 54 | | 最後更新 2016/9/15, by aaaddress1@gmail.com ( 55 | a(href='http://facebook.com/aaaddress1') 馬聖豪 56 | |) 57 | --------------------------------------------------------------------------------