diff --git a/app/__init__.py b/app/__init__.py index 9866fb3..9ded301 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,6 +1,6 @@ from flask import Flask from flask_bootstrap import Bootstrap -from app.view import user,uitest,utils,apinew +from app.view import user,uitest,utils,apinew,minder,minderfiles app = Flask(__name__) app.config.from_object('config') @@ -9,4 +9,6 @@ app.register_blueprint(user.mod) app.register_blueprint(uitest.mod) app.register_blueprint(utils.mod) app.register_blueprint(apinew.mod) +app.register_blueprint(minder.mod) +app.register_blueprint(minderfiles.mod) from app import views diff --git a/app/db/test_minder_manage.py b/app/db/test_minder_manage.py new file mode 100644 index 0000000..fc13877 --- /dev/null +++ b/app/db/test_minder_manage.py @@ -0,0 +1,126 @@ +from app import useDB,log +import string + +class test_minder_manage: + def __init__(self): + self.status = 0 + self.name = '' + + def new_minder(self,module,name,description, content='{}'): + import random, time + batchId = str(random.randint(10000, 99999)) + str(time.time()) + content = str(content).replace('"','\\"') + sql = string.Template('insert into test_minder (module,name,description,content,batchId) values ("$module","$name","$description","$content","$batchId");') + sql = sql.substitute(name = name, module = module, description=description, content=content,batchId=batchId) + print(sql) + useDB.useDB().insert(sql) + minders = test_minder_manage().show_test_minders(conditionList=['batchId'], + valueList=[batchId], + rows=1) + result = {} + if len(minders): + result['id'] = minders[0]['id'] + result['code']=1 + else: + result['code']=0 + result['id'] ='' + return result + + def copy_test_minder(self,id): + # module, name, steps, description, isPublic + searchresult = self.show_test_minders(['id'],[id],1) + result ={'code':0} + if len(searchresult): + searchresult=searchresult[0] + result = self.new_minder(name = searchresult['name'], module = searchresult['module'], description=searchresult['description'], content=searchresult['content']) + return result + + + def update_test_minder(self,id,fieldlist,valueList): + update_value = '%s = "%s"' %(fieldlist[0],str(valueList[0]).replace('"','\\"')) + for i in range(1,len(fieldlist)): + print(fieldlist[i]) + # if fieldlist[i]=='content': + update_value += ', %s = "%s"' %(fieldlist[i],str(valueList[i]).replace('"','\\"')) + # else: + # update_value += ', %s = "%s"' %(fieldlist[i],valueList[i]) + sql = string.Template('update test_minder set $field where id = "$id";') + sql = sql.substitute(field = update_value, id = id) + useDB.useDB().insert(sql) + + + def show_test_minders(self,conditionList, valueList, rows): + fieldlist = ['id', 'module', 'name', 'description','content'] + search_value = fieldlist[0] + for i in range(1,len(fieldlist)): + search_value = search_value + ','+fieldlist[i] + condition = '' + for i in range(len(conditionList)): + if valueList[i] !='': + condition += ' and %s = "%s"' %(conditionList[i],valueList[i]) + results = [] + + sql = 'select ' + search_value + ' from test_minder where status = 1 ' + str(condition) + ' order by id desc limit '+ str(rows)+';' + print(sql) + cases = useDB.useDB().search(sql) + log.log().logger.info('cases : %s'%cases) + for i in range(len(cases)): + result = {} + result['id'] = cases[i][0] + result['module'] = cases[i][1] + result['name'] = cases[i][2] + result['description'] = cases[i][3] + result['content'] = cases[i][4] + results.append(result) + return results + + + def show_test_cases_unattach(self,test_suite_id,conditionList, valueList, fieldlist,rows): + fieldlist = ['id', 'module', 'name', 'steps', 'description','isPublicFunction'] + search_value = fieldlist[0] + for i in range(1,len(fieldlist)): + search_value = search_value + ','+fieldlist[i] + results = [] + log.log().logger.info('%s, %s, %s, %s, %s' %(test_suite_id,conditionList, valueList, fieldlist,rows)) + condition = '' + for i in range(len(conditionList)): + if i == 0: + if conditionList[i]=='module': + log.log().logger.info(valueList[i]) + moduleList = '' + for j in range(len(valueList[i])): + if j : + moduleList += ',' + moduleList += '"'+valueList[i][j]+'"' + condition += str(conditionList[i]) + ' in (' + str(moduleList) + ')' + else: + condition += str(conditionList[i]) +' like "%'+str(valueList[i])+'%"' + else: + if conditionList[i] == 'module': + log.log().logger.info(valueList[i]) + moduleList = '' + for j in range(len(valueList[i])): + if j : + moduleList += ',' + moduleList += '"'+valueList[i][j]+'"' + condition += ' and ' + str(conditionList[i]) + ' in (' + str(moduleList) + ')' + else: + condition += ' and '+str(conditionList[i]) +' like "%'+str(valueList[i])+'%"' + if condition !='': + condition += ' and ' + sql = 'select ' + search_value + ' from test_case where status = 1 and isPublicFunction=0 and '+ str(condition) +' id not in (select distinct test_case_id from test_batch where test_suite_id = '+test_suite_id+' ) order by module desc;' + cases = useDB.useDB().search(sql) + log.log().logger.info('cases : %s'%cases) + for i in range(len(cases)): + result = {} + result['id'] = cases[i][0] + result['module'] = cases[i][1] + result['name'] = cases[i][2] + result['steps'] = cases[i][3] + result['description'] = cases[i][4] + result['isPublic'] = cases[i][5] + results.append(result) + return results + + + diff --git a/app/static/minder/.bowerrc b/app/static/minder/.bowerrc new file mode 100644 index 0000000..42b5474 --- /dev/null +++ b/app/static/minder/.bowerrc @@ -0,0 +1,5 @@ +{ + "directory": "bower_components", + "allow_root": true, + "registry": "https://registry.bower.io" +} diff --git a/app/static/minder/.gitignore b/app/static/minder/.gitignore new file mode 100644 index 0000000..d70e693 --- /dev/null +++ b/app/static/minder/.gitignore @@ -0,0 +1,8 @@ +.idea +.DS_Store +bower_components/ +node_modules/ +dist/ +ui/templates.js +.tmp/ +upload/ \ No newline at end of file diff --git a/app/static/minder/.jscsrc b/app/static/minder/.jscsrc new file mode 100644 index 0000000..c5a49f8 --- /dev/null +++ b/app/static/minder/.jscsrc @@ -0,0 +1,103 @@ +/** + * FEX Style Guide (Javascript) + * + * TODO: + * + * 1. 找不到选项:每行只允许一个语句 + * 2. 找不到选项:块状代码需要用大括号括起来 + */ +{ + // 缩进「MUST」使用 4 个空格 + "validateIndentation": 4, + + // 大括号(块状代码)前「MUST」使用空格 + "requireSpaceBeforeBlockStatements": true, + + // 下列关键字「MUST」使用空格 + "requireSpaceAfterKeywords": ["if", "else", "for", "while", + "do", "try", "catch", "finally" + ], + + // `,` 和 `;` 前面不允许「MUST NOT」使用空格。 + "requireLeftStickedOperators": [",", ";"], + + // 二元运算符前后「MUST」使用空格 + "requireSpaceBeforeBinaryOperators": [ + "+", + "-", + "*", + "/", + "=", + "==", + "===", + "!=", + "!==", + "|", + "||", + "&", + "&&" + ], + "requireSpaceAfterBinaryOperators": [ + "+", + "-", + "*", + "/", + "=", + "==", + "===", + "!=", + "!==", + "|", + "||", + "&", + "&&", + ":" + ], + + // 一元运算符与操作对象间「MUST NOT」使用空格 + "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], + + // 函数参数小括号前「MUST NOT」使用空格 + "disallowSpacesInFunctionExpression": { + "beforeOpeningRoundBrace": true + }, + + // 小括号里面「MUST NOT」使用空格 + "disallowSpacesInsideParentheses": true, + + // 行尾「MUST NOT」使用空格 + "disallowTrailingWhitespace": true, + + // 每行「MUST NOT」超过 120 个字符 + "maximumLineLength": 120, + + // 一下操作符「MUST NOT」放在一行的最前面,需要放在上一行的后面 + "requireOperatorBeforeLineBreak": [ + "?", + "+", + "-", + "/", + "*", + "=", + "==", + "===", + "!=", + "!==", + ">", + ">=", + "<", + "<=", + ",", + ";", + "&&", + "&", + "||", + "|" + ], + + // 字符串统一「MUST」使用单引号 + "validateQuoteMarks": "'", + + // 「MUST NOT」使用多行字符串 + "disallowMultipleLineStrings": true +} \ No newline at end of file diff --git a/app/static/minder/.jshintrc b/app/static/minder/.jshintrc new file mode 100644 index 0000000..15c62b8 --- /dev/null +++ b/app/static/minder/.jshintrc @@ -0,0 +1,16 @@ +{ + "undef" : true, + "unused" : false, + "strict" : false, + "curly" : false, + "newcap" : true, + "trailing" : true, + "white": false, + "quotmark": false, + "browser": true, + "boss": true, + "indent": 4, + "predef" : [ + "define" + ] +} \ No newline at end of file diff --git a/app/static/minder/Gruntfile.js b/app/static/minder/Gruntfile.js new file mode 100644 index 0000000..3b6a271 --- /dev/null +++ b/app/static/minder/Gruntfile.js @@ -0,0 +1,202 @@ +/* global require, module */ + +var path = require('path'); + +module.exports = function(grunt) { + 'use strict'; + + // Load grunt tasks automatically + require('load-grunt-tasks')(grunt); + grunt.loadNpmTasks('grunt-browser-sync'); + grunt.loadNpmTasks('grunt-contrib-watch'); + + var pkg = grunt.file.readJSON('package.json'); + + var appConfig = { + app: require('./bower.json').appPath || 'app', + dist: 'dist' + }; + + var banner = '/*!\n' + + ' * ====================================================\n' + + ' * <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + + '<%= grunt.template.today("yyyy-mm-dd") %>\n' + + '<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' + + ' * GitHub: <%= pkg.repository.url %> \n' + + ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + + ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n' + + ' * ====================================================\n' + + ' */\n\n'; + + var expose = '\nuse(\'expose-editor\');\n'; + + // Project configuration. + grunt.initConfig({ + + // Metadata. + pkg: pkg, + + yeoman: appConfig, + + clean: { + last: [ + '.tmp', + 'dist/*.js', + 'dist/*.css', + 'dist/*.css.map' + ], + clstmp: ['.tmp'] + }, + + // resolve dependence + dependence: { + options: { + base: 'src', + entrance: 'expose-editor' + }, + merge: { + files: [{ + src: [ + 'src/**/*.js' + ], + dest: '.tmp/scripts/kityminder.editor.logic.js' + }] + } + }, + + // browser sync for dev + browserSync: { + bsFiles: { + dist: 'dist/css/*.css', + src: 'src/**' + }, + options: { + server: { + baseDir: './', + index: 'index.html', + watchTask: true + } + } + }, + + // concat + concat: { + closure: { + options: { + banner: banner + '(function () {\n', + footer: expose + '})();' + }, + files: { + 'dist/kityminder.editor.js': [ + '.tmp/scripts/kityminder.editor.logic.js', + '.tmp/scripts/kityminder.app.annotated.js', + '.tmp/scripts/templates.annotated.js', + '.tmp/scripts/service/*.js', + '.tmp/scripts/filter/*.js', + '.tmp/scripts/dialog/**/*.js', + '.tmp/scripts/directive/**/*.js' + ] + } + } + }, + + uglify: { + options: { + banner: banner + }, + minimize: { + files: [{ + src: 'dist/kityminder.editor.js', + dest: 'dist/kityminder.editor.min.js' + }] + } + }, + + less: { + compile: { + options: { + sourceMap: true, + sourceMapURL: 'kityminder.editor.css.map', + sourceMapFilename: 'dist/kityminder.editor.css.map' + }, + files: [{ + dest: 'dist/kityminder.editor.css', + src: 'less/editor.less' + }] + } + }, + + cssmin: { + dist: { + files: { + 'dist/kityminder.editor.min.css': 'dist/kityminder.editor.css' + } + } + }, + + ngtemplates: { + kityminderEditor: { + src: ['ui/directive/**/*.html', 'ui/dialog/**/*.html'], + dest: 'ui/templates.js', + options: { + htmlmin: { + collapseBooleanAttributes: true, + collapseWhitespace: true, + removeComments: true + } + } + } + }, + + // Automatically inject Bower components into the app + wiredep: { + dev: { + src: ['index.html'], + devDependencies: true + }, + dist: { + src: ['dist/index.html'] + } + }, + + // Copies remaining files to places other tasks can use + copy: { + dist: { + files: [{ + expand: true, + cwd: 'ui', + src: 'images/*', + dest: 'dist' + + }] + } + }, + + + // ng-annotate tries to make the code safe for minification automatically + // by using the Angular long form for dependency injection. + ngAnnotate: { + dist: { + files: [{ + expand: true, + cwd: 'ui/', + src: '**/*.js', + ext: '.annotated.js', + extDot: 'last', + dest: '.tmp/scripts/' + }] + } + } + + + }); + + // Build task(s). + grunt.registerTask('build', ['clean:last', + //'wiredep:dist', + 'ngtemplates', 'dependence', 'ngAnnotate', 'concat', 'uglify', 'less', 'cssmin', 'copy', 'clean:clstmp']); + + grunt.registerTask('dev', ['clean:last', + //'wiredep:dev', + 'ngtemplates', 'dependence', 'ngAnnotate', 'concat', 'uglify', 'less', 'cssmin', 'copy', 'clean:clstmp', 'browserSync', 'watch']); +}; \ No newline at end of file diff --git a/app/static/minder/LICENSE b/app/static/minder/LICENSE new file mode 100644 index 0000000..d6a9326 --- /dev/null +++ b/app/static/minder/LICENSE @@ -0,0 +1,340 @@ +GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + {signature of Ty Coon}, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + diff --git a/app/static/minder/README.md b/app/static/minder/README.md new file mode 100644 index 0000000..f145579 --- /dev/null +++ b/app/static/minder/README.md @@ -0,0 +1,87 @@ +KityMinder Editor +========== + +## 简介 + +KityMinder Editor 是一款强大、简洁、体验优秀的脑图编辑工具,适合用于编辑树/图/网等结构的数据。 + +编辑器由百度 [FEX](https://github.com/fex-team) 基于 [kityminder-core](https://github.com/fex-team/kityminder-core) 搭建,并且在[百度脑图](http://naotu.baidu.com)中使用。 + +他们的区别与联系如下: + +![KityMinder 联系](relations.png "KityMinder 联系") + +- [kityminder-core](https://github.com/fex-team/kityminder-core) 是 kityminder 的核心部分,基于百度 [FEX](https://github.com/fex-team) 开发的矢量图形库 [kity](https://github.com/fex-team/kity)。包含了脑图数据的可视化展现,简单编辑功能等所有底层支持。 +- [kityminder-editor](https://github.com/fex-team/kityminder-editor) 基于 kityminder-core 搭建,依赖于 AngularJS,包含 UI 和热盒 [hotbox](https://github.com/fex-team/hotbox) 等方便用户输入的功能,简单来说,就是一款编辑器。 +- [百度脑图](http://naotu.baidu.com) 基于 kityminder-editor,加入了第三方格式导入导出 (FreeMind, XMind, MindManager) 、文件储存、用户认证、文件分享、历史版本等业务逻辑。 + +## 功能 + +- 基本操作:文本编辑,节点折叠、插入、删除、排序、归纳、复制、剪切、粘贴等 +- 样式控制:字体、加粗、斜体、颜色、样式拷贝、样式粘贴等 +- 图标:优先级、进度等 +- 历史:撤销/重做 +- 标签:多标签贴入 +- 备注:支持 Markdown 格式备注 +- 图片:支持本地/网络/搜索图片插入 +- 超链接:支持 HTTP/HTTPS/MAIL/FTP 链接插入 +- 布局:支持多种布局切换 +- 主题:支持多种主题切换 +- 数据导入导出:支持多种格式的导入,多种格式(包括图片)的导出 +- 缩略图:支持缩略图查看/导航 + +## 开发使用 +根目录下的 `index.html` 为开发环境,`dist` 目录下的 `index.html` 使用打包好的代码,适用于线上环境。 + +1. 安装 [nodejs](http://nodejs.org) 和 [npm](https://docs.npmjs.com/getting-started/installing-node) +2. 初始化:切到 kityminder-editor 根目录下运行 `npm run init` +3. 在 kityminder-editor 根目录下运行 `grunt dev` 即可启动项目 +4. 你可以基于根目录的 `index.html` 开发,或者查看 `dist` 目录下用于生产环境的 `index.html`,Enjoy it! + +另外,kityminder-editor 还提供了 bower 包,方便开发者直接使用。你可以在需要用到 kityminder-editor 的工程目录下 +运行 `bower install kityminder-editor`,接着手动引入 kityminder-editor 所依赖的 css 和 js 文件,具体文件见 +`dist` 目录下的 `index.html`,推荐使用 npm 包 [wireDep](https://www.npmjs.com/package/wiredep) 自动进行, +可参考根目录下 `Gruntfile.js`。 + +## 构建 +运行 `grunt build`,完成后 `dist` 目录里就是可用运行的 kityminder-editor, 双击 `index.html` 即可打开运行示例 + +## 初始化配置 +用户可以根据需要,配置 `kityminder-editor`, 具体使用方法如下: +``` +angular.module('kityminderDemo', ['kityminderEditor']) + .config(function (configProvider) { + configProvider.set('imageUpload', 'path/to/image/upload/handler'); + }); + +``` + +## 数据导入导出 +由于 kityminder-editor 是基于 kityminder-core 搭建的,而 kityminder-core 内置了五种常见 +格式的导入或导出,在创建编辑器实例之后,可以使用四个接口进行数据的导入导出。 + +* `editor.minder.exportJson()` - 导出脑图数据为 JSON 对象 +* `editor.minder.importJson(json)` - 导入 JSON 对象为当前脑图数据 +* `editor.minder.exportData(protocol, option)` - 导出脑图数据为指定的数据格式,返回一个 Promise,其值为导出的结果 +* `editor.minder.importData(protocol, data, option)` - 导入指定格式的数据为脑图数据,返回一个 Promise,其值为转换之后的脑图 Json 数据 + +目前支持的数据格式包括: + +* `json` - JSON 字符串,支持导入和导出 +* `text` - 纯文本格式,支持导入和导出 +* `markdown` - Markdown 格式,支持导入和导出 +* `svg` - SVG 矢量格式,仅支持导出 +* `png` - PNG 位图格式,仅支持导出 + +更多格式的支持,可以加载 [kityminder-protocol](https://github.com/fex-team/kityminder-protocol) 来扩展第三方格式支持。 + +数据格式的具体信息,可参考 [kityminder-core-wiki 的中的说明](https://github.com/fex-team/kityminder-core/wiki)。 + +## 联系我们 +问题和建议反馈: + +[Github issues](https://github.com/fex-team/kityminder-editor/issues) + +邮件组:kity@baidu.com + +QQ 讨论群:475962105 \ No newline at end of file diff --git a/app/static/minder/bower.json b/app/static/minder/bower.json new file mode 100644 index 0000000..226aaf4 --- /dev/null +++ b/app/static/minder/bower.json @@ -0,0 +1,67 @@ +{ + "name": "kityminder-editor", + "version": "1.0.61", + "authors": [ + "fex" + ], + "description": "Kity Minder Editor", + "main": [ + "dist/kityminder.editor.js", + "dist/kityminder.editor.css" + ], + "keywords": [ + "kityminder", + "fex", + "ui", + "javascript", + "html5", + "svg" + ], + "license": "BSD", + "homepage": "https://github.com/fex-team/kityminder-editor", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "less", + "ui", + "src", + "Gruntfile.js", + "package.json" + ], + "devDependencies": { + "seajs": "~2.3.0" + }, + "dependencies": { + "bootstrap": "~3.3.4", + "angular": "~1.3.15", + "angular-bootstrap": "~0.12.1", + "angular-ui-codemirror": "~0.2.3", + "codemirror": "~4.8.0", + "marked": "git://github.com/chjj/marked.git#master", + "hotbox": "~1.0.2", + "color-picker": "~1.0.2", + "kity": "^2.0.5", + "json-diff": "*" + }, + "overrides": { + "codemirror": { + "main": [ + "lib/codemirror.js", + "lib/codemirror.css", + "mode/xml/xml.js", + "mode/javascript/javascript.js", + "mode/css/css.js", + "mode/htmlmixed/htmlmixed.js", + "mode/markdown/markdown.js", + "addon/mode/overlay.js", + "mode/gfm/gfm.js" + ] + } + }, + "resolutions": { + "angular": "~1.3.8" + } +} diff --git a/app/static/minder/favicon.ico b/app/static/minder/favicon.ico new file mode 100644 index 0000000..24e0248 Binary files /dev/null and b/app/static/minder/favicon.ico differ diff --git a/app/static/minder/index.html b/app/static/minder/index.html new file mode 100644 index 0000000..e375031 --- /dev/null +++ b/app/static/minder/index.html @@ -0,0 +1,127 @@ + + + + + KityMinder Editor - Powered By FEX + + + + + + + + + + + + + + + + +
+ + 脑图编辑 + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/static/minder/less/_navigator.less b/app/static/minder/less/_navigator.less new file mode 100644 index 0000000..53f65dc --- /dev/null +++ b/app/static/minder/less/_navigator.less @@ -0,0 +1,127 @@ +.nav-bar { + position: absolute; + width: 35px; + height: 240px; + padding: 5px 0; + left: 10px; + bottom: 10px; + background: #fc8383; + color: #fff; + border-radius: 4px; + z-index: 10; + box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2); + transition: -webkit-transform .7s 0.1s ease; + transition: transform .7s 0.1s ease; + + .nav-btn { + width: 35px; + height: 24px; + line-height: 24px; + text-align: center; + + .icon { + background: url(images/icons.png); + width: 20px; + height: 20px; + margin: 2px auto; + display: block; + } + + &.active { + background-color: #5A6378; + } + } + + .zoom-in .icon { + background-position: 0 -730px; + } + + .zoom-out .icon { + background-position: 0 -750px; + } + + .hand .icon { + background-position: 0 -770px; + width: 25px; + height: 25px; + margin: 0 auto; + } + + .camera .icon { + background-position: 0 -870px; + width: 25px; + height: 25px; + margin: 0 auto; + } + + .nav-trigger .icon { + background-position: 0 -845px; + width: 25px; + height: 25px; + margin: 0 auto; + } + + .zoom-pan { + width: 2px; + height: 70px; + box-shadow: 0 1px #E50000; + position: relative; + background: white; + margin: 3px auto; + overflow: visible; + + .origin { + position: absolute; + width: 20px; + height: 8px; + left: -9px; + margin-top: -4px; + background: transparent; + + &:after { + content: ' '; + display: block; + width: 6px; + height: 2px; + background: white; + left: 7px; + top: 3px; + position: absolute; + } + } + + .indicator { + position: absolute; + width: 8px; + height: 8px; + left: -3px; + background: white; + border-radius: 100%; + margin-top: -4px; + } + + } +} + +.nav-previewer { + background: #fff; + width: 140px; + height: 120px; + position: absolute; + left: 45px; + bottom: 30px; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); + border-radius: 0 2px 2px 0; + padding: 1px; + z-index: 9; + cursor: crosshair; + transition: -webkit-transform .7s 0.1s ease; + transition: transform .7s 0.1s ease; + + &.grab { + cursor: move; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + cursor: grabbing; + } +} \ No newline at end of file diff --git a/app/static/minder/less/_tool_group.less b/app/static/minder/less/_tool_group.less new file mode 100644 index 0000000..be0ba7d --- /dev/null +++ b/app/static/minder/less/_tool_group.less @@ -0,0 +1,24 @@ +.tool-group { + padding: 0; + + &[disabled] { + opacity: 0.5; + } + + .tool-group-item { + display: inline-block; + border-radius: 4px; + + .tool-group-icon { + width: 20px; + height: 20px; + padding: 2px; + margin: 1px; + } + + &:hover {background-color: @button-hover;} + &:active {background-color: @button-active;} + + &.active {background-color: @button-active;} + } +} \ No newline at end of file diff --git a/app/static/minder/less/_vars.less b/app/static/minder/less/_vars.less new file mode 100644 index 0000000..369b3ac --- /dev/null +++ b/app/static/minder/less/_vars.less @@ -0,0 +1,7 @@ +@button-hover: hsl(222, 55%, 96%); +@button-active: hsl(222, 55%, 85%); +@button-pressed: hsl(222, 55%, 90%); + +@tool-hover: #eff3fa; +@tool-active: #c4d0ee; +@tool-selected: #87a9da; \ No newline at end of file diff --git a/app/static/minder/less/editor.less b/app/static/minder/less/editor.less new file mode 100644 index 0000000..7e6f322 --- /dev/null +++ b/app/static/minder/less/editor.less @@ -0,0 +1,135 @@ +.km-editor { + overflow: hidden; + z-index: 2; +} + +.km-editor > .mask { + display: block; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: transparent; +} + +.km-editor > .receiver { + position: absolute; + background: white; + outline: none; + box-shadow: 0 0 20px fadeout(black, 50%); + left: 0; + top: 0; + padding: 3px 5px; + margin-left: -3px; + margin-top: -5px; + max-width: 300px; + width: auto; + overflow: hidden; + font-size: 14px; + line-height: 1.4em; + min-height: 1.4em; + box-sizing: border-box; + overflow: hidden; + word-break: break-all; + word-wrap: break-word; + border: none; + -webkit-user-select: text; + pointer-events: none; + opacity: 0; + z-index: -1000; + &.debug { + opacity: 1; + outline: 1px solid green; + background: none; + z-index: 0; + } + + &.input { + pointer-events: all; + opacity: 1; + z-index: 999; + background: white; + outline: none; + } +} + +div.minder-editor-container { + position: absolute; + top: 40px; + bottom: 0; + left: 0; + right: 0; + font-family: Arial, "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif; +} + + +.minder-editor { + position: absolute; + top: 92px; + left: 0; + right: 0; + bottom: 0; +} + +.minder-viewer { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + + +.control-panel { + position: absolute; + top: 0; + right: 0; + width: 250px; + bottom: 0; + border-left: 1px solid #CCC; +} +.minder-divider { + position: absolute; + top: 0; + right: 250px; + bottom: 0; + width: 2px; + background-color: rgb(251, 251, 251); + cursor: ew-resize; +} + +// @override bootstrap +.panel-body { + padding: 10px; +} + +@import (less) "_vars.less"; +@import (less) "imageDialog.less"; +@import (less) "topTab/topTab.less"; +@import (less) "topTab/idea/undoRedo.less"; +@import (less) "topTab/idea/appendNode.less"; +@import (less) "topTab/idea/arrange.less"; +@import (less) "topTab/idea/operation.less"; +@import (less) "topTab/idea/hyperlink.less"; +@import (less) "topTab/idea/image.less"; +@import (less) "topTab/idea/note.less"; +@import (less) "topTab/idea/noteEditor.less"; +@import (less) "topTab/idea/priority.less"; +@import (less) "topTab/idea/progress.less"; +@import (less) "topTab/idea/resource.less"; +@import (less) "topTab/appearance/templatePanel.less"; +@import (less) "topTab/appearance/themePanel.less"; +@import (less) "topTab/appearance/layout.less"; +@import (less) "topTab/appearance/styleOperator.less"; +@import (less) "topTab/appearance/fontOperator.less"; +@import (less) "topTab/appearance/colorPanel.less"; +@import (less) "topTab/view/expand.less"; +@import (less) "topTab/view/select.less"; +@import (less) "topTab/view/search.less"; +@import (less) "topTab/searchBox.less"; +@import (less) "_tool_group.less"; +@import (less) "_navigator.less"; + + + diff --git a/app/static/minder/less/imageDialog.less b/app/static/minder/less/imageDialog.less new file mode 100644 index 0000000..9021ed6 --- /dev/null +++ b/app/static/minder/less/imageDialog.less @@ -0,0 +1,8 @@ +.upload-image { + width: 0.1px; + height: 0.1px; + opacity: 0; + overflow: hidden; + position: absolute; + z-index: -1; +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/appearance/colorPanel.less b/app/static/minder/less/topTab/appearance/colorPanel.less new file mode 100644 index 0000000..be2eff9 --- /dev/null +++ b/app/static/minder/less/topTab/appearance/colorPanel.less @@ -0,0 +1,77 @@ +.bg-color-wrap { + display: inline-block; + width: 30px; + height: 22px; + margin: 3px 3px 0 0; + border: 1px #efefef solid; + vertical-align: middle; + font-size: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + &[disabled] { + opacity: 0.5; + } + + .quick-bg-color { + display: inline-block; + width: 20px; + height: 16px; + font-size: 14px; + line-height: 16px; + vertical-align: top; + text-align: center; + cursor: default; + color: #000; + background: url(images/icons.png) no-repeat center -1260px; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &[disabled] { + opacity: 0.5; + } + } + + .bg-color-preview { + display: inline-block; + width: 12px; + height: 2px; + margin: 0 4px 0; + background-color: #fff; + + &[disabled] { + opacity: 0.5; + } + } +} + +.bg-color { + display: inline-block; + width: 8px; + height: 16px; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &[disabled] { + opacity: 0.5; + } + + .caret { + margin-left: -2px; + margin-top: 7px; + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/appearance/fontOperator.less b/app/static/minder/less/topTab/appearance/fontOperator.less new file mode 100644 index 0000000..49a9652 --- /dev/null +++ b/app/static/minder/less/topTab/appearance/fontOperator.less @@ -0,0 +1,160 @@ +.font-operator { + width: 170px; + display: inline-block; + vertical-align: middle; + font-size: 12px; + padding: 0 5px; + + .font-size-list { + display: inline-block; + border: 1px solid #eee; + padding: 2px 4px; + } + + .font-family-list { + display: inline-block; + border: 1px solid #eee; + padding: 2px 4px; + } + +} + +.current-font-item a { + text-decoration: none; + display: inline-block; +} + +.current-font-family { + width: 75px; + height: 18px; + overflow: hidden; + vertical-align: bottom; +} +.current-font-size { + width: 32px; + height: 18px; + overflow: hidden; + vertical-align: bottom; +} + +.current-font-item[disabled] { + opacity: 0.5; +} + +.font-item { + line-height: 1em; + text-align: left; +} + +.font-item-selected { + background-color: @tool-selected; +} + +.font-bold, .font-italics { + display: inline-block; + background: url(images/icons.png) no-repeat; + cursor: pointer; + margin: 0 3px; + + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &[disabled] { + opacity: 0.5; + } +} + +.font-bold { + background-position: 0 -240px; +} + +.font-italics { + background-position: 0 -260px; +} + +.font-bold-selected, .font-italics-selected { + background-color: @tool-selected; +} + +.font-color-wrap { + display: inline-block; + width: 30px; + height: 22px; + margin: 3px 3px 0 0; + border: 1px #efefef solid; + vertical-align: middle; + font-size: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + &[disabled] { + opacity: 0.5; + } + + .quick-font-color { + display: inline-block; + width: 20px; + height: 16px; + font-size: 14px; + line-height: 16px; + vertical-align: top; + text-align: center; + cursor: default; + color: #000; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &[disabled] { + opacity: 0.5; + } + } + + .font-color-preview { + display: inline-block; + width: 12px; + height: 2px; + margin: 0 4px 0; + background-color: #000; + + &[disabled] { + opacity: 0.5; + } + } +} + +.font-color { + display: inline-block; + width: 8px; + height: 16px; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &[disabled] { + opacity: 0.5; + } + + .caret { + margin-left: -2px; + margin-top: 7px; + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/appearance/layout.less b/app/static/minder/less/topTab/appearance/layout.less new file mode 100644 index 0000000..ba9bc31 --- /dev/null +++ b/app/static/minder/less/topTab/appearance/layout.less @@ -0,0 +1,65 @@ +.readjust-layout { + display: inline-block; + vertical-align: middle; + padding: 0 10px 0 5px; + border-right: 1px dashed #eee; +} + +.btn-icon { + width: 25px; + height: 25px; + margin-left: 12px; + display: block; +} + +.btn-label { + font-size: 12px; +} + +.btn-wrap { + width: 50px; + height: 42px; + cursor: pointer; + display: inline-block; + text-decoration: none; + + &[disabled] span { + opacity: 0.5; + } + + &[disabled] { + cursor: default; + } + + &[disabled]:hover { + background-color: transparent; + } + + &[disabled]:active { + background-color: transparent; + } + + &:link { + text-decoration: none; + } + + &:visited { + text-decoration: none; + } + + &:hover { + background-color: @tool-hover; + text-decoration: none; + } + + &:active { + background-color: @tool-active; + } + +} + +.reset-layout-icon { + background: url(images/icons.png) no-repeat; + background-position: 0 -150px; +} + diff --git a/app/static/minder/less/topTab/appearance/styleOperator.less b/app/static/minder/less/topTab/appearance/styleOperator.less new file mode 100644 index 0000000..15dbada --- /dev/null +++ b/app/static/minder/less/topTab/appearance/styleOperator.less @@ -0,0 +1,83 @@ +.style-operator { + display: inline-block; + vertical-align: middle; + padding: 0 5px; + border-right: 1px dashed #eee; + + .clear-style { + vertical-align: middle; + } + +} + +.clear-style-icon { + background: url(images/icons.png) no-repeat; + background-position: 0 -175px;; +} + +.s-btn-group-vertical { + display: inline-block; + vertical-align: middle; +} + +.s-btn-icon { + width: 20px; + height: 20px; + margin-right: 3px; + display: inline-block; + vertical-align: middle; +} + +.s-btn-label { + font-size: 12px; + vertical-align: middle; + display: inline-block; +} + +.s-btn-wrap { +// margin-bottom: 2px; + padding: 0 5px 0 3px; + display: inline-block; + text-decoration: none; + font-size: 0; + + &[disabled] span { + opacity: 0.5; + } + + &[disabled] { + cursor: default; + } + + &[disabled]:hover { + background-color: transparent; + } + + &[disabled]:active { + background-color: transparent; + } + + &:hover { + background-color: @tool-hover; + text-decoration: none; + } + + &:active { + background-color: @tool-active; + } + +} + +.copy-style-icon { + background: url(images/icons.png) no-repeat; + background-position: 0 -200px; +} + +.paste-style-wrap { + display: block; +} + +.paste-style-icon { + background: url(images/icons.png) no-repeat; + background-position: 0 -220px; +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/appearance/templatePanel.less b/app/static/minder/less/topTab/appearance/templatePanel.less new file mode 100644 index 0000000..f1d44f3 --- /dev/null +++ b/app/static/minder/less/topTab/appearance/templatePanel.less @@ -0,0 +1,71 @@ +.temp-panel { + margin: 5px 5px 5px 10px; + border-right: 1px dashed #eee; + display: inline-block; + vertical-align: middle; +} + +.temp-list { + min-width: 124px; +} + +.temp-item-wrap { + width: 50px; + height: 40px; + padding: 0 2px; + margin: 5px; + display: inline-block; +} + +.temp-item { + display: inline-block; + width: 50px; + height: 40px; + background-image: url(images/template.png); + background-repeat: no-repeat; + + &.default { + background-position: 0 0; + } + + &.structure { + background-position: -50px 0; + } + + &.filetree { + background-position: -100px 0; + } + + &.right { + background-position: -150px 0; + } + + &.fish-bone { + background-position: -200px 0; + } + + &.tianpan { + background-position: -250px 0; + } +} + +.current-temp-item { + width: 74px; + padding: 0 0 0 5px; + border: 1px solid #fff; + + &:hover { + background-color: @tool-hover; + } + + &[disabled] { + opacity: 0.5; + } + + .caret { + margin-left: 5px; + } +} +.temp-item-selected { + background-color: @tool-selected; +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/appearance/themePanel.less b/app/static/minder/less/topTab/appearance/themePanel.less new file mode 100644 index 0000000..19cf9de --- /dev/null +++ b/app/static/minder/less/topTab/appearance/themePanel.less @@ -0,0 +1,53 @@ +.theme-panel { + height: 42px; + margin: 5px; + padding: 0 5px 0 0; + border-right: 1px dashed #eee; + display: inline-block; + vertical-align: middle; +} + +.theme-list { + min-width: 162px; +} + +div a.theme-item { + display: inline-block; + width: 70px; + height: 30px; + text-align: center; + line-height: 30px; + padding: 0 5px; + font-size: 12px; + cursor: pointer; + text-decoration: none; + color: #000; +} + +.theme-item-selected { + width: 100px; + padding: 6px 7px; + border: 1px solid #fff; + + &:hover { + background-color: @tool-hover; + } + + .caret { + margin-left: 5px; + } + + &[disabled] { + opacity: 0.5; + } +} + +.theme-item-wrap { + display: inline-block; + width: 80px; + height: 40px; + padding: 5px; +} +.theme-item-wrap:hover { + background-color: #eff3fa; +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/idea/appendNode.less b/app/static/minder/less/topTab/idea/appendNode.less new file mode 100644 index 0000000..b648bd5 --- /dev/null +++ b/app/static/minder/less/topTab/idea/appendNode.less @@ -0,0 +1,21 @@ +.append-group { + width: 212px; +} + +.append-child-node { + .km-btn-icon { + background-position: 0 0; + } +} + +.append-sibling-node { + .km-btn-icon { + background-position: 0 -20px; + } +} + +.append-parent-node { + .km-btn-icon { + background-position: 0 -40px; + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/idea/arrange.less b/app/static/minder/less/topTab/idea/arrange.less new file mode 100644 index 0000000..c8582ed --- /dev/null +++ b/app/static/minder/less/topTab/idea/arrange.less @@ -0,0 +1,15 @@ +.arrange-group { + width: 64px; +} + +.arrange-up { + .km-btn-icon { + background-position: 0 -280px; + } +} + +.arrange-down { + .km-btn-icon { + background-position: 0 -300px; + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/idea/hyperlink.less b/app/static/minder/less/topTab/idea/hyperlink.less new file mode 100644 index 0000000..0c8d5fd --- /dev/null +++ b/app/static/minder/less/topTab/idea/hyperlink.less @@ -0,0 +1,43 @@ +.btn-group-vertical { + vertical-align: middle; + margin: 5px; + + .hyperlink, .hyperlink-caption { + width: 40px; + margin: 0; + padding: 0; + border: none!important; + border-radius: 0!important; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &.active { + box-shadow: none; + background-color: @tool-hover; + } + } + + .hyperlink { + height: 25px; + background: url(images/icons.png) no-repeat center -100px; + } + + .hyperlink-caption { + height: 20px; + + .caption { + font-size: 12px; + } + } +} + +//override bootstrap +.open > .dropdown-toggle.btn-default { + background-color: @tool-hover; +} diff --git a/app/static/minder/less/topTab/idea/image.less b/app/static/minder/less/topTab/idea/image.less new file mode 100644 index 0000000..0b77572 --- /dev/null +++ b/app/static/minder/less/topTab/idea/image.less @@ -0,0 +1,129 @@ +.btn-group-vertical { + + .image-btn, .image-btn-caption { + width: 40px; + margin: 0; + padding: 0; + border: none!important; + border-radius: 0!important; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &.active { + box-shadow: none; + background-color: @tool-hover; + } + } + + .image-btn { + height: 25px; + background: url(images/icons.png) no-repeat center -125px; + } + + .image-btn-caption { + height: 20px; + + .caption { + font-size: 12px; + } + } +} + +.image-preview { + display: block; + max-width: 50%; +} + +.modal-body { + .tab-pane { + font-size: inherit; + padding-top: 15px; + } +} + +.search-result { + margin-top: 15px; + height: 370px; + overflow: hidden; + + ul { + margin: 0; + padding: 0; + list-style: none; + clear: both; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + + li { + list-style: none; + float: left; + display: block; + width: 130px; + height: 130px; + line-height: 130px; + margin: 6px; + padding: 0; + font-size: 12px; + position: relative; + vertical-align: top; + text-align: center; + overflow: hidden; + cursor: pointer; + border: 2px solid #fcfcfc; + + &.selected { + border: 2px solid #fc8383; + } + + + img { + max-width: 126px; + max-height: 130px; + vertical-align: middle; + } + + span { + display: block; + position: absolute; + bottom: 0; + height: 20px; + background: rgba(0, 0, 0, 0.5); + left: 0; + right: 0; + color: white; + line-height: 20px; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; + opacity: 0; + -webkit-transform: translate(0, 20px); + -ms-transform: translate(0, 20px); + transform: translate(0, 20px); + -webkit-transition: all .2s ease; + transition: all .2s ease; + } + } + + li:hover span { + opacity: 1; + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); + } + } +} + +// 覆盖 bootstrap 样式 +@media (min-width: 768px){ + .form-inline .form-control { + width: 422px; + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/idea/note.less b/app/static/minder/less/topTab/idea/note.less new file mode 100644 index 0000000..2f4c85e --- /dev/null +++ b/app/static/minder/less/topTab/idea/note.less @@ -0,0 +1,48 @@ +.btn-group-vertical { + vertical-align: top; + margin: 5px; + + &.note-btn-group { + border-right: 1px dashed #eee; + padding-right: 5px; + } + + .note-btn, .note-btn-caption { + width: 40px; + margin: 0; + padding: 0; + border: none!important; + border-radius: 0!important; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &.active { + box-shadow: none; + background-color: @tool-hover; + } + } + + .note-btn { + height: 25px; + background: url(images/icons.png) no-repeat center -1150px; + } + + .note-btn-caption { + height: 20px; + + .caption { + font-size: 12px; + } + } +} + +//override bootstrap +.open > .dropdown-toggle.btn-default { + background-color: @tool-hover; +} diff --git a/app/static/minder/less/topTab/idea/noteEditor.less b/app/static/minder/less/topTab/idea/noteEditor.less new file mode 100644 index 0000000..ff76f09 --- /dev/null +++ b/app/static/minder/less/topTab/idea/noteEditor.less @@ -0,0 +1,168 @@ +.gfm-render { + + font-size: 12px; + -webkit-user-select: text; + color: #333; + line-height: 1.8em; + + blockquote, ul, table, p, pre, hr { + margin: 1em 0; + cursor: text; + &:first-child:last-child { + margin: 0; + } + } + + img { + max-width: 100%; + } + + a { + color: blue; + &:hover { + color: red; + } + } + + blockquote { + display: block; + border-left: 4px solid #E4AD91; + color: darken(#E4AD91, 10%); + padding-left: 10px; + font-style: italic; + margin-left: 2em; + } + + ul, ol { + padding-left: 3em; + } + + table { + width: 100%; + border-collapse: collapse; + th, td { + border: 1px solid #666; + padding: 2px 4px; + } + th { + background: rgba(45, 141, 234, 0.2); + } + tr:nth-child(even) td { + background: rgba(45, 141, 234, 0.03); + } + margin: 1em 0; + } + + em { + color: red; + } + + del { + color: #999; + } + + pre { + background: rgba(45, 141, 234, 0.1); + padding: 5px; + border-radius: 5px; + word-break: break-all; + word-wrap: break-word; + } + + code { + background: rgba(45, 141, 234, 0.1); + /* display: inline-block; */ + padding: 0 5px; + border-radius: 3px; + } + + pre code { + background: none; + } + + hr { + border: none; + border-top: 1px solid #CCC; + } + + .highlight { + background: yellow; + color: red; + } +} + +.km-note { + width: 300px; + border-left: 1px solid #babfcd; + padding: 5px 10px; + background: white; + position: absolute; + top: 92px; + right: 0; + bottom: 0; + left: auto; + z-index: 3; + + &.panel { + margin: 0; + padding: 0; + + .panel-heading { + + h3 { + display: inline-block; + } + + .close-note-editor { + width: 15px; + height: 15px; + display: inline-block; + float: right; + + &:hover { + cursor: pointer; + } + } + } + + .panel-body { + padding: 0; + } + } + + .CodeMirror { + position: absolute; + top: 41px; + bottom: 0; + height: auto; + cursor: text; + font-size: 14px; + line-height: 1.3em; + font-family: consolas; + } +} +.km-note-tips { + color: #ccc; + padding: 3px 8px; +} +#previewer-content { + position: absolute; + background: #FFD; + padding: 5px 15px; + border-radius: 5px; + max-width: 400px; + max-height: 200px; + overflow: auto; + z-index: 10; + box-shadow: 0 0 15px rgba(0, 0, 0, .5); + word-break: break-all; + .gfm-render; +} +#previewer-content.ng-hide { + display: block!important; + left: -99999px!important; + top: -99999px!important; +} +.panel-body { + padding: 10px; +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/idea/operation.less b/app/static/minder/less/topTab/idea/operation.less new file mode 100644 index 0000000..69a8804 --- /dev/null +++ b/app/static/minder/less/topTab/idea/operation.less @@ -0,0 +1,15 @@ +.operation-group { + width: 64px; +} + +.edit-node { + .km-btn-icon { + background-position: 0 -60px; + } +} + +.remove-node { + .km-btn-icon { + background-position: 0 -80px; + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/idea/priority.less b/app/static/minder/less/topTab/idea/priority.less new file mode 100644 index 0000000..4a7a2f8 --- /dev/null +++ b/app/static/minder/less/topTab/idea/priority.less @@ -0,0 +1,26 @@ +.priority-sprite(@count) when (@count >= 0) { + .priority-sprite(@count - 1); + &.priority-@{count} { + background-position: 0 (-20px * (@count - 1)); + } +} + +.tab-content .km-priority { + vertical-align: middle; + font-size: inherit; + display: inline-block; + width: 140px; + margin: 5px; + border-right: 1px dashed #eee; + + .km-priority-item { + margin: 0 1px; + padding: 1px; + + .km-priority-icon { + .priority-sprite(9); + background: url(images/iconpriority.png) repeat-y; + background-color: transparent; + } + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/idea/progress.less b/app/static/minder/less/topTab/idea/progress.less new file mode 100644 index 0000000..035b05e --- /dev/null +++ b/app/static/minder/less/topTab/idea/progress.less @@ -0,0 +1,26 @@ +.progress-sprite(@count) when (@count >= 0) { + .progress-sprite(@count - 1); + &.progress-@{count} { + background-position: 0 (-20px * (@count - 1)); + } +} + +.tab-content .km-progress { + vertical-align: middle; + font-size: inherit; + display: inline-block; + width: 140px; + margin: 5px; + border-right: 1px dashed #eee; + + .km-progress-item { + margin: 0 1px; + padding: 1px; + + .km-progress-icon { + .progress-sprite(9); + background: url(images/iconprogress.png) repeat-y; + background-color: transparent; + } + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/idea/resource.less b/app/static/minder/less/topTab/idea/resource.less new file mode 100644 index 0000000..76491be --- /dev/null +++ b/app/static/minder/less/topTab/idea/resource.less @@ -0,0 +1,83 @@ +.resource-editor { + vertical-align: middle; + display: inline-block; + margin: 5px; + + .input-group, .km-resource { + font-size: 12px; + } + + .input-group { + height: 20px; + width: 168px; + } + + .resource-dropdown { + position: relative; + width: 168px; + border: 1px solid #ccc; + margin-top: -1px; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + + .km-resource { + position: absolute; + width: 154px; + margin-bottom: 3px; + padding: 0; + list-style-type: none; + overflow: scroll; + max-height: 500px; + + &.open { + z-index: 3; + background-color: #fff; + } + + li { + display: inline-block; + padding: 1px 2px; + border-radius: 4px; + margin: 2px 3px; + + &[disabled] { + opacity: 0.5; + } + } + } + + .resource-caret { + display: block; + float: right; + vertical-align: middle; + width: 12px; + height: 24px; + padding: 8px 1px; + + &:hover {background-color: @button-hover;} + &:active {background-color: @button-active;} + } + } + + // 覆盖 bootstrap + input.form-control, .btn { + font-size: 12px; + } + + input.form-control { + padding: 2px 4px; + height: 24px; + border-bottom-left-radius: 0; + } + + .input-group-btn { + line-height: 24px; + + .btn { + padding: 2px 4px; + height: 24px; + border-bottom-right-radius: 0; + } + } +} + diff --git a/app/static/minder/less/topTab/idea/undoRedo.less b/app/static/minder/less/topTab/idea/undoRedo.less new file mode 100644 index 0000000..2ad7ab0 --- /dev/null +++ b/app/static/minder/less/topTab/idea/undoRedo.less @@ -0,0 +1,15 @@ +.do-group { + width: 38px; +} + +.undo { + .km-btn-icon { + background-position: 0 -1240px; + } +} + +.redo { + .km-btn-icon { + background-position: 0 -1220px; + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/searchBox.less b/app/static/minder/less/topTab/searchBox.less new file mode 100644 index 0000000..014257a --- /dev/null +++ b/app/static/minder/less/topTab/searchBox.less @@ -0,0 +1,59 @@ +.search-box { + float: right; + background-color: #fff; + border: 1px solid #dbdbdb; + position: relative; + top: 0; + z-index: 3; + width: 360px; + height: 40px; + padding: 3px 6px; + opacity: 1; + + .search-input-wrap, .prev-and-next-btn { + float: left; + } + + .close-search { + float: right; + height: 16px; + width: 16px; + padding: 1px; + border-radius: 100%; + margin-top: 6px; + margin-right: 10px; + + .glyphicon { + top: -1px + } + + &:hover { + background-color: #efefef; + } + + &:active { + background-color: #999; + } + } + + .search-input-wrap { + width: 240px; + } + + .prev-and-next-btn { + margin-left: 5px; + + .btn:focus { + outline: none; + } + } + + .search-input { + //border-right: none; + } + + .search-addon { + background-color: #fff; + } + +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/topTab.less b/app/static/minder/less/topTab/topTab.less new file mode 100644 index 0000000..0bd9a6c --- /dev/null +++ b/app/static/minder/less/topTab/topTab.less @@ -0,0 +1,89 @@ +.top-tab { + + .nav-tabs { + background-color: #e1e1e1; + border: 0; + height: 32px; + + li { + margin: 0; + + a { + margin: 0; + border: 0; + padding: 6px 15px; + border-radius: 0; + vertical-align: middle; + + + &:hover, &:focus { + background: inherit; + border: 0; + } + } + + + &.active a { + border: 0; + background-color: #fff; + + &:hover, &:focus { + border: 0; + } + } + } + } + + .tab-content { + height: 60px; + background-color: #fff; + border-bottom: 1px solid #dbdbdb; + } + + .tab-pane { + font-size: 0; + } +} + +.km-btn-group { + display: inline-block; + margin: 5px 0; + padding: 0 5px; + vertical-align: middle; + border-right: 1px dashed #eee; +} + +.km-btn-item { + display: inline-block; + margin: 0 3px; + font-size: 0; + cursor: default; + + &[disabled] { + opacity: 0.5; + + &:hover, &:active { + background-color: #fff; + } + } + + .km-btn-icon { + display: inline-block; + background: url(images/icons.png) no-repeat; + background-position: 0 20px; + width: 20px; + height: 20px; + padding: 2px; + margin: 1px; + vertical-align: middle; + } + + .km-btn-caption { + display: inline-block; + font-size: 12px; + vertical-align: middle; + } + + &:hover {background-color: @button-hover;} + &:active {background-color: @button-active;} +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/view/expand.less b/app/static/minder/less/topTab/view/expand.less new file mode 100644 index 0000000..0fd2551 --- /dev/null +++ b/app/static/minder/less/topTab/view/expand.less @@ -0,0 +1,39 @@ +.btn-group-vertical { + vertical-align: middle; + margin: 5px; + + .expand, .expand-caption { + width: 40px; + margin: 0; + padding: 0; + border: none!important; + border-radius: 0!important; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &.active { + box-shadow: none; + background-color: @tool-hover; + } + } + + .expand { + height: 25px; + background: url(images/icons.png) no-repeat 0 -995px; + background-position-x: 50%; + } + + .expand-caption { + height: 20px; + + .caption { + font-size: 12px; + } + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/view/search.less b/app/static/minder/less/topTab/view/search.less new file mode 100644 index 0000000..80c15eb --- /dev/null +++ b/app/static/minder/less/topTab/view/search.less @@ -0,0 +1,39 @@ +.btn-group-vertical { + vertical-align: middle; + margin: 5px; + + .search, .search-caption { + width: 40px; + margin: 0; + padding: 0; + border: none!important; + border-radius: 0!important; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &.active { + box-shadow: none; + background-color: @tool-hover; + } + } + + .search { + height: 25px; + background: url(images/icons.png) no-repeat 0 -345px; + background-position-x: 50%; + } + + .search-caption { + height: 20px; + + .caption { + font-size: 12px; + } + } +} \ No newline at end of file diff --git a/app/static/minder/less/topTab/view/select.less b/app/static/minder/less/topTab/view/select.less new file mode 100644 index 0000000..810abe2 --- /dev/null +++ b/app/static/minder/less/topTab/view/select.less @@ -0,0 +1,38 @@ +.btn-group-vertical { + vertical-align: middle; + margin: 5px; + + .select, .select-caption { + width: 40px; + margin: 0; + padding: 0; + border: none!important; + border-radius: 0!important; + + &:hover { + background-color: @tool-hover; + } + + &:active { + background-color: @tool-active; + } + + &.active { + box-shadow: none; + background-color: @tool-hover; + } + } + + .select { + height: 25px; + background: url(images/icons.png) no-repeat 7px -1175px; + } + + .select-caption { + height: 20px; + + .caption { + font-size: 12px; + } + } +} \ No newline at end of file diff --git a/app/static/minder/package-lock.json b/app/static/minder/package-lock.json new file mode 100644 index 0000000..abba877 --- /dev/null +++ b/app/static/minder/package-lock.json @@ -0,0 +1,4973 @@ +{ + "name": "kityminder-editor", + "version": "1.0.64", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "2.1.18", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-0.11.0.tgz", + "integrity": "sha1-bpXwJTrRYf8BJ9symD5eLlNS1Zo=", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "alter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/alter/-/alter-0.2.0.tgz", + "integrity": "sha1-x1iICGF1cgNKrmJICvJrHU0cs80=", + "dev": true, + "requires": { + "stable": "0.1.6" + } + }, + "ambi": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ambi/-/ambi-2.5.0.tgz", + "integrity": "sha1-fI43K+SIkRV+fOoBy2+RQ9H3QiA=", + "dev": true, + "requires": { + "editions": "1.3.4", + "typechecker": "4.5.0" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + }, + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "applause": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/applause/-/applause-0.3.4.tgz", + "integrity": "sha1-ewmzqpZagID6XYPaXDVoeKJm0/k=", + "dev": true, + "requires": { + "cson": "1.6.2", + "js-yaml": "3.11.0", + "lodash": "2.4.2" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "js-yaml": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "dev": true, + "requires": { + "argparse": "1.0.10", + "esprima": "4.0.0" + } + }, + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + } + } + }, + "argparse": { + "version": "0.1.16", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", + "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=", + "dev": true, + "requires": { + "underscore": "1.7.0", + "underscore.string": "2.4.0" + }, + "dependencies": { + "underscore.string": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", + "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=", + "dev": true + } + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true, + "optional": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "async": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", + "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "async-each-series": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", + "integrity": "sha1-dhfBkXQB/Yykooqtzj266Yr+tDI=", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "batch": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.5.3.tgz", + "integrity": "sha1-PzQU84AyF0O/wQQvmoP/HVgk1GQ=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", + "dev": true + }, + "body-parser": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", + "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", + "dev": true, + "requires": { + "bytes": "2.2.0", + "content-type": "1.0.4", + "debug": "2.2.0", + "depd": "1.1.2", + "http-errors": "1.3.1", + "iconv-lite": "0.4.13", + "on-finished": "2.3.0", + "qs": "5.2.0", + "raw-body": "2.1.7", + "type-is": "1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "http-errors": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "statuses": "1.3.1" + } + }, + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "qs": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", + "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=", + "dev": true + } + } + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "bower-config": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/bower-config/-/bower-config-0.5.3.tgz", + "integrity": "sha1-mPxbQah4cO+cu5KXY1z4H1UF/bE=", + "dev": true, + "requires": { + "graceful-fs": "2.0.3", + "mout": "0.9.1", + "optimist": "0.6.1", + "osenv": "0.0.3" + }, + "dependencies": { + "graceful-fs": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz", + "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "browser-sync": { + "version": "2.23.6", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.23.6.tgz", + "integrity": "sha512-loCO5NQKZXfBJrEvmLwF1TPSECCsPopNd29qduoysLmpw8op2lgolGMjz3oI/MjG4duzB9TfDs7k58djRSwPwg==", + "dev": true, + "requires": { + "browser-sync-ui": "1.0.1", + "bs-recipes": "1.3.4", + "chokidar": "1.7.0", + "connect": "3.5.0", + "connect-history-api-fallback": "1.5.0", + "dev-ip": "1.0.1", + "easy-extender": "2.3.2", + "eazy-logger": "3.0.2", + "emitter-steward": "1.0.0", + "etag": "1.8.1", + "fresh": "0.5.2", + "fs-extra": "3.0.1", + "http-proxy": "1.15.2", + "immutable": "3.8.2", + "localtunnel": "1.8.3", + "micromatch": "2.3.11", + "opn": "4.0.2", + "portscanner": "2.1.1", + "qs": "6.2.1", + "resp-modifier": "6.0.2", + "rx": "4.1.0", + "serve-index": "1.8.0", + "serve-static": "1.12.2", + "server-destroy": "1.0.1", + "socket.io": "2.0.4", + "ua-parser-js": "0.7.12", + "yargs": "6.4.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "qs": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz", + "integrity": "sha1-zgPF/wk1vB2daanxTL0Y5WjWdiU=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true + }, + "yargs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", + "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "window-size": "0.2.0", + "y18n": "3.2.1", + "yargs-parser": "4.2.1" + } + } + } + }, + "browser-sync-ui": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-1.0.1.tgz", + "integrity": "sha512-RIxmwVVcUFhRd1zxp7m2FfLnXHf59x4Gtj8HFwTA//3VgYI3AKkaQAuDL8KDJnE59XqCshxZa13JYuIWtZlKQg==", + "dev": true, + "requires": { + "async-each-series": "0.1.1", + "connect-history-api-fallback": "1.5.0", + "immutable": "3.8.2", + "server-destroy": "1.0.1", + "socket.io-client": "2.0.4", + "stream-throttle": "0.1.3" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "0.2.9" + } + }, + "bs-recipes": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", + "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "bytes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", + "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=", + "dev": true + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "camel-case": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-1.2.2.tgz", + "integrity": "sha1-Gsp8TRlTWaLOmVV5NDPG5VQlEfI=", + "dev": true, + "requires": { + "sentence-case": "1.1.3", + "upper-case": "1.1.3" + } + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "dev": true, + "requires": { + "ansi-styles": "1.1.0", + "escape-string-regexp": "1.0.5", + "has-ansi": "0.1.0", + "strip-ansi": "0.3.0", + "supports-color": "0.2.0" + } + }, + "change-case": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-2.1.6.tgz", + "integrity": "sha1-UUryBRMVimj+fwDf9MMy1sKY0vk=", + "dev": true, + "requires": { + "camel-case": "1.2.2", + "constant-case": "1.1.2", + "dot-case": "1.1.2", + "is-lower-case": "1.1.3", + "is-upper-case": "1.1.2", + "lower-case": "1.1.4", + "param-case": "1.1.2", + "pascal-case": "1.1.2", + "path-case": "1.1.2", + "sentence-case": "1.1.3", + "snake-case": "1.1.2", + "swap-case": "1.1.2", + "title-case": "1.1.2", + "upper-case": "1.1.3", + "upper-case-first": "1.1.2" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } + }, + "clean-css": { + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-2.2.23.tgz", + "integrity": "sha1-BZC1R4tRbEkD7cLYm9P9vdKGMow=", + "dev": true, + "requires": { + "commander": "2.2.0" + } + }, + "cli": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/cli/-/cli-0.6.6.tgz", + "integrity": "sha1-Aq1Eo4Cr8nraxebwzdewQ9dMU+M=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "3.2.11" + }, + "dependencies": { + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimatch": "0.3.0" + } + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + } + } + }, + "cli-color": { + "version": "0.1.7", + "resolved": "http://registry.npm.baidu-int.com/cli-color/-/cli-color-0.1.7.tgz", + "integrity": "sha1-rcMgD6RxzCEbDaf1ZrcemLnWc0c=", + "requires": { + "es5-ext": "0.8.2" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "coffee-script": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz", + "integrity": "sha1-FQ1rTLUiiUNp7+1qIQHCC8f0pPQ=", + "dev": true + }, + "colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", + "dev": true + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.2.0.tgz", + "integrity": "sha1-F1rUuTF/P/YV8gHB5XIk9Vo+kd8=", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-gslSSJx03QKa59cIKqeJO9HQ/WZMotvYJCuaUULrLpjj8oG40kV2Z+gz82pVxlTkOADi4PJxQPPfhl1ELYrrXw==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "typedarray": "0.0.6" + } + }, + "connect": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.5.0.tgz", + "integrity": "sha1-s1dSWgtMH1BZnNmD4dnv7qlncZg=", + "dev": true, + "requires": { + "debug": "2.2.0", + "finalhandler": "0.5.0", + "parseurl": "1.3.2", + "utils-merge": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", + "dev": true + }, + "constant-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-1.1.2.tgz", + "integrity": "sha1-jsLKW6ND4Aqjjb9OIA/VrJB+/WM=", + "dev": true, + "requires": { + "snake-case": "1.1.2", + "upper-case": "1.1.3" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "conventional-commit-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-2.2.0.tgz", + "integrity": "sha1-XblXOdbCEqy+e29lahG5QLqmiUY=", + "dev": true + }, + "convert-source-map": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.4.1.tgz", + "integrity": "sha1-+RmgCZ/jH4D8Wh0OswMWGzlAcMc=", + "dev": true + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "cson": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/cson/-/cson-1.6.2.tgz", + "integrity": "sha1-+uexPaHOsHfeKv26hjDGeQMl9Fk=", + "dev": true, + "requires": { + "ambi": "2.5.0", + "coffee-script": "1.8.0", + "extract-opts": "2.2.0", + "js2coffee": "0.3.5", + "requirefresh": "1.1.2" + }, + "dependencies": { + "coffee-script": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.8.0.tgz", + "integrity": "sha1-nJ8dK0pSoADe0Vtll5FwNkgmPB0=", + "dev": true, + "requires": { + "mkdirp": "0.3.5" + } + }, + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } + }, + "cz-conventional-changelog": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-1.2.0.tgz", + "integrity": "sha1-K8oElkyJGbI/P9aonvXmAIsxs/g=", + "dev": true, + "requires": { + "conventional-commit-types": "2.2.0", + "lodash.map": "4.6.0", + "longest": "1.0.1", + "pad-right": "0.2.2", + "right-pad": "1.0.1", + "word-wrap": "1.2.3" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "dateformat": { + "version": "1.0.2-1.2.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", + "integrity": "sha1-sCIMAt6YYXQztyhRz0fePfLNvuk=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "dev-ip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", + "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", + "dev": true + }, + "difflib": { + "version": "0.2.4", + "resolved": "http://registry.npm.baidu-int.com/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha1-teMDYabbAjF21WKJLbhZQKcY9H4=", + "requires": { + "heap": "0.2.6" + } + }, + "dot-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-1.1.2.tgz", + "integrity": "sha1-HnOCaQDeKNbeVIC8HeMdCEKwa+w=", + "dev": true, + "requires": { + "sentence-case": "1.1.3" + } + }, + "dreamopt": { + "version": "0.6.0", + "resolved": "http://registry.npm.baidu-int.com/dreamopt/-/dreamopt-0.6.0.tgz", + "integrity": "sha1-2BPM2sjTnYrVJndVFKE92mZNa0s=", + "requires": { + "wordwrap": "0.0.2" + } + }, + "easy-extender": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.2.tgz", + "integrity": "sha1-PTJI/r4rFZYHMW2PnPSRwWZIIh0=", + "dev": true, + "requires": { + "lodash": "3.10.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "eazy-logger": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.0.2.tgz", + "integrity": "sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw=", + "dev": true, + "requires": { + "tfunk": "3.1.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "editions": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "emitter-steward": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/emitter-steward/-/emitter-steward-1.0.0.tgz", + "integrity": "sha1-80Ea3pdYp1Zd+Eiy2gy70bRsvWQ=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "engine.io": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", + "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", + "dev": true, + "requires": { + "accepts": "1.3.5", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "uws": "9.14.0", + "ws": "3.3.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-client": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", + "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "3.3.3", + "xmlhttprequest-ssl": "1.5.5", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", + "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary2": "1.0.2" + } + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "optional": true, + "requires": { + "prr": "1.0.1" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es5-ext": { + "version": "0.8.2", + "resolved": "http://registry.npm.baidu-int.com/es5-ext/-/es5-ext-0.8.2.tgz", + "integrity": "sha1-q6jZ4ZQ6iVrJaDemKjmz9V7NlKs=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", + "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "extract-opts": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/extract-opts/-/extract-opts-2.2.0.tgz", + "integrity": "sha1-H6KOunNSxttID4hc63GkaBC+bX0=", + "dev": true, + "requires": { + "typechecker": "2.0.8" + }, + "dependencies": { + "typechecker": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-2.0.8.tgz", + "integrity": "sha1-6D2oS7ZMWEzLNFg4V2xAsDN9uC4=", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": "0.7.0" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "file": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/file/-/file-0.2.2.tgz", + "integrity": "sha1-w9/Y+M81Na5FXCtCPC5SY112tNM=", + "dev": true + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "finalhandler": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.0.tgz", + "integrity": "sha1-6VCKvs6bbbqHGmlCodeRG5GRGsc=", + "dev": true, + "requires": { + "debug": "2.2.0", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "statuses": "1.3.1", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "findup-sync": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", + "integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=", + "dev": true, + "requires": { + "glob": "3.2.11", + "lodash": "2.4.2" + }, + "dependencies": { + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimatch": "0.3.0" + } + }, + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "3.0.1", + "universalify": "0.1.1" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "gaze": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", + "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", + "dev": true, + "requires": { + "globule": "1.2.0" + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "getobject": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", + "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "dev": true, + "requires": { + "graceful-fs": "1.2.3", + "inherits": "1.0.2", + "minimatch": "0.2.14" + }, + "dependencies": { + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", + "dev": true + } + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "globule": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz", + "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=", + "dev": true, + "requires": { + "glob": "7.1.2", + "lodash": "4.17.5", + "minimatch": "3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + } + } + }, + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", + "dev": true + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "grunt": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", + "integrity": "sha1-VpN81RlDJK3/bSB2MYMqnWuk5/A=", + "dev": true, + "requires": { + "async": "0.1.22", + "coffee-script": "1.3.3", + "colors": "0.6.2", + "dateformat": "1.0.2-1.2.3", + "eventemitter2": "0.4.14", + "exit": "0.1.2", + "findup-sync": "0.1.3", + "getobject": "0.1.0", + "glob": "3.1.21", + "grunt-legacy-log": "0.1.3", + "grunt-legacy-util": "0.2.0", + "hooker": "0.2.3", + "iconv-lite": "0.2.11", + "js-yaml": "2.0.5", + "lodash": "0.9.2", + "minimatch": "0.2.14", + "nopt": "1.0.10", + "rimraf": "2.2.8", + "underscore.string": "2.2.1", + "which": "1.0.9" + } + }, + "grunt-angular-templates": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/grunt-angular-templates/-/grunt-angular-templates-0.5.9.tgz", + "integrity": "sha1-KJm+INlDitGbDQqAaqjseiOyWyo=", + "dev": true, + "requires": { + "html-minifier": "0.6.9" + } + }, + "grunt-browser-sync": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/grunt-browser-sync/-/grunt-browser-sync-2.2.0.tgz", + "integrity": "sha1-oOnB/RzLXEVMJexRcBE///BqR3I=", + "dev": true, + "requires": { + "browser-sync": "2.23.6" + } + }, + "grunt-contrib-clean": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.5.0.tgz", + "integrity": "sha1-9T397ghJsce0Dp67umn0jExgecU=", + "dev": true, + "requires": { + "rimraf": "2.2.8" + } + }, + "grunt-contrib-concat": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-0.5.1.tgz", + "integrity": "sha1-lTxu/f39LBB6uchQd/LUsk0xzUk=", + "dev": true, + "requires": { + "chalk": "0.5.1", + "source-map": "0.3.0" + }, + "dependencies": { + "source-map": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.3.0.tgz", + "integrity": "sha1-hYb7mloAXltQHiHNGLbyG0V60fk=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "grunt-contrib-copy": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-0.5.0.tgz", + "integrity": "sha1-QQB1rEWlhWuhkbHMclclRQ1KAhU=", + "dev": true + }, + "grunt-contrib-cssmin": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/grunt-contrib-cssmin/-/grunt-contrib-cssmin-0.12.3.tgz", + "integrity": "sha1-QVdZYJb7dlb8RktMx7B0beHzkBQ=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "clean-css": "3.4.28", + "maxmin": "1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "clean-css": { + "version": "3.4.28", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", + "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", + "dev": true, + "requires": { + "commander": "2.8.1", + "source-map": "0.4.4" + } + }, + "commander": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "dev": true, + "requires": { + "graceful-readlink": "1.0.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "grunt-contrib-less": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/grunt-contrib-less/-/grunt-contrib-less-1.4.1.tgz", + "integrity": "sha1-O73sC3XRLOqlXWKUNiXAsIYc328=", + "dev": true, + "requires": { + "async": "2.6.0", + "chalk": "1.1.3", + "less": "2.7.3", + "lodash": "4.17.5" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "4.17.5" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "grunt-contrib-uglify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-3.3.0.tgz", + "integrity": "sha512-W9O7lJE3PlD8VCc5fyaf98QV7f5wEDiU4PBIh0+/6UBbk2LhgzEFS0/p+taH5UD3+PlEn7QPN0o06Z0To6SqXw==", + "dev": true, + "requires": { + "chalk": "1.1.3", + "maxmin": "1.1.0", + "uglify-js": "3.3.16", + "uri-path": "1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "uglify-js": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.16.tgz", + "integrity": "sha512-FMh5SRqJRGhv9BbaTffENIpDDQIoPDR8DBraunGORGhySArsXlw9++CN+BWzPBLpoI4RcSnpfGPnilTxWL3Vvg==", + "dev": true, + "requires": { + "commander": "2.15.1", + "source-map": "0.6.1" + } + } + } + }, + "grunt-contrib-watch": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz", + "integrity": "sha1-hKGnodar0m7VaEE0lscxM+mQAY8=", + "dev": true, + "requires": { + "async": "1.5.2", + "gaze": "1.1.2", + "lodash": "3.10.1", + "tiny-lr": "0.2.1" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "grunt-legacy-log": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", + "integrity": "sha1-7ClCboAwIa9ZAp+H0vnNczWgVTE=", + "dev": true, + "requires": { + "colors": "0.6.2", + "grunt-legacy-log-utils": "0.1.1", + "hooker": "0.2.3", + "lodash": "2.4.2", + "underscore.string": "2.3.3" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "underscore.string": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", + "dev": true + } + } + }, + "grunt-legacy-log-utils": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz", + "integrity": "sha1-wHBrndkGThFvNvI/5OawSGcsD34=", + "dev": true, + "requires": { + "colors": "0.6.2", + "lodash": "2.4.2", + "underscore.string": "2.3.3" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "underscore.string": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", + "dev": true + } + } + }, + "grunt-legacy-util": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz", + "integrity": "sha1-kzJIhNv343qf98Am3/RR2UqeVUs=", + "dev": true, + "requires": { + "async": "0.1.22", + "exit": "0.1.2", + "getobject": "0.1.0", + "hooker": "0.2.3", + "lodash": "0.9.2", + "underscore.string": "2.2.1", + "which": "1.0.9" + } + }, + "grunt-module-dependence": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/grunt-module-dependence/-/grunt-module-dependence-0.2.1.tgz", + "integrity": "sha512-/3fUiimuVZZM5VAhDD0oxTeh+0jRMavaiP04oHlXs3EzJYHOHVFwsKVbwstGWvZYQhMLk2YY74vIKcU/rmCrUQ==", + "dev": true + }, + "grunt-ng-annotate": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/grunt-ng-annotate/-/grunt-ng-annotate-0.9.2.tgz", + "integrity": "sha1-cu2ORds4cVrbNbj5YicV9JcV994=", + "dev": true, + "requires": { + "lodash": "2.4.2", + "ng-annotate": "0.15.4" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + } + } + }, + "grunt-replace": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/grunt-replace/-/grunt-replace-0.8.0.tgz", + "integrity": "sha1-InGH8I16M0orKLMqT8AaWTJmCVY=", + "dev": true, + "requires": { + "applause": "0.3.4", + "chalk": "0.5.1" + } + }, + "grunt-wiredep": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-wiredep/-/grunt-wiredep-2.0.0.tgz", + "integrity": "sha1-ID9vYT95nW3XLOBE0NzvZNrx8uU=", + "dev": true, + "requires": { + "wiredep": "2.2.2" + } + }, + "gzip-size": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz", + "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", + "dev": true, + "requires": { + "browserify-zlib": "0.1.4", + "concat-stream": "1.6.1" + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "dev": true + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + } + }, + "has-binary2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz", + "integrity": "sha1-6D26SfC5vk0CbSc2U1DZ8D9Uvpg=", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "heap": { + "version": "0.2.6", + "resolved": "http://registry.npm.baidu-int.com/heap/-/heap-0.2.6.tgz", + "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=" + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true + }, + "hosted-git-info": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", + "dev": true + }, + "html-minifier": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-0.6.9.tgz", + "integrity": "sha1-UQXcI29efhqLplHUq5gThvx6vlM=", + "dev": true, + "requires": { + "change-case": "2.1.6", + "clean-css": "2.2.23", + "cli": "0.6.6", + "relateurl": "0.2.7", + "uglify-js": "2.4.24" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true + }, + "source-map": { + "version": "0.1.34", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.34.tgz", + "integrity": "sha1-p8/omux7FoLDsZjQrPtH19CQVms=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + }, + "uglify-js": { + "version": "2.4.24", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.24.tgz", + "integrity": "sha1-+tV1XB4Vd2WLsG/5q25UjJW+vW4=", + "dev": true, + "requires": { + "async": "0.2.10", + "source-map": "0.1.34", + "uglify-to-browserify": "1.0.2", + "yargs": "3.5.4" + } + }, + "yargs": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.5.4.tgz", + "integrity": "sha1-2K/49mXpTDS9JZvevRv68N3TU2E=", + "dev": true, + "requires": { + "camelcase": "1.2.1", + "decamelize": "1.2.0", + "window-size": "0.1.0", + "wordwrap": "0.0.2" + } + } + } + }, + "http-errors": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz", + "integrity": "sha1-eIwNLB3iyBuebowBhDtrl+uSB1A=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "setprototypeof": "1.0.2", + "statuses": "1.3.1" + } + }, + "http-parser-js": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.11.tgz", + "integrity": "sha512-QCR5O2AjjMW8Mo4HyI1ctFcv+O99j/0g367V3YoVnrNw5hkDvAWZD0lWGcc+F4yN3V55USPCVix4efb75HxFfA==", + "dev": true + }, + "http-proxy": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz", + "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=", + "dev": true, + "requires": { + "eventemitter3": "1.2.0", + "requires-port": "1.0.0" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "iconv-lite": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", + "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=", + "dev": true + }, + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "optional": true + }, + "immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.11.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-lower-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", + "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", + "dev": true, + "requires": { + "lower-case": "1.1.4" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-number-like": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", + "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", + "dev": true, + "requires": { + "lodash.isfinite": "3.3.2" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-upper-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", + "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", + "dev": true, + "requires": { + "upper-case": "1.1.3" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-yaml": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", + "integrity": "sha1-olrmUJmZ6X3yeMZxnaEb0Gh3Q6g=", + "dev": true, + "requires": { + "argparse": "0.1.16", + "esprima": "1.0.4" + } + }, + "js2coffee": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/js2coffee/-/js2coffee-0.3.5.tgz", + "integrity": "sha1-Hqv9gjyWakX1p1sxWWgxrYV55go=", + "dev": true, + "requires": { + "coffee-script": "1.7.1", + "file": "0.2.2", + "nopt": "3.0.6", + "underscore": "1.6.0" + }, + "dependencies": { + "coffee-script": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz", + "integrity": "sha1-YplqhheAx15tUGnROCJyO3NAS/w=", + "dev": true, + "requires": { + "mkdirp": "0.3.5" + } + }, + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.1.1" + } + }, + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", + "dev": true + } + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jshint-stylish": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jshint-stylish/-/jshint-stylish-1.0.2.tgz", + "integrity": "sha1-6Z88w0CvsY4qdwL4eY10AMoxRGo=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "log-symbols": "1.0.2", + "string-length": "1.0.1", + "text-table": "0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "json-diff": { + "version": "0.5.2", + "resolved": "http://registry.npm.baidu-int.com/json-diff/-/json-diff-0.5.2.tgz", + "integrity": "sha512-N7oapTQdD4rLMUtA7d1HATCPY/BpHuSNL1mhvIuoS0u5NideDvyR+gB/ntXB7ejFz/LM0XzPLNUJQcC68n5sBw==", + "requires": { + "cli-color": "0.1.7", + "difflib": "0.2.4", + "dreamopt": "0.6.0" + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, + "optional": true + } + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "kity": { + "version": "2.0.4", + "resolved": "http://registry.npm.baidu-int.com/kity/-/kity-2.0.4.tgz", + "integrity": "sha512-u6jPit9N44gPTMzB7EiX3szurI7JB6HPswJESQiS0UnrNiceOeLxGRAm0mgGRuRnkGXwmA3Pzn7hZ1rauINpOA==" + }, + "kityminder-core": { + "version": "1.4.50", + "resolved": "http://registry.npm.baidu-int.com/kityminder-core/-/kityminder-core-1.4.50.tgz", + "integrity": "sha512-HMXTLOqpyvnDVZiRJOt1TghF7hiWWxm2NKc40L9IL31Ev5Rkm4CHyY2m+1RP3YLHW00MWH/IX0KETuYIXnToTw==", + "requires": { + "json-diff": "0.5.2", + "kity": "2.0.4", + "seajs": "2.3.0" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "less": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", + "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", + "dev": true, + "requires": { + "errno": "0.1.7", + "graceful-fs": "4.1.11", + "image-size": "0.5.5", + "mime": "1.6.0", + "mkdirp": "0.5.1", + "promise": "7.3.1", + "request": "2.81.0", + "source-map": "0.5.7" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, + "optional": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "optional": true + } + } + }, + "limiter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.2.tgz", + "integrity": "sha512-JIKZ0xb6fZZYa3deZ0BgXCgX6HgV8Nx3mFGeFHmFWW8Fb2c08e0CyE+G3nalpD0xGvGssjGb1UdFr+PprxZEbw==", + "dev": true + }, + "livereload-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.3.0.tgz", + "integrity": "sha512-j1R0/FeGa64Y+NmqfZhyoVRzcFlOZ8sNlKzHjh4VvLULFACZhn68XrX5DFg2FhMvSMJmROuFxRSa560ECWKBMg==", + "dev": true + }, + "load-grunt-tasks": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz", + "integrity": "sha1-ByhWEYD9IP+KaSdQWFL8WKrqDIg=", + "dev": true, + "requires": { + "arrify": "1.0.1", + "multimatch": "2.1.0", + "pkg-up": "1.0.0", + "resolve-pkg": "0.1.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + } + } + }, + "localtunnel": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.8.3.tgz", + "integrity": "sha1-3MWSL9hWUQN9S94k/ZMkjQsk6wU=", + "dev": true, + "requires": { + "debug": "2.6.8", + "openurl": "1.1.1", + "request": "2.81.0", + "yargs": "3.29.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", + "dev": true + }, + "yargs": { + "version": "3.29.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.29.0.tgz", + "integrity": "sha1-GquWYOrnnYuPZ1vK7qtu40ws9pw=", + "dev": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "os-locale": "1.4.0", + "window-size": "0.1.4", + "y18n": "3.2.1" + } + } + } + }, + "lodash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz", + "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=", + "dev": true + }, + "lodash.isfinite": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", + "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", + "dev": true + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", + "dev": true + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "1.1.3" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "maxmin": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz", + "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "figures": "1.7.0", + "gzip-size": "1.0.0", + "pretty-bytes": "1.0.4" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true + }, + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "requires": { + "mime-db": "1.33.0" + } + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true, + "optional": true + } + } + }, + "mout": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/mout/-/mout-0.9.1.tgz", + "integrity": "sha1-hPDz/WrMcxf2PeKv/cwM7gCbBHc=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-union": "1.0.2", + "arrify": "1.0.1", + "minimatch": "3.0.4" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + } + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "ng-annotate": { + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/ng-annotate/-/ng-annotate-0.15.4.tgz", + "integrity": "sha1-ZQdSXI8vKPh4e824mPVtmzEGbpM=", + "dev": true, + "requires": { + "acorn": "0.11.0", + "alter": "0.2.0", + "convert-source-map": "0.4.1", + "optimist": "0.6.1", + "ordered-ast-traverse": "1.1.1", + "simple-fmt": "0.1.0", + "simple-is": "0.2.0", + "source-map": "0.1.43", + "stable": "0.1.6", + "stringmap": "0.2.2", + "stringset": "0.2.1", + "tryor": "0.1.2" + }, + "dependencies": { + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1.1.1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-path": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz", + "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "openurl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", + "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=", + "dev": true + }, + "opn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", + "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "pinkie-promise": "2.0.1" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "0.0.10", + "wordwrap": "0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + } + } + }, + "ordered-ast-traverse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ordered-ast-traverse/-/ordered-ast-traverse-1.1.1.tgz", + "integrity": "sha1-aEOhcLwO7otSDMjdwd3TqjD6BXw=", + "dev": true, + "requires": { + "ordered-esprima-props": "1.1.0" + } + }, + "ordered-esprima-props": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ordered-esprima-props/-/ordered-esprima-props-1.1.0.tgz", + "integrity": "sha1-qYJwht9fAQqmDpvQK24DNc6i/8s=", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, + "osenv": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.0.3.tgz", + "integrity": "sha1-zWrY3bKQkVrZ4idlV2Al1BHynLY=", + "dev": true + }, + "pad-right": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", + "integrity": "sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=", + "dev": true, + "requires": { + "repeat-string": "1.6.1" + } + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "param-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-1.1.2.tgz", + "integrity": "sha1-3LCRpDwlm5Io8cNB57akTqC/l0M=", + "dev": true, + "requires": { + "sentence-case": "1.1.3" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "1.0.2" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "1.0.2" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "pascal-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-1.1.2.tgz", + "integrity": "sha1-Pl1kogBDgwp8STRMLXS0G+DJyZs=", + "dev": true, + "requires": { + "camel-case": "1.2.2", + "upper-case-first": "1.1.2" + } + }, + "path-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-1.1.2.tgz", + "integrity": "sha1-UM5roNO+090LXCqcRVNpdDRAlRQ=", + "dev": true, + "requires": { + "sentence-case": "1.1.3" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + } + } + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "dev": true, + "requires": { + "find-up": "1.1.2" + } + }, + "portscanner": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", + "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=", + "dev": true, + "requires": { + "async": "1.5.2", + "is-number-like": "1.0.8" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + } + } + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-bytes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", + "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "optional": true, + "requires": { + "asap": "2.0.6" + } + }, + "propprop": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/propprop/-/propprop-0.3.1.tgz", + "integrity": "sha1-oEmjVouJZEAGfRXY7J8zc15XAXg=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true, + "optional": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", + "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", + "dev": true, + "requires": { + "bytes": "2.4.0", + "iconv-lite": "0.4.13", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.5", + "set-immediate-shim": "1.0.1" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + } + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "requirefresh": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/requirefresh/-/requirefresh-1.1.2.tgz", + "integrity": "sha1-2Ot0SSfG2RLeNBj5PcurJ7lZ8vM=", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + }, + "resolve-pkg": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz", + "integrity": "sha1-AsyZNBDik2livZcWahsHfalyVTE=", + "dev": true, + "requires": { + "resolve-from": "2.0.0" + } + }, + "resp-modifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", + "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=", + "dev": true, + "requires": { + "debug": "2.6.9", + "minimatch": "3.0.4" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + } + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "0.1.4" + } + }, + "right-pad": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", + "integrity": "sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=", + "dev": true + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "seajs": { + "version": "2.3.0", + "resolved": "http://registry.npm.baidu-int.com/seajs/-/seajs-2.3.0.tgz", + "integrity": "sha1-+inQ/h/NQsAYoq61ZwcDVGBZbIs=" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "send": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.15.2.tgz", + "integrity": "sha1-+R+rRAO8+H5xb3DOtdsvV4vcF9Y=", + "dev": true, + "requires": { + "debug": "2.6.4", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.0", + "http-errors": "1.6.2", + "mime": "1.3.4", + "ms": "1.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" + }, + "dependencies": { + "debug": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.4.tgz", + "integrity": "sha1-dYaps8OXQcAoKuM0RcTorHRzT+A=", + "dev": true, + "requires": { + "ms": "0.7.3" + }, + "dependencies": { + "ms": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=", + "dev": true + } + } + }, + "fresh": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", + "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.3.1" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + } + } + }, + "mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", + "dev": true + }, + "ms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-1.0.0.tgz", + "integrity": "sha1-Wa3NIu3FQ/e1OBhi0xOHsfS8lHM=", + "dev": true + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + } + } + }, + "sentence-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-1.1.3.tgz", + "integrity": "sha1-gDSq/CFFdy06vhUJqkLJ4QQtwTk=", + "dev": true, + "requires": { + "lower-case": "1.1.4" + } + }, + "serve-index": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.8.0.tgz", + "integrity": "sha1-fF2WwT+xMRAfk8HFd0+FFqHnjTs=", + "dev": true, + "requires": { + "accepts": "1.3.5", + "batch": "0.5.3", + "debug": "2.2.0", + "escape-html": "1.0.3", + "http-errors": "1.5.1", + "mime-types": "2.1.18", + "parseurl": "1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "serve-static": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.2.tgz", + "integrity": "sha1-5UbicmCBuBtLzsjpCAjrzdMjr7o=", + "dev": true, + "requires": { + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.15.2" + } + }, + "server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "setprototypeof": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz", + "integrity": "sha1-gaVSFB7BBLiOic44MQOtXGZWTQg=", + "dev": true + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-fmt": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/simple-fmt/-/simple-fmt-0.1.0.tgz", + "integrity": "sha1-GRv1ZqWeZTBILLJatTtKjchcOms=", + "dev": true + }, + "simple-is": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/simple-is/-/simple-is-0.2.0.tgz", + "integrity": "sha1-Krt1qt453rXMgVzhDmGRFkhQuvA=", + "dev": true + }, + "snake-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-1.1.2.tgz", + "integrity": "sha1-DC8l4wUVjZoY09l3BmGH/vilpmo=", + "dev": true, + "requires": { + "sentence-case": "1.1.3" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "socket.io": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz", + "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "engine.io": "3.1.5", + "socket.io-adapter": "1.1.1", + "socket.io-client": "2.0.4", + "socket.io-parser": "3.1.3" + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true + }, + "socket.io-client": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", + "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "2.6.9", + "engine.io-client": "3.1.6", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "3.1.3", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", + "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "3.1.0", + "has-binary2": "1.0.2", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "dev": true, + "requires": { + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "dev": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "stable": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.6.tgz", + "integrity": "sha1-kQ9dKu17Ugxud3SZwfMuE5/eyxA=", + "dev": true + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "stream-throttle": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", + "integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=", + "dev": true, + "requires": { + "commander": "2.2.0", + "limiter": "1.1.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "string-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", + "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", + "dev": true, + "requires": { + "strip-ansi": "3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "stringmap": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stringmap/-/stringmap-0.2.2.tgz", + "integrity": "sha1-VWwTeyWPlCuHdvWy71gqoGnX0bE=", + "dev": true + }, + "stringset": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/stringset/-/stringset-0.2.1.tgz", + "integrity": "sha1-7yWcTjSTRDd/zRyRPdLoSMnAQrU=", + "dev": true + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "dev": true + }, + "swap-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", + "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", + "dev": true, + "requires": { + "lower-case": "1.1.4", + "upper-case": "1.1.3" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tfunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz", + "integrity": "sha1-OORBT8ZJd9h6/apy+sttKfgve1s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "object-path": "0.9.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "tiny-lr": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz", + "integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=", + "dev": true, + "requires": { + "body-parser": "1.14.2", + "debug": "2.2.0", + "faye-websocket": "0.10.0", + "livereload-js": "2.3.0", + "parseurl": "1.3.2", + "qs": "5.1.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "qs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz", + "integrity": "sha1-TZMuXH6kEcynajEtOaYGIA/VDNk=", + "dev": true + } + } + }, + "title-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-1.1.2.tgz", + "integrity": "sha1-+uSmrlRr+iLQg6DuqRCkDRLtT1o=", + "dev": true, + "requires": { + "sentence-case": "1.1.3", + "upper-case": "1.1.3" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "tryor": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tryor/-/tryor-0.1.2.tgz", + "integrity": "sha1-gUXkynyv9ArN48z5Rui4u3W0Fys=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.18" + } + }, + "typechecker": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-4.5.0.tgz", + "integrity": "sha512-bqPE/ck3bVIaXP7gMKTKSHrypT32lpYTpiqzPYeYzdSQnmaGvaGhy7TnN/M/+5R+2rs/kKcp9ZLPRp/Q9Yj+4w==", + "dev": true, + "requires": { + "editions": "1.3.4" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.12", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.12.tgz", + "integrity": "sha1-BMgamb3V3FImPqKdJMa/jUgYpLs=", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "underscore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", + "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", + "dev": true + }, + "underscore.string": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz", + "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=", + "dev": true + }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "upper-case-first": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", + "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", + "dev": true, + "requires": { + "upper-case": "1.1.3" + } + }, + "uri-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", + "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", + "dev": true + }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", + "dev": true + }, + "uws": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", + "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", + "dev": true, + "optional": true + }, + "validate-npm-package-license": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "dev": true, + "requires": { + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "dev": true, + "requires": { + "http-parser-js": "0.4.11", + "websocket-extensions": "0.1.3" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true + }, + "which": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", + "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", + "dev": true + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wiredep": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/wiredep/-/wiredep-2.2.2.tgz", + "integrity": "sha1-FETRirLkk3UEEJP+3d3Rto97ZrM=", + "dev": true, + "requires": { + "bower-config": "0.5.3", + "chalk": "0.5.1", + "glob": "4.5.3", + "lodash": "2.4.2", + "minimist": "1.2.0", + "propprop": "0.3.1", + "through2": "0.6.5" + }, + "dependencies": { + "glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "2.0.10", + "once": "1.4.0" + } + }, + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + } + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "1.0.0", + "safe-buffer": "5.1.1", + "ultron": "1.1.1" + } + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + }, + "yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "dev": true, + "requires": { + "camelcase": "3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + } + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + } + } +} diff --git a/app/static/minder/package.json b/app/static/minder/package.json new file mode 100644 index 0000000..60cdd11 --- /dev/null +++ b/app/static/minder/package.json @@ -0,0 +1,58 @@ +{ + "name": "kityminder-editor", + "version": "1.0.64", + "description": "A powerful mind map editor", + "main": "kityminder.editor.js", + "scripts": { + "init": "npm i -g wr && npm install -g less && npm install -g bower && bower install && npm install", + "build": "grunt build", + "dev": "grunt dev", + "watch": "wr --exec \"lessc --source-map less/editor.less dist/kityminder.editor.css && grunt build\" less ui", + "postinstall": "bower install" + }, + "repository": { + "type": "git", + "url": "https://github.com/fex-team/kityminder-editor" + }, + "keywords": [ + "kityminder", + "editor", + "html5", + "js", + "mindmap" + ], + "author": "fex ", + "license": "GPL-2.0", + "bugs": { + "url": "https://github.com/fex-team/kityminder-editor/issues" + }, + "homepage": "https://github.com/fex-team/kityminder-editor", + "devDependencies": { + "cz-conventional-changelog": "^1.1.5", + "grunt": "~0.4.1", + "grunt-angular-templates": "~0.5.0", + "grunt-browser-sync": "^2.2.0", + "grunt-contrib-clean": "^0.5.0", + "grunt-contrib-concat": "~0.5.0", + "grunt-contrib-copy": "^0.5.0", + "grunt-contrib-cssmin": "^0.12.0", + "grunt-contrib-less": "^1.0.0", + "grunt-contrib-uglify": "^3.3.0", + "grunt-contrib-watch": "^1.0.0", + "grunt-module-dependence": "~0.2.0", + "grunt-ng-annotate": "^0.9.2", + "grunt-replace": "~0.8.0", + "grunt-wiredep": "^2.0.0", + "jshint-stylish": "^1.0.0", + "load-grunt-tasks": "^3.1.0", + "uglify-js": "^2.8.29" + }, + "dependencies": { + "kityminder-core": "^1.4.50" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + } +} diff --git a/app/static/minder/relations.png b/app/static/minder/relations.png new file mode 100644 index 0000000..8cc3468 Binary files /dev/null and b/app/static/minder/relations.png differ diff --git a/app/static/minder/server/imageUpload.php b/app/static/minder/server/imageUpload.php new file mode 100644 index 0000000..a88eacb --- /dev/null +++ b/app/static/minder/server/imageUpload.php @@ -0,0 +1,67 @@ +, msg: <错误信息>, data: {url: <返回的 URL>}}; + * 2. 由于要兼容两种情况的上传:通过对话框选择本地文件上传和直接 Ctrl + V(多见于截图后),因此本文件分别进行了判断 + * + * + * 注意: + * 1. 本文件的路径可以进行配置,详见 README.md 中「初始化配置」部分。 + * 2. 由于使用场景不同,请根据实际场景编写上传文件的处理。 + * 3. 本文件并没有做任何的安全方面的防护,请勿用于生产环境。 + * + * @author: zhangbobell + * + * @date: 2016.07.06 + * + */ + + // 返回给前端的地址是绝对地址,这里是前缀 + $HTTP_PREFIX = 'http://localhost/kityminder-editor/'; + + + $errno = 0; + $msg = 'ok'; + $url = ''; + + + if ((($_FILES["upload_file"]["type"] == "image/gif") + || ($_FILES["upload_file"]["type"] == "image/jpeg") + || ($_FILES["upload_file"]["type"] == "image/jpg") + || ($_FILES["upload_file"]["type"] == "image/png")) + && ($_FILES["upload_file"]["size"] < 1 * 1000 * 1000)) { + + if ($_FILES["upload_file"]["error"] > 0) { + $errno = 414; + $msg = $_FILES["upload_file"]["error"]; + } else { + + // 分为两种情况 `Ctrl + V` 和普通上传 + if ($_FILES["upload_file"]["name"] === 'blob') { + $ext_name = 'png'; + } else { + $ext_name = array_pop(explode('.', $_FILES["upload_file"]["name"])); + } + + $sha1_name = sha1_file($_FILES["upload_file"]["tmp_name"]) . '.' . $ext_name; + + move_uploaded_file($_FILES["upload_file"]["tmp_name"], "upload/" . $sha1_name); + $url = $HTTP_PREFIX . "server/upload/" . $sha1_name; + } + } else { + $errno = 416; + $msg = 'File is invalid'; + } + + + $result = array( + 'errno' => $errno, + 'msg' => $msg, + 'data' => array( + 'url' => $url + ) + ); + + echo json_encode($result); \ No newline at end of file diff --git a/app/static/minder/src/data.js b/app/static/minder/src/data.js new file mode 100644 index 0000000..c9ad7cd --- /dev/null +++ b/app/static/minder/src/data.js @@ -0,0 +1,171 @@ + +function exportData(){ + var jsonData=editor.minder.exportJson(); + jsonData = JSON.stringify(jsonData); + console.log(jsonData); + var minder_id = document.getElementById('minderId').value; + $.ajax( + { + url: "/save_test_minder_content.json", + data:{"content":jsonData,"id":minder_id}, + type: "post", + dataType:"json", + beforeSend:function() + { + return true; + }, + success:function(data) + { + if(data) + { + // 解析json数据 + var data = data; + if(data.code==200){ + alert('success!'); + // alert + }else{ + alert('code is :'+data.code+' and message is :'+data.msg); + } + } + + else + { + // $("#tip").html("失败,请重试"); + alert('操作失败'); + } + }, + error:function() + { + alert('请求出错'); + }, + complete:function() + { + // $('#tips').hide(); + } +}); + +} + + +function init(minder_id,refreshJson){ +// localStorage.removeItem('__dev_minder_content'); + document.getElementById('minderId').value = minder_id; + if (minder_id != ""){ + + $.ajax( + { + url: "/get_minders.json", + data:{"id":minder_id}, + type: "get", + dataType:"json", + beforeSend:function() + { + return true; + }, + success:function(data) + { + if(data) + { + // 解析json数据 + var data = data; + if(data.code==200){ +// alert('success!'); + console.log(JSON.parse(data.content)); +// editor.minder.importJson(JSON.parse(data.content)); + if (data.content!='{}'){ + if (refreshJson==1){ + editor.minder.importJson(JSON.parse(data.content)); + alert('刷新成功!'); + }else { + window.localStorage.__dev_minder_content=data.content; + } + }else{ + localStorage.removeItem('__dev_minder_content'); + if (refreshJson==1){ + alert('刷新成功!'); + } + } + // document.location.reload(); + // alert + }else{ + alert('code is :'+data.code+' and message is :'+data.msg); + } + } + + else + { + // $("#tip").html("失败,请重试"); + alert('操作失败'); + } + }, + error:function() + { + alert('请求出错'); + }, + complete:function() + { + // $('#tips').hide(); + } +}); + }else{ + alert('id is null!'); + } + +} + + + + +function copy_minder(){ + + var minder_id = document.getElementById('minderId').value; +// alert(minder_id); + if (minder_id != ""){ + + $.ajax( + { + url: "/copy_test_minder.json", + data:{"id":minder_id}, + type: "post", + dataType:"json", + beforeSend:function() + { + return true; + }, + success:function(data) + { + if(data) + { + // 解析json数据 + var data = data; + if(data.code==200){ + alert('success!'); + window.location.href=('/edit_minder_json?id='+data.id); + // document.location.reload(); + // alert + }else{ + alert('code is :'+data.code+' and message is :'+data.msg); + } + } + + else + { + // $("#tip").html("失败,请重试"); + alert('操作失败'); + } + }, + error:function() + { + alert('请求出错'); + }, + complete:function() + { + // $('#tips').hide(); + } +}); + }else{ + alert('id is null!'); + } + +} + diff --git a/app/static/minder/src/editor.js b/app/static/minder/src/editor.js new file mode 100644 index 0000000..7d0ff03 --- /dev/null +++ b/app/static/minder/src/editor.js @@ -0,0 +1,40 @@ +define(function(require, exports, module) { + + /** + * 运行时 + */ + var runtimes = []; + + function assemble(runtime) { + runtimes.push(runtime); + } + + function KMEditor(selector) { + this.selector = selector; + for (var i = 0; i < runtimes.length; i++) { + if (typeof runtimes[i] == 'function') { + runtimes[i].call(this, this); + } + } + } + + KMEditor.assemble = assemble; + + assemble(require('./runtime/container')); + assemble(require('./runtime/fsm')); + assemble(require('./runtime/minder')); + assemble(require('./runtime/receiver')); + assemble(require('./runtime/hotbox')); + assemble(require('./runtime/input')); + assemble(require('./runtime/clipboard-mimetype')); + assemble(require('./runtime/clipboard')); + assemble(require('./runtime/drag')); + assemble(require('./runtime/node')); + assemble(require('./runtime/history')); + assemble(require('./runtime/jumping')); + assemble(require('./runtime/priority')); + assemble(require('./runtime/progress')); + + + return module.exports = KMEditor; +}); \ No newline at end of file diff --git a/app/static/minder/src/expose-editor.js b/app/static/minder/src/expose-editor.js new file mode 100644 index 0000000..35dd900 --- /dev/null +++ b/app/static/minder/src/expose-editor.js @@ -0,0 +1,11 @@ +/** + * @fileOverview + * + * 打包暴露 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ +define('expose-editor', function(require, exports, module) { + return module.exports = kityminder.Editor = require('./editor'); +}); \ No newline at end of file diff --git a/app/static/minder/src/hotbox.js b/app/static/minder/src/hotbox.js new file mode 100644 index 0000000..de3e45a --- /dev/null +++ b/app/static/minder/src/hotbox.js @@ -0,0 +1,3 @@ +define(function(require, exports, module) { + return module.exports = window.HotBox; +}); \ No newline at end of file diff --git a/app/static/minder/src/lang.js b/app/static/minder/src/lang.js new file mode 100644 index 0000000..c7d8611 --- /dev/null +++ b/app/static/minder/src/lang.js @@ -0,0 +1,3 @@ +define(function(require, exports, module) { + +}); \ No newline at end of file diff --git a/app/static/minder/src/minder.js b/app/static/minder/src/minder.js new file mode 100644 index 0000000..46544d0 --- /dev/null +++ b/app/static/minder/src/minder.js @@ -0,0 +1,3 @@ +define(function(require, exports, module) { + return module.exports = window.kityminder.Minder; +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/clipboard-mimetype.js b/app/static/minder/src/runtime/clipboard-mimetype.js new file mode 100644 index 0000000..33ef036 --- /dev/null +++ b/app/static/minder/src/runtime/clipboard-mimetype.js @@ -0,0 +1,123 @@ +/** + * @Desc: 新增一个用于处理系统ctrl+c ctrl+v等方式导入导出节点的MIMETYPE处理,如系统不支持clipboardEvent或者是FF则不初始化改class + * @Editor: Naixor + * @Date: 2015.9.21 + */ +define(function(require, exports, module) { + function MimeType() { + /** + * 私有变量 + */ + var SPLITOR = '\uFEFF'; + var MIMETYPE = { + 'application/km': '\uFFFF' + }; + var SIGN = { + '\uFEFF': 'SPLITOR', + '\uFFFF': 'application/km' + }; + + /** + * 用于将一段纯文本封装成符合其数据格式的文本 + * @method process private + * @param {MIMETYPE} mimetype 数据格式 + * @param {String} text 原始文本 + * @return {String} 符合该数据格式下的文本 + * @example + * var str = "123"; + * str = process('application/km', str); // 返回的内容再经过MimeType判断会读取出其数据格式为application/km + * process('text/plain', str); // 若接受到一个非纯文本信息,则会将其转换为新的数据格式 + */ + function process(mimetype, text) { + if (!this.isPureText(text)) { + var _mimetype = this.whichMimeType(text); + if (!_mimetype) { + throw new Error('unknow mimetype!'); + }; + text = this.getPureText(text); + }; + if (mimetype === false) { + return text; + }; + return mimetype + SPLITOR + text; + } + + /** + * 注册数据类型的标识 + * @method registMimeTypeProtocol public + * @param {String} type 数据类型 + * @param {String} sign 标识 + */ + this.registMimeTypeProtocol = function(type, sign) { + if (sign && SIGN[sign]) { + throw new Error('sing has registed!'); + } + if (type && !!MIMETYPE[type]) { + throw new Error('mimetype has registed!'); + }; + SIGN[sign] = type; + MIMETYPE[type] = sign; + } + + /** + * 获取已注册数据类型的协议 + * @method getMimeTypeProtocol public + * @param {String} type 数据类型 + * @param {String} text|undefiend 文本内容或不传入 + * @return {String|Function} + * @example + * text若不传入则直接返回对应数据格式的处理(process)方法 + * 若传入文本则直接调用对应的process方法进行处理,此时返回处理后的内容 + * var m = new MimeType(); + * var kmprocess = m.getMimeTypeProtocol('application/km'); + * kmprocess("123") === m.getMimeTypeProtocol('application/km', "123"); + * + */ + this.getMimeTypeProtocol = function(type, text) { + var mimetype = MIMETYPE[type] || false; + + if (text === undefined) { + return process.bind(this, mimetype); + }; + + return process(mimetype, text); + } + + this.getSpitor = function() { + return SPLITOR; + } + + this.getMimeType = function(sign) { + if (sign !== undefined) { + return SIGN[sign] || null; + }; + return MIMETYPE; + } + } + + MimeType.prototype.isPureText = function(text) { + return !(~text.indexOf(this.getSpitor())); + } + + MimeType.prototype.getPureText = function(text) { + if (this.isPureText(text)) { + return text; + }; + return text.split(this.getSpitor())[1]; + } + + MimeType.prototype.whichMimeType = function(text) { + if (this.isPureText(text)) { + return null; + }; + return this.getMimeType(text.split(this.getSpitor())[0]); + } + + function MimeTypeRuntime() { + if (this.minder.supportClipboardEvent && !kity.Browser.gecko) { + this.MimeType = new MimeType(); + }; + } + + return module.exports = MimeTypeRuntime; +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/clipboard.js b/app/static/minder/src/runtime/clipboard.js new file mode 100644 index 0000000..e01e354 --- /dev/null +++ b/app/static/minder/src/runtime/clipboard.js @@ -0,0 +1,188 @@ +/** + * @Desc: 处理editor的clipboard事件,只在支持ClipboardEvent并且不是FF的情况下工作 + * @Editor: Naixor + * @Date: 2015.9.21 + */ +define(function(require, exports, module) { + + function ClipboardRuntime () { + var minder = this.minder; + var Data = window.kityminder.data; + + if (!minder.supportClipboardEvent || kity.Browser.gecko) { + return; + }; + + var fsm = this.fsm; + var receiver = this.receiver; + var MimeType = this.MimeType; + + var kmencode = MimeType.getMimeTypeProtocol('application/km'), + decode = Data.getRegisterProtocol('json').decode; + var _selectedNodes = []; + + /* + * 增加对多节点赋值粘贴的处理 + */ + function encode (nodes) { + var _nodes = []; + for (var i = 0, l = nodes.length; i < l; i++) { + _nodes.push(minder.exportNode(nodes[i])); + } + return kmencode(Data.getRegisterProtocol('json').encode(_nodes)); + } + + var beforeCopy = function (e) { + if (document.activeElement == receiver.element) { + var clipBoardEvent = e; + var state = fsm.state(); + + switch (state) { + case 'input': { + break; + } + case 'normal': { + var nodes = [].concat(minder.getSelectedNodes()); + if (nodes.length) { + // 这里由于被粘贴复制的节点的id信息也都一样,故做此算法 + // 这里有个疑问,使用node.getParent()或者node.parent会离奇导致出现非选中节点被渲染成选中节点,因此使用isAncestorOf,而没有使用自行回溯的方式 + if (nodes.length > 1) { + var targetLevel; + nodes.sort(function(a, b) { + return a.getLevel() - b.getLevel(); + }); + targetLevel = nodes[0].getLevel(); + if (targetLevel !== nodes[nodes.length-1].getLevel()) { + var plevel, pnode, + idx = 0, l = nodes.length, pidx = l-1; + + pnode = nodes[pidx]; + + while (pnode.getLevel() !== targetLevel) { + idx = 0; + while (idx < l && nodes[idx].getLevel() === targetLevel) { + if (nodes[idx].isAncestorOf(pnode)) { + nodes.splice(pidx, 1); + break; + } + idx++; + } + pidx--; + pnode = nodes[pidx]; + } + }; + }; + var str = encode(nodes); + clipBoardEvent.clipboardData.setData('text/plain', str); + } + e.preventDefault(); + break; + } + } + } + } + + var beforeCut = function (e) { + if (document.activeElement == receiver.element) { + if (minder.getStatus() !== 'normal') { + e.preventDefault(); + return; + }; + + var clipBoardEvent = e; + var state = fsm.state(); + + switch (state) { + case 'input': { + break; + } + case 'normal': { + var nodes = minder.getSelectedNodes(); + if (nodes.length) { + clipBoardEvent.clipboardData.setData('text/plain', encode(nodes)); + minder.execCommand('removenode'); + } + e.preventDefault(); + break; + } + } + }; + } + + var beforePaste = function(e) { + if (document.activeElement == receiver.element) { + if (minder.getStatus() !== 'normal') { + e.preventDefault(); + return; + }; + + var clipBoardEvent = e; + var state = fsm.state(); + var textData = clipBoardEvent.clipboardData.getData('text/plain'); + + switch (state) { + case 'input': { + // input状态下如果格式为application/km则不进行paste操作 + if (!MimeType.isPureText(textData)) { + e.preventDefault(); + return; + }; + break; + } + case 'normal': { + /* + * 针对normal状态下通过对选中节点粘贴导入子节点文本进行单独处理 + */ + var sNodes = minder.getSelectedNodes(); + + if (MimeType.whichMimeType(textData) === 'application/km') { + var nodes = decode(MimeType.getPureText(textData)); + var _node; + sNodes.forEach(function(node) { + // 由于粘贴逻辑中为了排除子节点重新排序导致逆序,因此复制的时候倒过来 + for (var i = nodes.length-1; i >= 0; i--) { + _node = minder.createNode(null, node); + minder.importNode(_node, nodes[i]); + _selectedNodes.push(_node); + node.appendChild(_node); + } + }); + minder.select(_selectedNodes, true); + _selectedNodes = []; + + minder.refresh(); + } + else if (clipBoardEvent.clipboardData && clipBoardEvent.clipboardData.items[0].type.indexOf('image') > -1) { + var imageFile = clipBoardEvent.clipboardData.items[0].getAsFile(); + var serverService = angular.element(document.body).injector().get('server'); + + return serverService.uploadImage(imageFile).then(function (json) { + var resp = json.data; + if (resp.errno === 0) { + minder.execCommand('image', resp.data.url); + } + }); + } + else { + sNodes.forEach(function(node) { + minder.Text2Children(node, textData); + }); + } + e.preventDefault(); + break; + } + } + } + } + /** + * 由editor的receiver统一处理全部事件,包括clipboard事件 + * @Editor: Naixor + * @Date: 2015.9.24 + */ + document.addEventListener('copy', beforeCopy); + document.addEventListener('cut', beforeCut); + document.addEventListener('paste', beforePaste); + } + + return module.exports = ClipboardRuntime; +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/container.js b/app/static/minder/src/runtime/container.js new file mode 100644 index 0000000..258ac1a --- /dev/null +++ b/app/static/minder/src/runtime/container.js @@ -0,0 +1,33 @@ +/** + * @fileOverview + * + * 初始化编辑器的容器 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ +define(function(require, exports, module) { + + /** + * 最先执行的 Runtime,初始化编辑器容器 + */ + function ContainerRuntime() { + var container; + + if (typeof(this.selector) == 'string') { + container = document.querySelector(this.selector); + } else { + container = this.selector; + } + + if (!container) throw new Error('Invalid selector: ' + this.selector); + + // 这个类名用于给编辑器添加样式 + container.classList.add('km-editor'); + + // 暴露容器给其他运行时使用 + this.container = container; + } + + return module.exports = ContainerRuntime; +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/drag.js b/app/static/minder/src/runtime/drag.js new file mode 100644 index 0000000..3fc185f --- /dev/null +++ b/app/static/minder/src/runtime/drag.js @@ -0,0 +1,140 @@ +/** + * @fileOverview + * + * 用于拖拽节点时屏蔽键盘事件 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ +define(function(require, exports, module) { + + var Hotbox = require('../hotbox'); + var Debug = require('../tool/debug'); + var debug = new Debug('drag'); + + function DragRuntime() { + var fsm = this.fsm; + var minder = this.minder; + var hotbox = this.hotbox; + var receiver = this.receiver; + var receiverElement = receiver.element; + + // setup everything to go + setupFsm(); + + // listen the fsm changes, make action. + function setupFsm() { + + // when jumped to drag mode, enter + fsm.when('* -> drag', function() { + // now is drag mode + }); + + fsm.when('drag -> *', function(exit, enter, reason) { + if (reason == 'drag-finish') { + // now exit drag mode + } + }); + } + + var downX, downY; + var MOUSE_HAS_DOWN = 0; + var MOUSE_HAS_UP = 1; + var BOUND_CHECK = 20; + var flag = MOUSE_HAS_UP; + var maxX, maxY, osx, osy, containerY; + var freeHorizen = false, freeVirtical = false; + var frame; + + function move(direction, speed) { + if (!direction) { + freeHorizen = freeVirtical = false; + frame && kity.releaseFrame(frame); + frame = null; + return; + } + if (!frame) { + frame = kity.requestFrame((function (direction, speed, minder) { + return function (frame) { + switch (direction) { + case 'left': + minder._viewDragger.move({x: -speed, y: 0}, 0); + break; + case 'top': + minder._viewDragger.move({x: 0, y: -speed}, 0); + break; + case 'right': + minder._viewDragger.move({x: speed, y: 0}, 0); + break; + case 'bottom': + minder._viewDragger.move({x: 0, y: speed}, 0); + break; + default: + return; + } + frame.next(); + }; + })(direction, speed, minder)); + } + } + + minder.on('mousedown', function(e) { + flag = MOUSE_HAS_DOWN; + var rect = minder.getPaper().container.getBoundingClientRect(); + downX = e.originEvent.clientX; + downY = e.originEvent.clientY; + containerY = rect.top; + maxX = rect.width; + maxY = rect.height; + }); + + minder.on('mousemove', function(e) { + if (fsm.state() === 'drag' && flag == MOUSE_HAS_DOWN && minder.getSelectedNode() + && (Math.abs(downX - e.originEvent.clientX) > BOUND_CHECK + || Math.abs(downY - e.originEvent.clientY) > BOUND_CHECK)) { + osx = e.originEvent.clientX; + osy = e.originEvent.clientY - containerY; + + if (osx < BOUND_CHECK) { + move('right', BOUND_CHECK - osx); + } else if (osx > maxX - BOUND_CHECK) { + move('left', BOUND_CHECK + osx - maxX); + } else { + freeHorizen = true; + } + if (osy < BOUND_CHECK) { + move('bottom', osy); + } else if (osy > maxY - BOUND_CHECK) { + move('top', BOUND_CHECK + osy - maxY); + } else { + freeVirtical = true; + } + if (freeHorizen && freeVirtical) { + move(false); + } + } + if (fsm.state() !== 'drag' + && flag === MOUSE_HAS_DOWN + && minder.getSelectedNode() + && (Math.abs(downX - e.originEvent.clientX) > BOUND_CHECK + || Math.abs(downY - e.originEvent.clientY) > BOUND_CHECK)) { + + if (fsm.state() === 'hotbox') { + hotbox.active(Hotbox.STATE_IDLE); + } + + return fsm.jump('drag', 'user-drag'); + } + }); + + window.addEventListener('mouseup', function () { + flag = MOUSE_HAS_UP; + if (fsm.state() === 'drag') { + move(false); + return fsm.jump('normal', 'drag-finish'); + } + }, false); + } + + return module.exports = DragRuntime; +}); diff --git a/app/static/minder/src/runtime/fsm.js b/app/static/minder/src/runtime/fsm.js new file mode 100644 index 0000000..c9ed5cb --- /dev/null +++ b/app/static/minder/src/runtime/fsm.js @@ -0,0 +1,121 @@ +/** + * @fileOverview + * + * 编辑器状态机 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ +define(function(require, exports, module) { + + var Debug = require('../tool/debug'); + var debug = new Debug('fsm'); + + function handlerConditionMatch(condition, when, exit, enter) { + if (condition.when != when) return false; + if (condition.enter != '*' && condition.enter != enter) return false; + if (condition.exit != '*' && condition.exit != exit) return; + return true; + } + + function FSM(defaultState) { + var currentState = defaultState; + var BEFORE_ARROW = ' - '; + var AFTER_ARROW = ' -> '; + var handlers = []; + + /** + * 状态跳转 + * + * 会通知所有的状态跳转监视器 + * + * @param {string} newState 新状态名称 + * @param {any} reason 跳转的原因,可以作为参数传递给跳转监视器 + */ + this.jump = function(newState, reason) { + if (!reason) throw new Error('Please tell fsm the reason to jump'); + + var oldState = currentState; + var notify = [oldState, newState].concat([].slice.call(arguments, 1)); + var i, handler; + + // 跳转前 + for (i = 0; i < handlers.length; i++) { + handler = handlers[i]; + if (handlerConditionMatch(handler.condition, 'before', oldState, newState)) { + if (handler.apply(null, notify)) return; + } + } + + currentState = newState; + debug.log('[{0}] {1} -> {2}', reason, oldState, newState); + + // 跳转后 + for (i = 0; i < handlers.length; i++) { + handler = handlers[i]; + if (handlerConditionMatch(handler.condition, 'after', oldState, newState)) { + handler.apply(null, notify); + } + } + return currentState; + }; + + /** + * 返回当前状态 + * @return {string} + */ + this.state = function() { + return currentState; + }; + + /** + * 添加状态跳转监视器 + * + * @param {string} condition + * 监视的时机 + * "* => *" (默认) + * + * @param {Function} handler + * 监视函数,当状态跳转的时候,会接收三个参数 + * * from - 跳转前的状态 + * * to - 跳转后的状态 + * * reason - 跳转的原因 + */ + this.when = function(condition, handler) { + if (arguments.length == 1) { + handler = condition; + condition = '* -> *'; + } + + var when, resolved, exit, enter; + + resolved = condition.split(BEFORE_ARROW); + if (resolved.length == 2) { + when = 'before'; + } else { + resolved = condition.split(AFTER_ARROW); + if (resolved.length == 2) { + when = 'after'; + } + } + if (!when) throw new Error('Illegal fsm condition: ' + condition); + + exit = resolved[0]; + enter = resolved[1]; + + handler.condition = { + when: when, + exit: exit, + enter: enter + }; + + handlers.push(handler); + }; + } + + function FSMRumtime() { + this.fsm = new FSM('normal'); + } + + return module.exports = FSMRumtime; +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/history.js b/app/static/minder/src/runtime/history.js new file mode 100644 index 0000000..e95c161 --- /dev/null +++ b/app/static/minder/src/runtime/history.js @@ -0,0 +1,133 @@ +/** + * @fileOverview + * + * 历史管理 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ + + +define(function(require, exports, module) { + var jsonDiff = require('../tool/jsondiff'); + + function HistoryRuntime() { + var minder = this.minder; + var hotbox = this.hotbox; + + var MAX_HISTORY = 100; + + var lastSnap; + var patchLock; + var undoDiffs; + var redoDiffs; + + function reset() { + undoDiffs = []; + redoDiffs = []; + lastSnap = minder.exportJson(); + } + + function makeUndoDiff() { + var headSnap = minder.exportJson(); + var diff = jsonDiff(headSnap, lastSnap); + if (diff.length) { + undoDiffs.push(diff); + while (undoDiffs.length > MAX_HISTORY) { + undoDiffs.shift(); + } + lastSnap = headSnap; + return true; + } + } + + function makeRedoDiff() { + var revertSnap = minder.exportJson(); + redoDiffs.push(jsonDiff(revertSnap, lastSnap)); + lastSnap = revertSnap; + } + + function undo() { + patchLock = true; + var undoDiff = undoDiffs.pop(); + if (undoDiff) { + minder.applyPatches(undoDiff); + makeRedoDiff(); + } + patchLock = false; + } + + function redo() { + patchLock = true; + var redoDiff = redoDiffs.pop(); + if (redoDiff) { + minder.applyPatches(redoDiff); + makeUndoDiff(); + } + patchLock = false; + } + + function changed() { + if (patchLock) return; + if (makeUndoDiff()) redoDiffs = []; + } + + function hasUndo() { + return !!undoDiffs.length; + } + + function hasRedo() { + return !!redoDiffs.length; + } + + function updateSelection(e) { + if (!patchLock) return; + var patch = e.patch; + switch (patch.express) { + case 'node.add': + minder.select(patch.node.getChild(patch.index), true); + break; + case 'node.remove': + case 'data.replace': + case 'data.remove': + case 'data.add': + minder.select(patch.node, true); + break; + } + } + + this.history = { + reset: reset, + undo: undo, + redo: redo, + hasUndo: hasUndo, + hasRedo: hasRedo + }; + reset(); + minder.on('contentchange', changed); + minder.on('import', reset); + minder.on('patch', updateSelection); + + var main = hotbox.state('main'); + main.button({ + position: 'top', + label: '撤销', + key: 'Ctrl + Z', + enable: hasUndo, + action: undo, + next: 'idle' + }); + main.button({ + position: 'top', + label: '重做', + key: 'Ctrl + Y', + enable: hasRedo, + action: redo, + next: 'idle' + }); + } + + window.diff = jsonDiff; + + return module.exports = HistoryRuntime; +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/hotbox.js b/app/static/minder/src/runtime/hotbox.js new file mode 100644 index 0000000..2794b41 --- /dev/null +++ b/app/static/minder/src/runtime/hotbox.js @@ -0,0 +1,56 @@ +/** + * @fileOverview + * + * 热盒 Runtime + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ +define(function(require, exports, module) { + var Hotbox = require('../hotbox'); + + function HotboxRuntime() { + var fsm = this.fsm; + var minder = this.minder; + var receiver = this.receiver; + var container = this.container; + + var hotbox = new Hotbox(container); + + hotbox.setParentFSM(fsm); + + fsm.when('normal -> hotbox', function(exit, enter, reason) { + var node = minder.getSelectedNode(); + var position; + if (node) { + var box = node.getRenderBox(); + position = { + x: box.cx, + y: box.cy + }; + } + hotbox.active('main', position); + }); + + fsm.when('normal -> normal', function(exit, enter, reason, e) { + if (reason == 'shortcut-handle') { + var handleResult = hotbox.dispatch(e); + if (handleResult) { + e.preventDefault(); + } else { + minder.dispatchKeyEvent(e); + } + } + }); + + fsm.when('modal -> normal', function(exit, enter, reason, e) { + if (reason == 'import-text-finish') { + receiver.element.focus(); + } + }); + + this.hotbox = hotbox; + } + + return module.exports = HotboxRuntime; +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/input.js b/app/static/minder/src/runtime/input.js new file mode 100644 index 0000000..2b4e124 --- /dev/null +++ b/app/static/minder/src/runtime/input.js @@ -0,0 +1,395 @@ +/** + * @fileOverview + * + * 文本输入支持 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ +define(function(require, exports, module) { + + require('../tool/innertext'); + + var Debug = require('../tool/debug'); + var debug = new Debug('input'); + + function InputRuntime() { + var fsm = this.fsm; + var minder = this.minder; + var hotbox = this.hotbox; + var receiver = this.receiver; + var receiverElement = receiver.element; + var isGecko = window.kity.Browser.gecko; + + // setup everything to go + setupReciverElement(); + setupFsm(); + setupHotbox(); + + // expose editText() + this.editText = editText; + + + // listen the fsm changes, make action. + function setupFsm() { + + // when jumped to input mode, enter + fsm.when('* -> input', enterInputMode); + + // when exited, commit or exit depends on the exit reason + fsm.when('input -> *', function(exit, enter, reason) { + switch (reason) { + case 'input-cancel': + return exitInputMode(); + case 'input-commit': + default: + return commitInputResult(); + } + }); + + // lost focus to commit + receiver.onblur(function (e) { + if (fsm.state() == 'input') { + fsm.jump('normal', 'input-commit'); + } + }); + + minder.on('beforemousedown', function () { + if (fsm.state() == 'input') { + fsm.jump('normal', 'input-commit'); + } + }); + + minder.on('dblclick', function() { + if (minder.getSelectedNode() && minder._status !== 'readonly') { + editText(); + } + }); + } + + + // let the receiver follow the current selected node position + function setupReciverElement() { + if (debug.flaged) { + receiverElement.classList.add('debug'); + } + + receiverElement.onmousedown = function(e) { + e.stopPropagation(); + }; + + minder.on('layoutallfinish viewchange viewchanged selectionchange', function(e) { + + // viewchange event is too frequenced, lazy it + if (e.type == 'viewchange' && fsm.state() != 'input') return; + + updatePosition(); + }); + + updatePosition(); + } + + + // edit entrance in hotbox + function setupHotbox() { + hotbox.state('main').button({ + position: 'center', + label: '编辑', + key: 'F2', + enable: function() { + return minder.queryCommandState('text') != -1; + }, + action: editText + }); + } + + + /** + * 增加对字体的鉴别,以保证用户在编辑状态ctrl/cmd + b/i所触发的加粗斜体与显示一致 + * @editor Naixor + * @Date 2015-12-2 + */ + // edit for the selected node + function editText() { + var node = minder.getSelectedNode(); + if (!node) { + return; + } + var textContainer = receiverElement; + receiverElement.innerText = ""; + if (node.getData('font-weight') === 'bold') { + var b = document.createElement('b'); + textContainer.appendChild(b); + textContainer = b; + } + if (node.getData('font-style') === 'italic') { + var i = document.createElement('i'); + textContainer.appendChild(i); + textContainer = i; + } + textContainer.innerText = minder.queryCommandValue('text'); + + if (isGecko) { + receiver.fixFFCaretDisappeared(); + }; + fsm.jump('input', 'input-request'); + receiver.selectAll(); + } + + /** + * 增加对字体的鉴别,以保证用户在编辑状态ctrl/cmd + b/i所触发的加粗斜体与显示一致 + * @editor Naixor + * @Date 2015-12-2 + */ + function enterInputMode() { + var node = minder.getSelectedNode(); + if (node) { + var fontSize = node.getData('font-size') || node.getStyle('font-size'); + receiverElement.style.fontSize = fontSize + 'px'; + receiverElement.style.minWidth = 0; + receiverElement.style.minWidth = receiverElement.clientWidth + 'px'; + receiverElement.style.fontWeight = node.getData('font-weight') || ''; + receiverElement.style.fontStyle = node.getData('font-style') || ''; + receiverElement.classList.add('input'); + receiverElement.focus(); + } + } + + /** + * 按照文本提交操作处理 + * @Desc: 从其他节点复制文字到另一个节点时部分浏览器(chrome)会自动包裹一个span标签,这样试用一下逻辑出来的就不是text节点二是span节点因此导致undefined的情况发生 + * @Warning: 下方代码使用[].slice.call来将HTMLDomCollection处理成为Array,ie8及以下会有问题 + * @Editor: Naixor + * @Date: 2015.9.16 + */ + function commitInputText (textNodes) { + var text = ''; + var TAB_CHAR = '\t', + ENTER_CHAR = '\n', + STR_CHECK = /\S/, + SPACE_CHAR = '\u0020', + // 针对FF,SG,BD,LB,IE等浏览器下SPACE的charCode存在为32和160的情况做处理 + SPACE_CHAR_REGEXP = new RegExp('(\u0020|' + String.fromCharCode(160) + ')'), + BR = document.createElement('br'); + var isBold = false, + isItalic = false; + + for (var str, + _divChildNodes, + space_l, space_num, tab_num, + i = 0, l = textNodes.length; i < l; i++) { + str = textNodes[i]; + + switch (Object.prototype.toString.call(str)) { + // 正常情况处理 + case '[object HTMLBRElement]': { + text += ENTER_CHAR; + break; + } + case '[object Text]': { + // SG下会莫名其妙的加上 影响后续判断,干掉! + /** + * FF下的wholeText会导致如下问题: + * |123| -> 在一个节点中输入一段字符,此时TextNode为[#Text 123] + * 提交并重新编辑,在后面追加几个字符 + * |123abc| -> 此时123为一个TextNode为[#Text 123, #Text abc],但是对这两个任意取值wholeText均为全部内容123abc + * 上述BUG仅存在在FF中,故将wholeText更改为textContent + */ + str = str.textContent.replace(" ", " "); + + if (!STR_CHECK.test(str)) { + space_l = str.length; + while (space_l--) { + if (SPACE_CHAR_REGEXP.test(str[space_l])) { + text += SPACE_CHAR; + } else if (str[space_l] === TAB_CHAR) { + text += TAB_CHAR; + } + } + } else { + text += str; + } + break; + } + // ctrl + b/i 会给字体加上/标签来实现黑体和斜体 + case '[object HTMLElement]': { + switch (str.nodeName) { + case "B": { + isBold = true; + break; + } + case "I": { + isItalic = true; + break; + } + default: {} + } + [].splice.apply(textNodes, [i, 1].concat([].slice.call(str.childNodes))); + l = textNodes.length; + i--; + break; + } + // 被增加span标签的情况会被处理成正常情况并会推交给上面处理 + case '[object HTMLSpanElement]': { + [].splice.apply(textNodes, [i, 1].concat([].slice.call(str.childNodes))); + l = textNodes.length; + i--; + break; + } + // 若标签为image标签,则判断是否为合法url,是将其加载进来 + case '[object HTMLImageElement]': { + if (str.src) { + if (/http(|s):\/\//.test(str.src)) { + minder.execCommand("Image", str.src, str.alt); + } else { + // data:image协议情况 + } + }; + break; + } + // 被增加div标签的情况会被处理成正常情况并会推交给上面处理 + case '[object HTMLDivElement]': { + _divChildNodes = []; + for (var di = 0, l = str.childNodes.length; di < l; di++) { + _divChildNodes.push(str.childNodes[di]); + } + _divChildNodes.push(BR); + [].splice.apply(textNodes, [i, 1].concat(_divChildNodes)); + l = textNodes.length; + i--; + break; + } + default: { + if (str && str.childNodes.length) { + _divChildNodes = []; + for (var di = 0, l = str.childNodes.length; di < l; di++) { + _divChildNodes.push(str.childNodes[di]); + } + _divChildNodes.push(BR); + [].splice.apply(textNodes, [i, 1].concat(_divChildNodes)); + l = textNodes.length; + i--; + } else { + if (str && str.textContent !== undefined) { + text += str.textContent; + } else { + text += ""; + } + } + // // 其他带有样式的节点被粘贴进来,则直接取textContent,若取不出来则置空 + } + } + }; + + text = text.replace(/^\n*|\n*$/g, ''); + text = text.replace(new RegExp('(\n|\r|\n\r)(\u0020|' + String.fromCharCode(160) + '){4}', 'g'), '$1\t'); + minder.getSelectedNode().setText(text); + if (isBold) { + minder.queryCommandState('bold') || minder.execCommand('bold'); + } else { + minder.queryCommandState('bold') && minder.execCommand('bold'); + } + + if (isItalic) { + minder.queryCommandState('italic') || minder.execCommand('italic'); + } else { + minder.queryCommandState('italic') && minder.execCommand('italic'); + } + exitInputMode(); + return text; + } + + /** + * 判断节点的文本信息是否是 + * @Desc: 从其他节点复制文字到另一个节点时部分浏览器(chrome)会自动包裹一个span标签,这样使用以下逻辑出来的就不是text节点二是span节点因此导致undefined的情况发生 + * @Notice: 此处逻辑应该拆分到 kityminder-core/core/data中去,单独增加一个对某个节点importJson的事件 + * @Editor: Naixor + * @Date: 2015.9.16 + */ + function commitInputNode(node, text) { + try { + minder.decodeData('text', text).then(function(json) { + function importText(node, json, minder) { + var data = json.data; + + node.setText(data.text || ''); + + var childrenTreeData = json.children || []; + for (var i = 0; i < childrenTreeData.length; i++) { + var childNode = minder.createNode(null, node); + importText(childNode, childrenTreeData[i], minder); + } + return node; + } + importText(node, json, minder); + minder.fire("contentchange"); + minder.getRoot().renderTree(); + minder.layout(300); + }); + } catch (e) { + minder.fire("contentchange"); + minder.getRoot().renderTree(); + + // 无法被转换成脑图节点则不处理 + if (e.toString() !== 'Error: Invalid local format') { + throw e; + } + } + } + + function commitInputResult() { + /** + * @Desc: 进行如下处理: + * 根据用户的输入判断是否生成新的节点 + * fix #83 https://github.com/fex-team/kityminder-editor/issues/83 + * @Editor: Naixor + * @Date: 2015.9.16 + */ + var textNodes = [].slice.call(receiverElement.childNodes); + + /** + * @Desc: 增加setTimeout的原因:ie下receiverElement.innerHTML=""会导致后 + * 面commitInputText中使用textContent报错,不要问我什么原因! + * @Editor: Naixor + * @Date: 2015.12.14 + */ + setTimeout(function () { + // 解决过大内容导致SVG窜位问题 + receiverElement.innerHTML = ""; + }, 0); + var node = minder.getSelectedNode(); + + textNodes = commitInputText(textNodes); + commitInputNode(node, textNodes); + + if (node.type == 'root') { + var rootText = minder.getRoot().getText(); + minder.fire('initChangeRoot', {text: rootText}); + } + } + + function exitInputMode() { + receiverElement.classList.remove('input'); + receiver.selectAll(); + } + + function updatePosition() { + var planed = updatePosition; + + var focusNode = minder.getSelectedNode(); + if (!focusNode) return; + + if (!planed.timer) { + planed.timer = setTimeout(function() { + var box = focusNode.getRenderBox('TextRenderer'); + receiverElement.style.left = Math.round(box.x) + 'px'; + receiverElement.style.top = (debug.flaged ? Math.round(box.bottom + 30) : Math.round(box.y)) + 'px'; + //receiverElement.focus(); + planed.timer = 0; + }); + } + } + } + + return module.exports = InputRuntime; +}); diff --git a/app/static/minder/src/runtime/jumping.js b/app/static/minder/src/runtime/jumping.js new file mode 100644 index 0000000..e16eacf --- /dev/null +++ b/app/static/minder/src/runtime/jumping.js @@ -0,0 +1,174 @@ +/** + * @fileOverview + * + * 根据按键控制状态机的跳转 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ +define(function(require, exports, module) { + + var Hotbox = require('../hotbox'); + + + // Nice: http://unixpapa.com/js/key.html + function isIntendToInput(e) { + if (e.ctrlKey || e.metaKey || e.altKey) return false; + + // a-zA-Z + if (e.keyCode >= 65 && e.keyCode <= 90) return true; + + // 0-9 以及其上面的符号 + if (e.keyCode >= 48 && e.keyCode <= 57) return true; + + // 小键盘区域 (除回车外) + if (e.keyCode != 108 && e.keyCode >= 96 && e.keyCode <= 111) return true; + + // 小键盘区域 (除回车外) + // @yinheli from pull request + if (e.keyCode != 108 && e.keyCode >= 96 && e.keyCode <= 111) return true; + + // 输入法 + if (e.keyCode == 229 || e.keyCode === 0) return true; + + return false; + } + /** + * @Desc: 下方使用receiver.enable()和receiver.disable()通过 + * 修改div contenteditable属性的hack来解决开启热核后依然无法屏蔽浏览器输入的bug; + * 特别: win下FF对于此种情况必须要先blur在focus才能解决,但是由于这样做会导致用户 + * 输入法状态丢失,因此对FF暂不做处理 + * @Editor: Naixor + * @Date: 2015.09.14 + */ + function JumpingRuntime() { + var fsm = this.fsm; + var minder = this.minder; + var receiver = this.receiver; + var container = this.container; + var receiverElement = receiver.element; + var hotbox = this.hotbox; + + // normal -> * + receiver.listen('normal', function(e) { + // 为了防止处理进入edit模式而丢失处理的首字母,此时receiver必须为enable + receiver.enable(); + // normal -> hotbox + if (e.is('Space')) { + e.preventDefault(); + // safari下Space触发hotbox,然而这时Space已在receiver上留下作案痕迹,因此抹掉 + if (kity.Browser.safari) { + receiverElement.innerHTML = ''; + } + return fsm.jump('hotbox', 'space-trigger'); + } + + /** + * check + * @editor Naixor + * @Date 2015-12-2 + */ + switch (e.type) { + case 'keydown': { + if (minder.getSelectedNode()) { + if (isIntendToInput(e)) { + return fsm.jump('input', 'user-input'); + }; + } else { + receiverElement.innerHTML = ''; + } + // normal -> normal shortcut + fsm.jump('normal', 'shortcut-handle', e); + break; + } + case 'keyup': { + break; + } + default: {} + } + }); + + // hotbox -> normal + receiver.listen('hotbox', function(e) { + receiver.disable(); + e.preventDefault(); + var handleResult = hotbox.dispatch(e); + if (hotbox.state() == Hotbox.STATE_IDLE && fsm.state() == 'hotbox') { + return fsm.jump('normal', 'hotbox-idle'); + } + }); + + // input => normal + receiver.listen('input', function(e) { + receiver.enable(); + if (e.type == 'keydown') { + if (e.is('Enter')) { + e.preventDefault(); + return fsm.jump('normal', 'input-commit'); + } + if (e.is('Esc')) { + e.preventDefault(); + return fsm.jump('normal', 'input-cancel'); + } + if (e.is('Tab') || e.is('Shift + Tab')) { + e.preventDefault(); + } + } else if (e.type == 'keyup' && e.is('Esc')) { + e.preventDefault(); + return fsm.jump('normal', 'input-cancel'); + } + }); + + + ////////////////////////////////////////////// + /// 右键呼出热盒 + /// 判断的标准是:按下的位置和结束的位置一致 + ////////////////////////////////////////////// + var downX, downY; + var MOUSE_RB = 2; // 右键 + + container.addEventListener('mousedown', function(e) { + if (e.button == MOUSE_RB) { + e.preventDefault(); + } + if (fsm.state() == 'hotbox') { + hotbox.active(Hotbox.STATE_IDLE); + fsm.jump('normal', 'blur'); + } else if (fsm.state() == 'normal' && e.button == MOUSE_RB) { + downX = e.clientX; + downY = e.clientY; + } + }, false); + + container.addEventListener('mousewheel', function(e) { + if (fsm.state() == 'hotbox') { + hotbox.active(Hotbox.STATE_IDLE); + fsm.jump('normal', 'mousemove-blur'); + } + }, false); + + container.addEventListener('contextmenu', function(e) { + e.preventDefault(); + }); + + container.addEventListener('mouseup', function(e) { + if (fsm.state() != 'normal') { + return; + } + if (e.button != MOUSE_RB || e.clientX != downX || e.clientY != downY) { + return; + } + if (!minder.getSelectedNode()) { + return; + } + fsm.jump('hotbox', 'content-menu'); + }, false); + + // 阻止热盒事件冒泡,在热盒正确执行前导致热盒关闭 + hotbox.$element.addEventListener('mousedown', function(e) { + e.stopPropagation(); + }); + } + + return module.exports = JumpingRuntime; +}); diff --git a/app/static/minder/src/runtime/minder.js b/app/static/minder/src/runtime/minder.js new file mode 100644 index 0000000..4dcd1ae --- /dev/null +++ b/app/static/minder/src/runtime/minder.js @@ -0,0 +1,31 @@ +/** + * @fileOverview + * + * 脑图示例运行时 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ +define(function(require, exports, module) { + var Minder = require('../minder'); + + function MinderRuntime() { + + // 不使用 kityminder 的按键处理,由 ReceiverRuntime 统一处理 + var minder = new Minder({ + enableKeyReceiver: false, + enableAnimation: true + }); + + // 渲染,初始化 + minder.renderTo(this.selector); + minder.setTheme(null); + minder.select(minder.getRoot(), true); + minder.execCommand('text', '中心主题'); + + // 导出给其它 Runtime 使用 + this.minder = minder; + } + + return module.exports = MinderRuntime; +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/node.js b/app/static/minder/src/runtime/node.js new file mode 100644 index 0000000..b8bf9a6 --- /dev/null +++ b/app/static/minder/src/runtime/node.js @@ -0,0 +1,112 @@ +define(function(require, exports, module) { + + function NodeRuntime() { + var runtime = this; + var minder = this.minder; + var hotbox = this.hotbox; + var fsm = this.fsm; + + var main = hotbox.state('main'); + + var buttons = [ + '前移:Alt+Up:ArrangeUp', + '下级:Tab|Insert:AppendChildNode', + '同级:Enter:AppendSiblingNode', + '后移:Alt+Down:ArrangeDown', + '删除:Delete|Backspace:RemoveNode', + '上级:Shift+Tab|Shift+Insert:AppendParentNode' + //'全选:Ctrl+A:SelectAll' + ]; + + var AppendLock = 0; + + buttons.forEach(function(button) { + var parts = button.split(':'); + var label = parts.shift(); + var key = parts.shift(); + var command = parts.shift(); + main.button({ + position: 'ring', + label: label, + key: key, + action: function() { + if (command.indexOf('Append') === 0) { + AppendLock++; + minder.execCommand(command, '分支主题'); + + // provide in input runtime + function afterAppend () { + if (!--AppendLock) { + runtime.editText(); + } + minder.off('layoutallfinish', afterAppend); + } + minder.on('layoutallfinish', afterAppend); + } else { + minder.execCommand(command); + fsm.jump('normal', 'command-executed'); + } + }, + enable: function() { + return minder.queryCommandState(command) != -1; + } + }); + }); + + main.button({ + position: 'bottom', + label: '导入节点', + key: 'Alt + V', + enable: function() { + var selectedNodes = minder.getSelectedNodes(); + return selectedNodes.length == 1; + }, + action: importNodeData, + next: 'idle' + }); + + main.button({ + position: 'bottom', + label: '导出节点', + key: 'Alt + C', + enable: function() { + var selectedNodes = minder.getSelectedNodes(); + return selectedNodes.length == 1; + }, + action: exportNodeData, + next: 'idle' + }); + + function importNodeData() { + minder.fire('importNodeData'); + } + + function exportNodeData() { + minder.fire('exportNodeData'); + } + + //main.button({ + // position: 'ring', + // key: '/', + // action: function(){ + // if (!minder.queryCommandState('expand')) { + // minder.execCommand('expand'); + // } else if (!minder.queryCommandState('collapse')) { + // minder.execCommand('collapse'); + // } + // }, + // enable: function() { + // return minder.queryCommandState('expand') != -1 || minder.queryCommandState('collapse') != -1; + // }, + // beforeShow: function() { + // if (!minder.queryCommandState('expand')) { + // this.$button.children[0].innerHTML = '展开'; + // } else { + // this.$button.children[0].innerHTML = '收起'; + // } + // } + //}) + } + + return module.exports = NodeRuntime; +}); diff --git a/app/static/minder/src/runtime/priority.js b/app/static/minder/src/runtime/priority.js new file mode 100644 index 0000000..3b91dcc --- /dev/null +++ b/app/static/minder/src/runtime/priority.js @@ -0,0 +1,51 @@ +define(function(require, exports, module){ + + function PriorityRuntime() { + var minder = this.minder; + var hotbox = this.hotbox; + + var main = hotbox.state('main'); + + main.button({ + position: 'top', + label: '优先级', + key: 'P', + next: 'priority', + enable: function() { + return minder.queryCommandState('priority') != -1; + } + }); + + var priority = hotbox.state('priority'); + '123456789'.replace(/./g, function(p) { + priority.button({ + position: 'ring', + label: 'P' + p, + key: p, + action: function() { + minder.execCommand('Priority', p); + } + }); + }); + + priority.button({ + position: 'center', + label: '移除', + key: 'Del', + action: function() { + minder.execCommand('Priority', 0); + } + }); + + priority.button({ + position: 'top', + label: '返回', + key: 'esc', + next: 'back' + }); + + } + + return module.exports = PriorityRuntime; + +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/progress.js b/app/static/minder/src/runtime/progress.js new file mode 100644 index 0000000..3ce7d30 --- /dev/null +++ b/app/static/minder/src/runtime/progress.js @@ -0,0 +1,52 @@ +define(function(require, exports, module){ + + function ProgressRuntime() { + var minder = this.minder; + var hotbox = this.hotbox; + + var main = hotbox.state('main'); + + main.button({ + position: 'top', + label: '进度', + key: 'G', + next: 'progress', + enable: function() { + return minder.queryCommandState('progress') != -1; + } + }); + + var progress = hotbox.state('progress'); + '012345678'.replace(/./g, function(p) { + progress.button({ + position: 'ring', + label: 'G' + p, + key: p, + action: function() { + minder.execCommand('Progress', parseInt(p) + 1); + } + }); + }); + + progress.button({ + position: 'center', + label: '移除', + key: 'Del', + action: function() { + minder.execCommand('Progress', 0); + } + }); + + progress.button({ + position: 'top', + label: '返回', + key: 'esc', + next: 'back' + }); + + + } + + return module.exports = ProgressRuntime; + +}); \ No newline at end of file diff --git a/app/static/minder/src/runtime/receiver.js b/app/static/minder/src/runtime/receiver.js new file mode 100644 index 0000000..98c0c37 --- /dev/null +++ b/app/static/minder/src/runtime/receiver.js @@ -0,0 +1,144 @@ +/** + * @fileOverview + * + * 键盘事件接收/分发器 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ + +define(function(require, exports, module) { + var key = require('../tool/key'); + var hotbox = require('hotbox'); + + function ReceiverRuntime() { + var fsm = this.fsm; + var minder = this.minder; + var me = this; + + // 接收事件的 div + var element = document.createElement('div'); + element.contentEditable = true; + /** + * @Desc: 增加tabindex属性使得element的contenteditable不管是trur还是false都能有focus和blur事件 + * @Editor: Naixor + * @Date: 2015.09.14 + */ + element.setAttribute("tabindex", -1); + element.classList.add('receiver'); + element.onkeydown = element.onkeypress = element.onkeyup = dispatchKeyEvent; + this.container.appendChild(element); + + // receiver 对象 + var receiver = { + element: element, + selectAll: function() { + // 保证有被选中的 + if (!element.innerHTML) element.innerHTML = ' '; + var range = document.createRange(); + var selection = window.getSelection(); + range.selectNodeContents(element); + selection.removeAllRanges(); + selection.addRange(range); + element.focus(); + }, + /** + * @Desc: 增加enable和disable方法用于解决热核态的输入法屏蔽问题 + * @Editor: Naixor + * @Date: 2015.09.14 + */ + enable: function() { + element.setAttribute("contenteditable", true); + }, + disable: function() { + element.setAttribute("contenteditable", false); + }, + /** + * @Desc: hack FF下div contenteditable的光标丢失BUG + * @Editor: Naixor + * @Date: 2015.10.15 + */ + fixFFCaretDisappeared: function() { + element.removeAttribute("contenteditable"); + element.setAttribute("contenteditable", "true"); + element.blur(); + element.focus(); + }, + /** + * 以此事件代替通过mouse事件来判断receiver丢失焦点的事件 + * @editor Naixor + * @Date 2015-12-2 + */ + onblur: function (handler) { + element.onblur = handler; + } + }; + receiver.selectAll(); + + minder.on('beforemousedown', receiver.selectAll); + minder.on('receiverfocus', receiver.selectAll); + minder.on('readonly', function() { + // 屏蔽minder的事件接受,删除receiver和hotbox + minder.disable(); + editor.receiver.element.parentElement.removeChild(editor.receiver.element); + editor.hotbox.$container.removeChild(editor.hotbox.$element); + }); + + // 侦听器,接收到的事件会派发给所有侦听器 + var listeners = []; + + // 侦听指定状态下的事件,如果不传 state,侦听所有状态 + receiver.listen = function(state, listener) { + if (arguments.length == 1) { + listener = state; + state = '*'; + } + listener.notifyState = state; + listeners.push(listener); + }; + + function dispatchKeyEvent(e) { + e.is = function(keyExpression) { + var subs = keyExpression.split('|'); + for (var i = 0; i < subs.length; i++) { + if (key.is(this, subs[i])) return true; + } + return false; + }; + var listener, jumpState; + for (var i = 0; i < listeners.length; i++) { + + listener = listeners[i]; + // 忽略不在侦听状态的侦听器 + if (listener.notifyState != '*' && listener.notifyState != fsm.state()) { + continue; + } + + /** + * + * 对于所有的侦听器,只允许一种处理方式:跳转状态。 + * 如果侦听器确定要跳转,则返回要跳转的状态。 + * 每个事件只允许一个侦听器进行状态跳转 + * 跳转动作由侦听器自行完成(因为可能需要在跳转时传递 reason),返回跳转结果即可。 + * 比如: + * + * ```js + * receiver.listen('normal', function(e) { + * if (isSomeReasonForJumpState(e)) { + * return fsm.jump('newstate', e); + * } + * }); + * ``` + */ + if (listener.call(null, e)) { + return; + } + } + } + + this.receiver = receiver; + } + + return module.exports = ReceiverRuntime; + +}); diff --git a/app/static/minder/src/tool/debug.js b/app/static/minder/src/tool/debug.js new file mode 100644 index 0000000..b6812de --- /dev/null +++ b/app/static/minder/src/tool/debug.js @@ -0,0 +1,47 @@ +/** + * @fileOverview + * + * 支持各种调试后门 + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ +define(function(require, exports, module) { + var format = require('./format'); + + function noop() {} + + function stringHash(str) { + var hash = 0; + for (var i = 0; i < str.length; i++) { + hash += str.charCodeAt(i); + } + return hash; + } + + /* global console */ + function Debug(flag) { + var debugMode = this.flaged = window.location.search.indexOf(flag) != -1; + + if (debugMode) { + var h = stringHash(flag) % 360; + + var flagStyle = format( + 'background: hsl({0}, 50%, 80%); ' + + 'color: hsl({0}, 100%, 30%); ' + + 'padding: 2px 3px; ' + + 'margin: 1px 3px 0 0;' + + 'border-radius: 2px;', h); + + var textStyle = 'background: none; color: black;'; + this.log = function() { + var output = format.apply(null, arguments); + console.log(format('%c{0}%c{1}', flag, output), flagStyle, textStyle); + }; + } else { + this.log = noop; + } + } + + return module.exports = Debug; +}); \ No newline at end of file diff --git a/app/static/minder/src/tool/format.js b/app/static/minder/src/tool/format.js new file mode 100644 index 0000000..2e168dc --- /dev/null +++ b/app/static/minder/src/tool/format.js @@ -0,0 +1,11 @@ +define(function(require, exports, module) { + function format(template, args) { + if (typeof(args) != 'object') { + args = [].slice.call(arguments, 1); + } + return String(template).replace(/\{(\w+)\}/ig, function(match, $key) { + return args[$key] || $key; + }); + } + return module.exports = format; +}); \ No newline at end of file diff --git a/app/static/minder/src/tool/innertext.js b/app/static/minder/src/tool/innertext.js new file mode 100644 index 0000000..912fdb9 --- /dev/null +++ b/app/static/minder/src/tool/innertext.js @@ -0,0 +1,54 @@ +/** + * @fileOverview + * + * innerText polyfill + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ + + +define(function(require, exports, module) { + if ((!('innerText' in document.createElement('a'))) && ('getSelection' in window)) { + HTMLElement.prototype.__defineGetter__('innerText', function() { + var selection = window.getSelection(), + ranges = [], + str, i; + + // Save existing selections. + for (i = 0; i < selection.rangeCount; i++) { + ranges[i] = selection.getRangeAt(i); + } + + // Deselect everything. + selection.removeAllRanges(); + + // Select `el` and all child nodes. + // 'this' is the element .innerText got called on + selection.selectAllChildren(this); + + // Get the string representation of the selected nodes. + str = selection.toString(); + + // Deselect everything. Again. + selection.removeAllRanges(); + + // Restore all formerly existing selections. + for (i = 0; i < ranges.length; i++) { + selection.addRange(ranges[i]); + } + + // Oh look, this is what we wanted. + // String representation of the element, close to as rendered. + return str; + }); + HTMLElement.prototype.__defineSetter__('innerText', function(text) { + /** + * @Desc: 解决FireFox节点内容删除后text为null,出现报错的问题 + * @Editor: Naixor + * @Date: 2015.9.16 + */ + this.innerHTML = (text || '').replace(//g, '>').replace(/\n/g, '
'); + }); + } +}); \ No newline at end of file diff --git a/app/static/minder/src/tool/jsondiff.js b/app/static/minder/src/tool/jsondiff.js new file mode 100644 index 0000000..dac36e1 --- /dev/null +++ b/app/static/minder/src/tool/jsondiff.js @@ -0,0 +1,91 @@ +/** + * @fileOverview + * + * + * + * @author: techird + * @copyright: Baidu FEX, 2014 + */ + + +define(function(require, exports, module) { + /*! + * https://github.com/Starcounter-Jack/Fast-JSON-Patch + * json-patch-duplex.js 0.5.0 + * (c) 2013 Joachim Wester + * MIT license + */ + + var _objectKeys = (function () { + if (Object.keys) + return Object.keys; + + return function (o) { + var keys = []; + for (var i in o) { + if (o.hasOwnProperty(i)) { + keys.push(i); + } + } + return keys; + }; + })(); + function escapePathComponent(str) { + if (str.indexOf('/') === -1 && str.indexOf('~') === -1) + return str; + return str.replace(/~/g, '~0').replace(/\//g, '~1'); + } + function deepClone(obj) { + if (typeof obj === "object") { + return JSON.parse(JSON.stringify(obj)); + } else { + return obj; + } + } + + // Dirty check if obj is different from mirror, generate patches and update mirror + function _generate(mirror, obj, patches, path) { + var newKeys = _objectKeys(obj); + var oldKeys = _objectKeys(mirror); + var changed = false; + var deleted = false; + + for (var t = oldKeys.length - 1; t >= 0; t--) { + var key = oldKeys[t]; + var oldVal = mirror[key]; + if (obj.hasOwnProperty(key)) { + var newVal = obj[key]; + if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null) { + _generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key)); + } else { + if (oldVal != newVal) { + changed = true; + patches.push({ op: "replace", path: path + "/" + escapePathComponent(key), value: deepClone(newVal) }); + } + } + } else { + patches.push({ op: "remove", path: path + "/" + escapePathComponent(key) }); + deleted = true; // property has been deleted + } + } + + if (!deleted && newKeys.length == oldKeys.length) { + return; + } + + for (var t = 0; t < newKeys.length; t++) { + var key = newKeys[t]; + if (!mirror.hasOwnProperty(key)) { + patches.push({ op: "add", path: path + "/" + escapePathComponent(key), value: deepClone(obj[key]) }); + } + } + } + + function compare(tree1, tree2) { + var patches = []; + _generate(tree1, tree2, patches, ''); + return patches; + } + + return module.exports = compare; +}); \ No newline at end of file diff --git a/app/static/minder/src/tool/key.js b/app/static/minder/src/tool/key.js new file mode 100644 index 0000000..5a403b9 --- /dev/null +++ b/app/static/minder/src/tool/key.js @@ -0,0 +1,69 @@ +define(function(require, exports, module) { + var keymap = require('./keymap'); + + var CTRL_MASK = 0x1000; + var ALT_MASK = 0x2000; + var SHIFT_MASK = 0x4000; + + function hash(unknown) { + if (typeof(unknown) == 'string') { + return hashKeyExpression(unknown); + } + return hashKeyEvent(unknown); + } + function is(a, b) { + return a && b && hash(a) == hash(b); + } + exports.hash = hash; + exports.is = is; + + + function hashKeyEvent(keyEvent) { + var hashCode = 0; + if (keyEvent.ctrlKey || keyEvent.metaKey) { + hashCode |= CTRL_MASK; + } + if (keyEvent.altKey) { + hashCode |= ALT_MASK; + } + if (keyEvent.shiftKey) { + hashCode |= SHIFT_MASK; + } + // Shift, Control, Alt KeyCode ignored. + if ([16, 17, 18, 91].indexOf(keyEvent.keyCode) === -1) { + /** + * 解决浏览器输入法状态下对keyDown的keyCode判断不准确的问题,使用keyIdentifier, + * 可以解决chrome和safari下的各种问题,其他浏览器依旧有问题,然而那并不影响我们对特 + * 需判断的按键进行判断(比如Space在safari输入法态下就是229,其他的就不是) + * @editor Naixor + * @Date 2015-12-2 + */ + if (keyEvent.keyCode === 229 && keyEvent.keyIdentifier) { + return hashCode |= parseInt(keyEvent.keyIdentifier.substr(2), 16); + } + hashCode |= keyEvent.keyCode; + } + return hashCode; + } + + function hashKeyExpression(keyExpression) { + var hashCode = 0; + keyExpression.toLowerCase().split(/\s*\+\s*/).forEach(function(name) { + switch(name) { + case 'ctrl': + case 'cmd': + hashCode |= CTRL_MASK; + break; + case 'alt': + hashCode |= ALT_MASK; + break; + case 'shift': + hashCode |= SHIFT_MASK; + break; + default: + hashCode |= keymap[name]; + } + }); + return hashCode; + } +}); diff --git a/app/static/minder/src/tool/keymap.js b/app/static/minder/src/tool/keymap.js new file mode 100644 index 0000000..0e587da --- /dev/null +++ b/app/static/minder/src/tool/keymap.js @@ -0,0 +1,82 @@ +define(function(require, exports, module) { + var keymap = { + + 'Shift': 16, + 'Control': 17, + 'Alt': 18, + 'CapsLock': 20, + + 'BackSpace': 8, + 'Tab': 9, + 'Enter': 13, + 'Esc': 27, + 'Space': 32, + + 'PageUp': 33, + 'PageDown': 34, + 'End': 35, + 'Home': 36, + + 'Insert': 45, + + 'Left': 37, + 'Up': 38, + 'Right': 39, + 'Down': 40, + + 'Direction': { + 37: 1, + 38: 1, + 39: 1, + 40: 1 + }, + + 'Del': 46, + + 'NumLock': 144, + + 'Cmd': 91, + 'CmdFF': 224, + 'F1': 112, + 'F2': 113, + 'F3': 114, + 'F4': 115, + 'F5': 116, + 'F6': 117, + 'F7': 118, + 'F8': 119, + 'F9': 120, + 'F10': 121, + 'F11': 122, + 'F12': 123, + + '`': 192, + '=': 187, + '-': 189, + + '/': 191, + '.': 190 + }; + + // 小写适配 + for (var key in keymap) { + if (keymap.hasOwnProperty(key)) { + keymap[key.toLowerCase()] = keymap[key]; + } + } + var aKeyCode = 65; + var aCharCode = 'a'.charCodeAt(0); + + // letters + 'abcdefghijklmnopqrstuvwxyz'.split('').forEach(function(letter) { + keymap[letter] = aKeyCode + (letter.charCodeAt(0) - aCharCode); + }); + + // numbers + var n = 9; + do { + keymap[n.toString()] = n + 48; + } while (--n); + + module.exports = keymap; +}); \ No newline at end of file diff --git a/app/static/minder/ui/dialog/hyperlink/hyperlink.ctrl.js b/app/static/minder/ui/dialog/hyperlink/hyperlink.ctrl.js new file mode 100644 index 0000000..74b78c9 --- /dev/null +++ b/app/static/minder/ui/dialog/hyperlink/hyperlink.ctrl.js @@ -0,0 +1,47 @@ +angular.module('kityminderEditor') + .controller('hyperlink.ctrl', function ($scope, $modalInstance, link) { + + var urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$'; + $scope.R_URL = new RegExp(urlRegex, 'i'); + + $scope.url = link.url || ''; + $scope.title = link.title || ''; + + setTimeout(function() { + var $linkUrl = $('#link-url'); + $linkUrl.focus(); + $linkUrl[0].setSelectionRange(0, $scope.url.length); + }, 30); + + $scope.shortCut = function(e) { + e.stopPropagation(); + + if (e.keyCode == 13) { + $scope.ok(); + } else if (e.keyCode == 27) { + $scope.cancel(); + } + }; + + $scope.ok = function () { + if($scope.R_URL.test($scope.url)) { + $modalInstance.close({ + url: $scope.url, + title: $scope.title + }); + } else { + $scope.urlPassed = false; + + var $linkUrl = $('#link-url'); + $linkUrl.focus(); + $linkUrl[0].setSelectionRange(0, $scope.url.length); + } + editor.receiver.selectAll(); + }; + + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + editor.receiver.selectAll(); + }; + + }); \ No newline at end of file diff --git a/app/static/minder/ui/dialog/hyperlink/hyperlink.tpl.html b/app/static/minder/ui/dialog/hyperlink/hyperlink.tpl.html new file mode 100644 index 0000000..bceaa3b --- /dev/null +++ b/app/static/minder/ui/dialog/hyperlink/hyperlink.tpl.html @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/app/static/minder/ui/dialog/imExportNode/imExportNode.ctrl.js b/app/static/minder/ui/dialog/imExportNode/imExportNode.ctrl.js new file mode 100644 index 0000000..61cc67f --- /dev/null +++ b/app/static/minder/ui/dialog/imExportNode/imExportNode.ctrl.js @@ -0,0 +1,95 @@ +angular.module('kityminderEditor') + .controller('imExportNode.ctrl', function ($scope, $modalInstance, title, defaultValue, type) { + + $scope.title = title; + + $scope.value = defaultValue; + + $scope.type = type; + + $scope.ok = function () { + if ($scope.value == '') { + return; + } + $modalInstance.close($scope.value); + editor.receiver.selectAll(); + }; + + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + editor.receiver.selectAll(); + }; + + setTimeout(function() { + $('.single-input').focus(); + + $('.single-input')[0].setSelectionRange(0, defaultValue.length); + + }, 30); + + $scope.shortCut = function(e) { + e.stopPropagation(); + + //if (e.keyCode == 13 && e.shiftKey == false) { + // $scope.ok(); + //} + + if (e.keyCode == 27) { + $scope.cancel(); + } + + // tab 键屏蔽默认事件 和 backspace 键屏蔽默认事件 + if (e.keyCode == 8 && type == 'export') { + e.preventDefault(); + } + + if (e.keyCode == 9) { + e.preventDefault(); + var $textarea = e.target; + var pos = getCursortPosition($textarea); + var str = $textarea.value; + $textarea.value = str.substr(0, pos) + '\t' + str.substr(pos); + setCaretPosition($textarea, pos + 1); + } + + }; + + /* + * 获取 textarea 的光标位置 + * @Author: Naixor + * @date: 2015.09.23 + * */ + function getCursortPosition (ctrl) { + var CaretPos = 0; // IE Support + if (document.selection) { + ctrl.focus (); + var Sel = document.selection.createRange (); + Sel.moveStart ('character', -ctrl.value.length); + CaretPos = Sel.text.length; + } + // Firefox support + else if (ctrl.selectionStart || ctrl.selectionStart == '0') { + CaretPos = ctrl.selectionStart; + } + return (CaretPos); + } + + /* + * 设置 textarea 的光标位置 + * @Author: Naixor + * @date: 2015.09.23 + * */ + function setCaretPosition(ctrl, pos){ + if(ctrl.setSelectionRange) { + ctrl.focus(); + ctrl.setSelectionRange(pos,pos); + } else if (ctrl.createTextRange) { + var range = ctrl.createTextRange(); + range.collapse(true); + range.moveEnd('character', pos); + range.moveStart('character', pos); + range.select(); + } + } + + }); \ No newline at end of file diff --git a/app/static/minder/ui/dialog/imExportNode/imExportNode.tpl.html b/app/static/minder/ui/dialog/imExportNode/imExportNode.tpl.html new file mode 100644 index 0000000..6c68b28 --- /dev/null +++ b/app/static/minder/ui/dialog/imExportNode/imExportNode.tpl.html @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/app/static/minder/ui/dialog/image/image.ctrl.js b/app/static/minder/ui/dialog/image/image.ctrl.js new file mode 100644 index 0000000..ff09701 --- /dev/null +++ b/app/static/minder/ui/dialog/image/image.ctrl.js @@ -0,0 +1,114 @@ +angular.module('kityminderEditor') + .controller('image.ctrl', ['$http', '$scope', '$modalInstance', 'image', 'server', function($http, $scope, $modalInstance, image, server) { + + $scope.data = { + list: [], + url: image.url || '', + title: image.title || '', + R_URL: /^https?\:\/\/\w+/ + }; + + setTimeout(function() { + var $imageUrl = $('#image-url'); + $imageUrl.focus(); + $imageUrl[0].setSelectionRange(0, $scope.data.url.length); + }, 300); + + + // 搜索图片按钮点击事件 + $scope.searchImage = function() { + $scope.list = []; + + getImageData() + .success(function(json) { + if(json && json.data) { + for(var i = 0; i < json.data.length; i++) { + if(json.data[i].objURL) { + $scope.list.push({ + title: json.data[i].fromPageTitleEnc, + src: json.data[i].middleURL, + url: json.data[i].middleURL + }); + } + } + } + }) + .error(function() { + + }); + }; + + // 选择图片的鼠标点击事件 + $scope.selectImage = function($event) { + var targetItem = $('#img-item'+ (this.$index)); + var targetImg = $('#img-'+ (this.$index)); + + targetItem.siblings('.selected').removeClass('selected'); + targetItem.addClass('selected'); + + $scope.data.url = targetImg.attr('src'); + $scope.data.title = targetImg.attr('alt'); + }; + + // 自动上传图片,后端需要直接返回图片 URL + $scope.uploadImage = function() { + var fileInput = $('#upload-image'); + if (!fileInput.val()) { + return; + } + if (/^.*\.(jpg|JPG|jpeg|JPEG|gif|GIF|png|PNG)$/.test(fileInput.val())) { + var file = fileInput[0].files[0]; + return server.uploadImage(file).then(function (json) { + var resp = json.data; + if (resp.errno === 0) { + $scope.data.url = resp.data.url; + } + }); + } else { + alert("后缀只能是 jpg、gif 及 png"); + } + }; + + $scope.shortCut = function(e) { + e.stopPropagation(); + + if (e.keyCode == 13) { + $scope.ok(); + } else if (e.keyCode == 27) { + $scope.cancel(); + } + }; + + $scope.ok = function () { + if($scope.data.R_URL.test($scope.data.url)) { + $modalInstance.close({ + url: $scope.data.url, + title: $scope.data.title + }); + } else { + $scope.urlPassed = false; + + var $imageUrl = $('#image-url'); + if ($imageUrl) { + $imageUrl.focus(); + $imageUrl[0].setSelectionRange(0, $scope.data.url.length); + } + + } + + editor.receiver.selectAll(); + }; + + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + editor.receiver.selectAll(); + }; + + function getImageData() { + var key = $scope.data.searchKeyword2; + var currentTime = new Date(); + var url = 'http://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&fp=result&queryWord='+ key +'&cl=2&lm=-1&ie=utf-8&oe=utf-8&st=-1&ic=0&word='+ key +'&face=0&istype=2&nc=1&pn=60&rn=60&gsm=3c&'+ currentTime.getTime() +'=&callback=JSON_CALLBACK'; + + return $http.jsonp(url); + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/dialog/image/image.tpl.html b/app/static/minder/ui/dialog/image/image.tpl.html new file mode 100644 index 0000000..45ba66a --- /dev/null +++ b/app/static/minder/ui/dialog/image/image.tpl.html @@ -0,0 +1,69 @@ + + + \ No newline at end of file diff --git a/app/static/minder/ui/directive/appendNode/appendNode.directive.js b/app/static/minder/ui/directive/appendNode/appendNode.directive.js new file mode 100644 index 0000000..3152b82 --- /dev/null +++ b/app/static/minder/ui/directive/appendNode/appendNode.directive.js @@ -0,0 +1,31 @@ +angular.module('kityminderEditor') + .directive('appendNode', ['commandBinder', function(commandBinder) { + return { + restrict: 'E', + templateUrl: 'ui/directive/appendNode/appendNode.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + var minder = $scope.minder; + + commandBinder.bind(minder, 'appendchildnode', $scope) + + $scope.execCommand = function(command) { + minder.execCommand(command, '分支主题'); + editText(); + }; + + function editText() { + var receiverElement = editor.receiver.element; + var fsm = editor.fsm; + var receiver = editor.receiver; + + receiverElement.innerText = minder.queryCommandValue('text'); + fsm.jump('input', 'input-request'); + receiver.selectAll(); + } + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/appendNode/appendNode.html b/app/static/minder/ui/directive/appendNode/appendNode.html new file mode 100644 index 0000000..faabac7 --- /dev/null +++ b/app/static/minder/ui/directive/appendNode/appendNode.html @@ -0,0 +1,23 @@ +
+
+ + {{ 'appendchildnode' | lang:'ui/command' }} +
+
+ + {{ 'appendparentnode' | lang:'ui/command' }} +
+
+ + {{ 'appendsiblingnode' | lang:'ui/command' }} +
+
\ No newline at end of file diff --git a/app/static/minder/ui/directive/arrange/arrange.directive.js b/app/static/minder/ui/directive/arrange/arrange.directive.js new file mode 100644 index 0000000..c64bdae --- /dev/null +++ b/app/static/minder/ui/directive/arrange/arrange.directive.js @@ -0,0 +1,16 @@ +angular.module('kityminderEditor') + .directive('arrange', ['commandBinder', function(commandBinder) { + return { + restrict: 'E', + templateUrl: 'ui/directive/arrange/arrange.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + var minder = $scope.minder; + + //commandBinder.bind(minder, 'priority', $scope); + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/arrange/arrange.html b/app/static/minder/ui/directive/arrange/arrange.html new file mode 100644 index 0000000..d3483ff --- /dev/null +++ b/app/static/minder/ui/directive/arrange/arrange.html @@ -0,0 +1,16 @@ +
+
+ + {{ 'arrangeup' | lang:'ui/command' }} +
+
+ + {{ 'arrangedown' | lang:'ui/command' }} +
+
\ No newline at end of file diff --git a/app/static/minder/ui/directive/colorPanel/colorPanel.directive.js b/app/static/minder/ui/directive/colorPanel/colorPanel.directive.js new file mode 100644 index 0000000..5ccf7af --- /dev/null +++ b/app/static/minder/ui/directive/colorPanel/colorPanel.directive.js @@ -0,0 +1,33 @@ +angular.module('kityminderEditor') + .directive('colorPanel', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/colorPanel/colorPanel.html', + scope: { + minder: '=' + }, + replace: true, + link: function(scope) { + + var minder = scope.minder; + var currentTheme = minder.getThemeItems(); + + scope.$on('colorPicked', function(event, color) { + event.stopPropagation(); + scope.bgColor = color; + minder.execCommand('background', color); + }); + + scope.setDefaultBg = function() { + var currentNode = minder.getSelectedNode(); + var bgColor = minder.getNodeStyle(currentNode, 'background'); + + // 有可能是 kity 的颜色类 + return typeof bgColor === 'object' ? bgColor.toHEX() : bgColor; + }; + + scope.bgColor = scope.setDefaultBg() || '#fff'; + + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/colorPanel/colorPanel.html b/app/static/minder/ui/directive/colorPanel/colorPanel.html new file mode 100644 index 0000000..9f79983 --- /dev/null +++ b/app/static/minder/ui/directive/colorPanel/colorPanel.html @@ -0,0 +1,16 @@ +
+ + + + + + +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/expandLevel/expandLevel.directive.js b/app/static/minder/ui/directive/expandLevel/expandLevel.directive.js new file mode 100644 index 0000000..0d41bc2 --- /dev/null +++ b/app/static/minder/ui/directive/expandLevel/expandLevel.directive.js @@ -0,0 +1,15 @@ +angular.module('kityminderEditor') + .directive('expandLevel', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/expandLevel/expandLevel.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + + $scope.levels = [1, 2, 3, 4, 5, 6]; + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/expandLevel/expandLevel.html b/app/static/minder/ui/directive/expandLevel/expandLevel.html new file mode 100644 index 0000000..31dda83 --- /dev/null +++ b/app/static/minder/ui/directive/expandLevel/expandLevel.html @@ -0,0 +1,21 @@ +
+ + + +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/fontOperator/fontOperator.directive.js b/app/static/minder/ui/directive/fontOperator/fontOperator.directive.js new file mode 100644 index 0000000..25f720d --- /dev/null +++ b/app/static/minder/ui/directive/fontOperator/fontOperator.directive.js @@ -0,0 +1,83 @@ +angular.module('kityminderEditor') + .directive('fontOperator', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/fontOperator/fontOperator.html', + scope: { + minder: '=' + }, + replace: true, + link: function(scope) { + var minder = scope.minder; + var currentTheme = minder.getThemeItems(); + + scope.fontSizeList = [10, 12, 16, 18, 24, 32, 48]; + scope.fontFamilyList = [{ + name: '宋体', + val: '宋体,SimSun' + }, { + name: '微软雅黑', + val: '微软雅黑,Microsoft YaHei' + }, { + name: '楷体', + val: '楷体,楷体_GB2312,SimKai' + }, { + name: '黑体', + val: '黑体, SimHei' + }, { + name: '隶书', + val: '隶书, SimLi' + }, { + name: 'Andale Mono', + val: 'andale mono' + }, { + name: 'Arial', + val: 'arial,helvetica,sans-serif' + }, { + name: 'arialBlack', + val: 'arial black,avant garde' + }, { + name: 'Comic Sans Ms', + val: 'comic sans ms' + }, { + name: 'Impact', + val: 'impact,chicago' + }, { + name: 'Times New Roman', + val: 'times new roman' + }, { + name: 'Sans-Serif', + val: 'sans-serif' + }]; + + scope.$on('colorPicked', function(event, color) { + event.stopPropagation(); + + scope.foreColor = color; + minder.execCommand('forecolor', color); + }); + + scope.setDefaultColor = function() { + var currentNode = minder.getSelectedNode(); + var fontColor = minder.getNodeStyle(currentNode, 'color'); + + // 有可能是 kity 的颜色类 + return typeof fontColor === 'object' ? fontColor.toHEX() : fontColor; + }; + + scope.foreColor = scope.setDefaultColor() || '#000'; + + scope.getFontfamilyName = function(val) { + var fontName = ''; + scope.fontFamilyList.forEach(function(ele, idx, arr) { + if (ele.val === val) { + fontName = ele.name; + return ''; + } + }); + + return fontName; + } + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/fontOperator/fontOperator.html b/app/static/minder/ui/directive/fontOperator/fontOperator.html new file mode 100644 index 0000000..4ae0cf8 --- /dev/null +++ b/app/static/minder/ui/directive/fontOperator/fontOperator.html @@ -0,0 +1,51 @@ + diff --git a/app/static/minder/ui/directive/hyperLink/hyperLink.directive.js b/app/static/minder/ui/directive/hyperLink/hyperLink.directive.js new file mode 100644 index 0000000..70cee0d --- /dev/null +++ b/app/static/minder/ui/directive/hyperLink/hyperLink.directive.js @@ -0,0 +1,35 @@ +angular.module('kityminderEditor') + .directive('hyperLink', ['$modal', function($modal) { + return { + restrict: 'E', + templateUrl: 'ui/directive/hyperLink/hyperLink.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + var minder = $scope.minder; + + $scope.addHyperlink = function() { + + var link = minder.queryCommandValue('HyperLink'); + + var hyperlinkModal = $modal.open({ + animation: true, + templateUrl: 'ui/dialog/hyperlink/hyperlink.tpl.html', + controller: 'hyperlink.ctrl', + size: 'md', + resolve: { + link: function() { + return link; + } + } + }); + + hyperlinkModal.result.then(function(result) { + minder.execCommand('HyperLink', result.url, result.title || ''); + }); + } + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/hyperLink/hyperLink.html b/app/static/minder/ui/directive/hyperLink/hyperLink.html new file mode 100644 index 0000000..4e4b66d --- /dev/null +++ b/app/static/minder/ui/directive/hyperLink/hyperLink.html @@ -0,0 +1,27 @@ +
+ + + +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/imageBtn/imageBtn.directive.js b/app/static/minder/ui/directive/imageBtn/imageBtn.directive.js new file mode 100644 index 0000000..71a435a --- /dev/null +++ b/app/static/minder/ui/directive/imageBtn/imageBtn.directive.js @@ -0,0 +1,35 @@ +angular.module('kityminderEditor') + .directive('imageBtn', ['$modal', function($modal) { + return { + restrict: 'E', + templateUrl: 'ui/directive/imageBtn/imageBtn.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + var minder = $scope.minder; + + $scope.addImage = function() { + + var image = minder.queryCommandValue('image'); + + var imageModal = $modal.open({ + animation: true, + templateUrl: 'ui/dialog/image/image.tpl.html', + controller: 'image.ctrl', + size: 'md', + resolve: { + image: function() { + return image; + } + } + }); + + imageModal.result.then(function(result) { + minder.execCommand('image', result.url, result.title || ''); + }); + } + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/imageBtn/imageBtn.html b/app/static/minder/ui/directive/imageBtn/imageBtn.html new file mode 100644 index 0000000..1350ed3 --- /dev/null +++ b/app/static/minder/ui/directive/imageBtn/imageBtn.html @@ -0,0 +1,27 @@ +
+ + + +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/kityminderEditor/kityminderEditor.directive.js b/app/static/minder/ui/directive/kityminderEditor/kityminderEditor.directive.js new file mode 100644 index 0000000..751b62c --- /dev/null +++ b/app/static/minder/ui/directive/kityminderEditor/kityminderEditor.directive.js @@ -0,0 +1,71 @@ +angular.module('kityminderEditor') + .directive('kityminderEditor', ['config', 'minder.service', 'revokeDialog', function(config, minderService, revokeDialog) { + return { + restrict: 'EA', + templateUrl: 'ui/directive/kityminderEditor/kityminderEditor.html', + replace: true, + scope: { + onInit: '&' + }, + link: function(scope, element, attributes) { + + var $minderEditor = element.children('.minder-editor')[0]; + + function onInit(editor, minder) { + scope.onInit({ + editor: editor, + minder: minder + }); + + minderService.executeCallback(); + } + + if (typeof(seajs) != 'undefined') { + /* global seajs */ + seajs.config({ + base: './src' + }); + + define('demo', function(require) { + var Editor = require('editor'); + + var editor = window.editor = new Editor($minderEditor); + + if (window.localStorage.__dev_minder_content) { + editor.minder.importJson(JSON.parse(window.localStorage.__dev_minder_content)); + } + + editor.minder.on('contentchange', function() { + window.localStorage.__dev_minder_content = JSON.stringify(editor.minder.exportJson()); + }); + + window.minder = window.km = editor.minder; + + scope.editor = editor; + scope.minder = minder; + scope.config = config.get(); + + //scope.minder.setDefaultOptions(scope.config); + scope.$apply(); + + onInit(editor, minder); + }); + + seajs.use('demo'); + + } else if (window.kityminder && window.kityminder.Editor) { + var editor = new kityminder.Editor($minderEditor); + + window.editor = scope.editor = editor; + window.minder = scope.minder = editor.minder; + + scope.config = config.get(); + + //scope.minder.setDefaultOptions(config.getConfig()); + + onInit(editor, editor.minder); + } + + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/kityminderEditor/kityminderEditor.html b/app/static/minder/ui/directive/kityminderEditor/kityminderEditor.html new file mode 100644 index 0000000..86f05e2 --- /dev/null +++ b/app/static/minder/ui/directive/kityminderEditor/kityminderEditor.html @@ -0,0 +1,8 @@ +
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/kityminderViewer/kityminderViewer.directive.js b/app/static/minder/ui/directive/kityminderViewer/kityminderViewer.directive.js new file mode 100644 index 0000000..e77c30b --- /dev/null +++ b/app/static/minder/ui/directive/kityminderViewer/kityminderViewer.directive.js @@ -0,0 +1,34 @@ +angular.module('kityminderEditor') + .directive('kityminderViewer', ['config', 'minder.service', function(config, minderService) { + return { + restrict: 'EA', + templateUrl: 'ui/directive/kityminderViewer/kityminderViewer.html', + replace: true, + scope: { + onInit: '&' + }, + link: function(scope, element, attributes) { + + var $minderEditor = element.children('.minder-viewer')[0]; + + function onInit(editor, minder) { + scope.onInit({ + editor: editor, + minder: minder + }); + + minderService.executeCallback(); + } + + if (window.kityminder && window.kityminder.Editor) { + var editor = new kityminder.Editor($minderEditor); + + window.editor = scope.editor = editor; + window.minder = scope.minder = editor.minder; + + onInit(editor, editor.minder); + } + + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/kityminderViewer/kityminderViewer.html b/app/static/minder/ui/directive/kityminderViewer/kityminderViewer.html new file mode 100644 index 0000000..47f672a --- /dev/null +++ b/app/static/minder/ui/directive/kityminderViewer/kityminderViewer.html @@ -0,0 +1,5 @@ +
+
+
+ +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/layout/layout.directive.js b/app/static/minder/ui/directive/layout/layout.directive.js new file mode 100644 index 0000000..5351cb9 --- /dev/null +++ b/app/static/minder/ui/directive/layout/layout.directive.js @@ -0,0 +1,14 @@ +angular.module('kityminderEditor') + .directive('layout', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/layout/layout.html', + scope: { + minder: '=' + }, + replace: true, + link: function(scope) { + + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/layout/layout.html b/app/static/minder/ui/directive/layout/layout.html new file mode 100644 index 0000000..04c9e51 --- /dev/null +++ b/app/static/minder/ui/directive/layout/layout.html @@ -0,0 +1,6 @@ + diff --git a/app/static/minder/ui/directive/navigator/navigator.directive.js b/app/static/minder/ui/directive/navigator/navigator.directive.js new file mode 100644 index 0000000..1f387ee --- /dev/null +++ b/app/static/minder/ui/directive/navigator/navigator.directive.js @@ -0,0 +1,221 @@ +/** + * @fileOverview + * + * 左下角的导航器 + * + * @author: zhangbobell + * @email : zhangbobell@163.com + * + * @copyright: Baidu FEX, 2015 */ +angular.module('kityminderEditor') + .directive('navigator', ['memory', 'config', function(memory, config) { + return { + restrict: 'A', + templateUrl: 'ui/directive/navigator/navigator.html', + scope: { + minder: '=' + }, + link: function(scope) { + minder.setDefaultOptions({zoom: config.get('zoom')}); + + scope.isNavOpen = !memory.get('navigator-hidden'); + + scope.getZoomRadio = function(value) { + var zoomStack = minder.getOption('zoom'); + var minValue = zoomStack[0]; + var maxValue = zoomStack[zoomStack.length - 1]; + var valueRange = maxValue - minValue; + + return (1 - (value - minValue) / valueRange); + }; + + scope.getHeight = function(value) { + var totalHeight = $('.zoom-pan').height(); + + return scope.getZoomRadio(value) * totalHeight; + }; + + // 初始的缩放倍数 + scope.zoom = 100; + + // 发生缩放事件时 + minder.on('zoom', function(e) { + scope.zoom = e.zoom; + }); + + scope.toggleNavOpen = function() { + scope.isNavOpen = !scope.isNavOpen; + memory.set('navigator-hidden', !scope.isNavOpen); + + if (scope.isNavOpen) { + bind(); + updateContentView(); + updateVisibleView(); + } else{ + unbind(); + } + }; + + setTimeout(function() { + if (scope.isNavOpen) { + bind(); + updateContentView(); + updateVisibleView(); + } else{ + unbind(); + } + }, 0); + + + + function bind() { + minder.on('layout layoutallfinish', updateContentView); + minder.on('viewchange', updateVisibleView); + } + + function unbind() { + minder.off('layout layoutallfinish', updateContentView); + minder.off('viewchange', updateVisibleView); + } + + + /** 以下部分是缩略图导航器 * + * */ + + var $previewNavigator = $('.nav-previewer'); + + // 画布,渲染缩略图 + var paper = new kity.Paper($previewNavigator[0]); + + // 用两个路径来挥之节点和连线的缩略图 + var nodeThumb = paper.put(new kity.Path()); + var connectionThumb = paper.put(new kity.Path()); + + // 表示可视区域的矩形 + var visibleRect = paper.put(new kity.Rect(100, 100).stroke('red', '1%')); + + var contentView = new kity.Box(), visibleView = new kity.Box(); + + /** + * 增加一个对天盘图情况缩略图的处理, + * @Editor: Naixor line 104~129 + * @Date: 2015.11.3 + */ + var pathHandler = getPathHandler(minder.getTheme()); + + // 主题切换事件 + minder.on('themechange', function(e) { + pathHandler = getPathHandler(e.theme); + }); + + function getPathHandler(theme) { + switch (theme) { + case "tianpan": + case "tianpan-compact": + return function(nodePathData, x, y, width, height) { + var r = width >> 1; + nodePathData.push('M', x, y + r, + 'a', r, r, 0, 1, 1, 0, 0.01, + 'z'); + } + default: { + return function(nodePathData, x, y, width, height) { + nodePathData.push('M', x, y, + 'h', width, 'v', height, + 'h', -width, 'z'); + } + } + } + } + + navigate(); + + function navigate() { + + function moveView(center, duration) { + var box = visibleView; + center.x = -center.x; + center.y = -center.y; + + var viewMatrix = minder.getPaper().getViewPortMatrix(); + box = viewMatrix.transformBox(box); + + var targetPosition = center.offset(box.width / 2, box.height / 2); + + minder.getViewDragger().moveTo(targetPosition, duration); + } + + var dragging = false; + + paper.on('mousedown', function(e) { + dragging = true; + moveView(e.getPosition('top'), 200); + $previewNavigator.addClass('grab'); + }); + + paper.on('mousemove', function(e) { + if (dragging) { + moveView(e.getPosition('top')); + } + }); + + $(window).on('mouseup', function() { + dragging = false; + $previewNavigator.removeClass('grab'); + }); + } + + function updateContentView() { + + var view = minder.getRenderContainer().getBoundaryBox(); + + contentView = view; + + var padding = 30; + + paper.setViewBox( + view.x - padding - 0.5, + view.y - padding - 0.5, + view.width + padding * 2 + 1, + view.height + padding * 2 + 1); + + var nodePathData = []; + var connectionThumbData = []; + + minder.getRoot().traverse(function(node) { + var box = node.getLayoutBox(); + pathHandler(nodePathData, box.x, box.y, box.width, box.height); + if (node.getConnection() && node.parent && node.parent.isExpanded()) { + connectionThumbData.push(node.getConnection().getPathData()); + } + }); + + paper.setStyle('background', minder.getStyle('background')); + + if (nodePathData.length) { + nodeThumb + .fill(minder.getStyle('root-background')) + .setPathData(nodePathData); + } else { + nodeThumb.setPathData(null); + } + + if (connectionThumbData.length) { + connectionThumb + .stroke(minder.getStyle('connect-color'), '0.5%') + .setPathData(connectionThumbData); + } else { + connectionThumb.setPathData(null); + } + + updateVisibleView(); + } + + function updateVisibleView() { + visibleView = minder.getViewDragger().getView(); + visibleRect.setBox(visibleView.intersect(contentView)); + } + + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/navigator/navigator.html b/app/static/minder/ui/directive/navigator/navigator.html new file mode 100644 index 0000000..db6af0b --- /dev/null +++ b/app/static/minder/ui/directive/navigator/navigator.html @@ -0,0 +1,42 @@ + + \ No newline at end of file diff --git a/app/static/minder/ui/directive/noteBtn/noteBtn.directive.js b/app/static/minder/ui/directive/noteBtn/noteBtn.directive.js new file mode 100644 index 0000000..1a86e78 --- /dev/null +++ b/app/static/minder/ui/directive/noteBtn/noteBtn.directive.js @@ -0,0 +1,18 @@ +angular.module('kityminderEditor') + .directive('noteBtn', ['valueTransfer', function(valueTransfer) { + return { + restrict: 'E', + templateUrl: 'ui/directive/noteBtn/noteBtn.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + var minder = $scope.minder; + + $scope.addNote =function() { + valueTransfer.noteEditorOpen = true; + }; + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/noteBtn/noteBtn.html b/app/static/minder/ui/directive/noteBtn/noteBtn.html new file mode 100644 index 0000000..02ba67d --- /dev/null +++ b/app/static/minder/ui/directive/noteBtn/noteBtn.html @@ -0,0 +1,27 @@ +
+ + + +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/noteEditor/noteEditor.directive.js b/app/static/minder/ui/directive/noteEditor/noteEditor.directive.js new file mode 100644 index 0000000..2d12de3 --- /dev/null +++ b/app/static/minder/ui/directive/noteEditor/noteEditor.directive.js @@ -0,0 +1,76 @@ +angular.module('kityminderEditor') + + .directive('noteEditor', ['valueTransfer', function(valueTransfer) { + return { + restrict: 'A', + templateUrl: 'ui/directive/noteEditor/noteEditor.html', + scope: { + minder: '=' + }, + replace: true, + controller: function($scope) { + var minder = $scope.minder; + var isInteracting = false; + var cmEditor; + + $scope.codemirrorLoaded = function(_editor) { + + cmEditor = $scope.cmEditor = _editor; + + _editor.setSize('100%', '100%'); + }; + + function updateNote() { + var enabled = $scope.noteEnabled = minder.queryCommandState('note') != -1; + var noteValue = minder.queryCommandValue('note') || ''; + + if (enabled) { + $scope.noteContent = noteValue; + } + + isInteracting = true; + $scope.$apply(); + isInteracting = false; + } + + + $scope.$watch('noteContent', function(content) { + var enabled = minder.queryCommandState('note') != -1; + + if (content && enabled && !isInteracting) { + minder.execCommand('note', content); + } + + setTimeout(function() { + cmEditor.refresh(); + }); + }); + + + var noteEditorOpen = function() { + return valueTransfer.noteEditorOpen; + }; + + // 监听面板状态变量的改变 + $scope.$watch(noteEditorOpen, function(newVal, oldVal) { + if (newVal) { + setTimeout(function() { + cmEditor.refresh(); + cmEditor.focus(); + }); + } + $scope.noteEditorOpen = valueTransfer.noteEditorOpen; + }, true); + + + $scope.closeNoteEditor = function() { + valueTransfer.noteEditorOpen = false; + editor.receiver.selectAll(); + }; + + + + minder.on('interactchange', updateNote); + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/noteEditor/noteEditor.html b/app/static/minder/ui/directive/noteEditor/noteEditor.html new file mode 100644 index 0000000..d0b4c68 --- /dev/null +++ b/app/static/minder/ui/directive/noteEditor/noteEditor.html @@ -0,0 +1,24 @@ +
+
+

备注

+ 支持 GFM 语法书写 + +
+
+
+
+

+ 请选择节点编辑备注 +

+
+
\ No newline at end of file diff --git a/app/static/minder/ui/directive/notePreviewer/notePreviewer.directive.js b/app/static/minder/ui/directive/notePreviewer/notePreviewer.directive.js new file mode 100644 index 0000000..75d8d87 --- /dev/null +++ b/app/static/minder/ui/directive/notePreviewer/notePreviewer.directive.js @@ -0,0 +1,94 @@ +// TODO: 使用一个 div 容器作为 previewer,而不是两个 +angular.module('kityminderEditor') + + .directive('notePreviewer', ['$sce', 'valueTransfer', function($sce, valueTransfer) { + return { + restrict: 'A', + templateUrl: 'ui/directive/notePreviewer/notePreviewer.html', + link: function(scope, element) { + var minder = scope.minder; + var $container = element.parent(); + var $previewer = element.children(); + scope.showNotePreviewer = false; + + marked.setOptions({ + gfm: true, + tables: true, + breaks: true, + pedantic: false, + sanitize: true, + smartLists: true, + smartypants: false + }); + + + var previewTimer; + minder.on('shownoterequest', function(e) { + + previewTimer = setTimeout(function() { + preview(e.node, e.keyword); + }, 300); + }); + minder.on('hidenoterequest', function() { + clearTimeout(previewTimer); + + scope.showNotePreviewer = false; + //scope.$apply(); + }); + + var previewLive = false; + $(document).on('mousedown mousewheel DOMMouseScroll', function() { + if (!previewLive) return; + scope.showNotePreviewer = false; + scope.$apply(); + }); + + element.on('mousedown mousewheel DOMMouseScroll', function(e) { + e.stopPropagation(); + }); + + function preview(node, keyword) { + var icon = node.getRenderer('NoteIconRenderer').getRenderShape(); + var b = icon.getRenderBox('screen'); + var note = node.getData('note'); + + $previewer[0].scrollTop = 0; + + var html = marked(note); + if (keyword) { + html = html.replace(new RegExp('(' + keyword + ')', 'ig'), '$1'); + } + scope.noteContent = $sce.trustAsHtml(html); + scope.$apply(); // 让浏览器重新渲染以获取 previewer 提示框的尺寸 + + var cw = $($container[0]).width(); + var ch = $($container[0]).height(); + var pw = $($previewer).outerWidth(); + var ph = $($previewer).outerHeight(); + + var x = b.cx - pw / 2 - $container[0].offsetLeft; + var y = b.bottom + 10 - $container[0].offsetTop; + + if (x < 0) x = 10; + if (x + pw > cw) x = b.left - pw - 10 - $container[0].offsetLeft; + if (y + ph > ch) y = b.top - ph - 10 - $container[0].offsetTop; + + + scope.previewerStyle = { + 'left': Math.round(x) + 'px', + 'top': Math.round(y) + 'px' + }; + + scope.showNotePreviewer = true; + + var view = $previewer[0].querySelector('.highlight'); + if (view) { + view.scrollIntoView(); + } + previewLive = true; + + scope.$apply(); + } + } + } +}]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/notePreviewer/notePreviewer.html b/app/static/minder/ui/directive/notePreviewer/notePreviewer.html new file mode 100644 index 0000000..83ad700 --- /dev/null +++ b/app/static/minder/ui/directive/notePreviewer/notePreviewer.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/operation/operation.directive.js b/app/static/minder/ui/directive/operation/operation.directive.js new file mode 100644 index 0000000..13d96e5 --- /dev/null +++ b/app/static/minder/ui/directive/operation/operation.directive.js @@ -0,0 +1,25 @@ +angular.module('kityminderEditor') + .directive('operation', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/operation/operation.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + $scope.editNode = function() { + + var receiverElement = editor.receiver.element; + var fsm = editor.fsm; + var receiver = editor.receiver; + + receiverElement.innerText = minder.queryCommandValue('text'); + fsm.jump('input', 'input-request'); + receiver.selectAll(); + + } + + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/operation/operation.html b/app/static/minder/ui/directive/operation/operation.html new file mode 100644 index 0000000..f737b99 --- /dev/null +++ b/app/static/minder/ui/directive/operation/operation.html @@ -0,0 +1,16 @@ +
+
+ + {{ 'editnode' | lang:'ui/command' }} +
+
+ + {{ 'removenode' | lang:'ui/command' }} +
+
diff --git a/app/static/minder/ui/directive/priorityEditor/priorityEditor.directive.js b/app/static/minder/ui/directive/priorityEditor/priorityEditor.directive.js new file mode 100644 index 0000000..5d7ef6a --- /dev/null +++ b/app/static/minder/ui/directive/priorityEditor/priorityEditor.directive.js @@ -0,0 +1,32 @@ +angular.module('kityminderEditor') + + .directive('priorityEditor', ['commandBinder', function(commandBinder) { + return { + restrict: 'E', + templateUrl: 'ui/directive/priorityEditor/priorityEditor.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + var minder = $scope.minder; + var priorities = []; + + for (var i = 0; i < 10; i++) { + priorities.push(i); + } + + commandBinder.bind(minder, 'priority', $scope); + + $scope.priorities = priorities; + + $scope.getPriorityTitle = function(p) { + switch(p) { + case 0: return '移除优先级'; + default: return '优先级' + p; + } + } + } + + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/priorityEditor/priorityEditor.html b/app/static/minder/ui/directive/priorityEditor/priorityEditor.html new file mode 100644 index 0000000..e97bacd --- /dev/null +++ b/app/static/minder/ui/directive/priorityEditor/priorityEditor.html @@ -0,0 +1,9 @@ +
    +
  • +
    +
  • +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/progressEditor/progressEditor.directive.js b/app/static/minder/ui/directive/progressEditor/progressEditor.directive.js new file mode 100644 index 0000000..cd5007c --- /dev/null +++ b/app/static/minder/ui/directive/progressEditor/progressEditor.directive.js @@ -0,0 +1,33 @@ +angular.module('kityminderEditor') + .directive('progressEditor', ['commandBinder', function(commandBinder) { + return { + restrict: 'E', + templateUrl: 'ui/directive/progressEditor/progressEditor.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + var minder = $scope.minder; + var progresses = []; + + for (var i = 0; i < 10; i++) { + progresses.push(i); + } + + commandBinder.bind(minder, 'progress', $scope); + + $scope.progresses = progresses; + + $scope.getProgressTitle = function(p) { + switch(p) { + case 0: return '移除进度'; + case 1: return '未开始'; + case 9: return '全部完成'; + default: return '完成' + (p - 1) + '/8'; + + } + } + } + } + }]) \ No newline at end of file diff --git a/app/static/minder/ui/directive/progressEditor/progressEditor.html b/app/static/minder/ui/directive/progressEditor/progressEditor.html new file mode 100644 index 0000000..c2c4240 --- /dev/null +++ b/app/static/minder/ui/directive/progressEditor/progressEditor.html @@ -0,0 +1,9 @@ +
    +
  • +
    +
  • +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/resourceEditor/resourceEditor.directive.js b/app/static/minder/ui/directive/resourceEditor/resourceEditor.directive.js new file mode 100644 index 0000000..5ba3afc --- /dev/null +++ b/app/static/minder/ui/directive/resourceEditor/resourceEditor.directive.js @@ -0,0 +1,91 @@ +angular.module('kityminderEditor') + .directive('resourceEditor', function () { + return { + restrict: 'E', + templateUrl: 'ui/directive/resourceEditor/resourceEditor.html', + scope: { + minder: '=' + }, + replace: true, + controller: function ($scope) { + var minder = $scope.minder; + + var isInteracting = false; + + minder.on('interactchange', function () { + var enabled = $scope.enabled = minder.queryCommandState('resource') != -1; + var selected = enabled ? minder.queryCommandValue('resource') : []; + var used = minder.getUsedResource().map(function (resourceName) { + return { + name: resourceName, + selected: selected.indexOf(resourceName) > -1 + } + }); + $scope.used = used; + + isInteracting = true; + $scope.$apply(); + isInteracting = false; + }); + + $scope.$watch('used', function (used) { + if (minder.queryCommandState('resource') != -1 && used) { + var resource = used.filter(function (resource) { + return resource.selected; + }).map(function (resource) { + return resource.name; + }); + + // 由于 interactchange 带来的改变则不用执行 resource 命令 + if (isInteracting) { + return; + } + minder.execCommand('resource', resource); + } + }, true); + + $scope.resourceColor = function (resource) { + return minder.getResourceColor(resource).toHEX(); + }; + + $scope.addResource = function (resourceName) { + var origin = minder.queryCommandValue('resource'); + if (!resourceName || !/\S/.test(resourceName)) return; + + if (origin.indexOf(resourceName) == -1) { + $scope.used.push({ + name: resourceName, + selected: true + }); + } + + $scope.newResourceName = null; + }; + + } + }; + }) + + .directive('clickAnywhereButHere', ['$document', function ($document) { + return { + link: function(scope, element, attrs) { + var onClick = function (event) { + var isChild = $('#resource-dropdown').has(event.target).length > 0; + var isSelf = $('#resource-dropdown') == event.target; + var isInside = isChild || isSelf; + if (!isInside) { + scope.$apply(attrs.clickAnywhereButHere) + } + }; + + scope.$watch(attrs.isActive, function(newValue, oldValue) { + if (newValue !== oldValue && newValue == true) { + $document.bind('click', onClick); + } + else if (newValue !== oldValue && newValue == false) { + $document.unbind('click', onClick); + } + }); + } + }; + }]); \ No newline at end of file diff --git a/app/static/minder/ui/directive/resourceEditor/resourceEditor.html b/app/static/minder/ui/directive/resourceEditor/resourceEditor.html new file mode 100644 index 0000000..e4803a1 --- /dev/null +++ b/app/static/minder/ui/directive/resourceEditor/resourceEditor.html @@ -0,0 +1,29 @@ +
+
+ + + + +
+
+
    +
  • + +
  • +
+
+ +
+
+
diff --git a/app/static/minder/ui/directive/searchBox/searchBox.directive.js b/app/static/minder/ui/directive/searchBox/searchBox.directive.js new file mode 100644 index 0000000..ea9aa61 --- /dev/null +++ b/app/static/minder/ui/directive/searchBox/searchBox.directive.js @@ -0,0 +1,147 @@ +angular.module('kityminderEditor') + .directive('searchBox', function() { + return { + restrict: 'A', + templateUrl: 'ui/directive/searchBox/searchBox.html', + scope: { + minder: '=' + }, + replace: true, + controller: function ($scope) { + var minder = $scope.minder; + var editor = window.editor; + $scope.handleKeyDown = handleKeyDown; + $scope.doSearch = doSearch; + $scope.exitSearch = exitSearch; + $scope.showTip = false; + $scope.showSearch = false; + + // 处理输入框按键事件 + function handleKeyDown(e) { + if (e.keyCode == 13) { + var direction = e.shiftKey ? 'prev' : 'next'; + doSearch($scope.keyword, direction); + } + if (e.keyCode == 27) { + exitSearch(); + } + } + + function exitSearch() { + $('#search-input').blur(); + $scope.showSearch = false; + minder.fire('hidenoterequest'); + editor.receiver.selectAll(); + } + + function enterSearch() { + $scope.showSearch = true; + setTimeout(function() { + $('#search-input').focus(); + }, 10); + + if ($scope.keyword) { + $('#search-input')[0].setSelectionRange(0, $scope.keyword.length); + } + } + + $('body').on('keydown', function(e) { + if (e.keyCode == 70 && (e.ctrlKey || e.metaKey) && !e.shiftKey) { + enterSearch(); + + $scope.$apply(); + e.preventDefault(); + } + }); + + minder.on('searchNode', function() { + enterSearch(); + }); + + + var nodeSequence = []; + var searchSequence = []; + + + minder.on('contentchange', makeNodeSequence); + + makeNodeSequence(); + + + function makeNodeSequence() { + nodeSequence = []; + minder.getRoot().traverse(function(node) { + nodeSequence.push(node); + }); + } + + function makeSearchSequence(keyword) { + searchSequence = []; + + for (var i = 0; i < nodeSequence.length; i++) { + var node = nodeSequence[i]; + var text = node.getText().toLowerCase(); + if (text.indexOf(keyword) != -1) { + searchSequence.push({node:node}); + } + var note = node.getData('note'); + if (note && note.toLowerCase().indexOf(keyword) != -1) { + searchSequence.push({node: node, keyword: keyword}); + } + } + } + + + function doSearch(keyword, direction) { + $scope.showTip = false; + minder.fire('hidenoterequest'); + + if (!keyword || !/\S/.exec(keyword)) { + $('#search-input').focus(); + return; + } + + // 当搜索不到节点时候默认的选项 + $scope.showTip = true; + $scope.curIndex = 0; + $scope.resultNum = 0; + + + keyword = keyword.toLowerCase(); + var newSearch = doSearch.lastKeyword != keyword; + + doSearch.lastKeyword = keyword; + + if (newSearch) { + makeSearchSequence(keyword); + } + + $scope.resultNum = searchSequence.length; + + if (searchSequence.length) { + var curIndex = newSearch ? 0 : (direction === 'next' ? doSearch.lastIndex + 1 : doSearch.lastIndex - 1) || 0; + curIndex = (searchSequence.length + curIndex) % searchSequence.length; + + setSearchResult(searchSequence[curIndex].node, searchSequence[curIndex].keyword); + + doSearch.lastIndex = curIndex; + + $scope.curIndex = curIndex + 1; + + function setSearchResult(node, previewKeyword) { + minder.execCommand('camera', node, 50); + setTimeout(function () { + minder.select(node, true); + if (!node.isExpanded()) minder.execCommand('expand', true); + if (previewKeyword) { + minder.fire('shownoterequest', {node: node, keyword: previewKeyword}); + } + }, 60); + } + } + } + + + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/searchBox/searchBox.html b/app/static/minder/ui/directive/searchBox/searchBox.html new file mode 100644 index 0000000..75ce518 --- /dev/null +++ b/app/static/minder/ui/directive/searchBox/searchBox.html @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/app/static/minder/ui/directive/searchBtn/searchBtn.directive.js b/app/static/minder/ui/directive/searchBtn/searchBtn.directive.js new file mode 100644 index 0000000..c60d85f --- /dev/null +++ b/app/static/minder/ui/directive/searchBtn/searchBtn.directive.js @@ -0,0 +1,18 @@ +angular.module('kityminderEditor') + .directive('searchBtn', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/searchBtn/searchBtn.html', + scope: { + minder: '=' + }, + replace: true, + link: function (scope) { + scope.enterSearch = enterSearch; + + function enterSearch() { + minder.fire('searchNode'); + } + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/searchBtn/searchBtn.html b/app/static/minder/ui/directive/searchBtn/searchBtn.html new file mode 100644 index 0000000..e0e3297 --- /dev/null +++ b/app/static/minder/ui/directive/searchBtn/searchBtn.html @@ -0,0 +1,14 @@ +
+ + +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/selectAll/selectAll.directive.js b/app/static/minder/ui/directive/selectAll/selectAll.directive.js new file mode 100644 index 0000000..69d1eeb --- /dev/null +++ b/app/static/minder/ui/directive/selectAll/selectAll.directive.js @@ -0,0 +1,86 @@ +angular.module('kityminderEditor') + .directive('selectAll', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/selectAll/selectAll.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + var minder = $scope.minder; + + $scope.items = ['revert', 'siblings', 'level', 'path', 'tree']; + + $scope.select = { + all: function() { + var selection = []; + minder.getRoot().traverse(function(node) { + selection.push(node); + }); + minder.select(selection, true); + minder.fire('receiverfocus'); + }, + revert: function() { + var selected = minder.getSelectedNodes(); + var selection = []; + minder.getRoot().traverse(function(node) { + if (selected.indexOf(node) == -1) { + selection.push(node); + } + }); + minder.select(selection, true); + minder.fire('receiverfocus'); + }, + siblings: function() { + var selected = minder.getSelectedNodes(); + var selection = []; + selected.forEach(function(node) { + if (!node.parent) return; + node.parent.children.forEach(function(sibling) { + if (selection.indexOf(sibling) == -1) selection.push(sibling); + }); + }); + minder.select(selection, true); + minder.fire('receiverfocus'); + }, + level: function() { + var selectedLevel = minder.getSelectedNodes().map(function(node) { + return node.getLevel(); + }); + var selection = []; + minder.getRoot().traverse(function(node) { + if (selectedLevel.indexOf(node.getLevel()) != -1) { + selection.push(node); + } + }); + minder.select(selection, true); + minder.fire('receiverfocus'); + }, + path: function() { + var selected = minder.getSelectedNodes(); + var selection = []; + selected.forEach(function(node) { + while(node && selection.indexOf(node) == -1) { + selection.push(node); + node = node.parent; + } + }); + minder.select(selection, true); + minder.fire('receiverfocus'); + }, + tree: function() { + var selected = minder.getSelectedNodes(); + var selection = []; + selected.forEach(function(parent) { + parent.traverse(function(node) { + if (selection.indexOf(node) == -1) selection.push(node); + }); + }); + minder.select(selection, true); + minder.fire('receiverfocus'); + } + }; + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/selectAll/selectAll.html b/app/static/minder/ui/directive/selectAll/selectAll.html new file mode 100644 index 0000000..b5e2398 --- /dev/null +++ b/app/static/minder/ui/directive/selectAll/selectAll.html @@ -0,0 +1,21 @@ +
+ + + +
\ No newline at end of file diff --git a/app/static/minder/ui/directive/styleOperator/styleOperator.directive.js b/app/static/minder/ui/directive/styleOperator/styleOperator.directive.js new file mode 100644 index 0000000..a094604 --- /dev/null +++ b/app/static/minder/ui/directive/styleOperator/styleOperator.directive.js @@ -0,0 +1,11 @@ +angular.module('kityminderEditor') + .directive('styleOperator', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/styleOperator/styleOperator.html', + scope: { + minder: '=' + }, + replace: true + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/styleOperator/styleOperator.html b/app/static/minder/ui/directive/styleOperator/styleOperator.html new file mode 100644 index 0000000..98371a0 --- /dev/null +++ b/app/static/minder/ui/directive/styleOperator/styleOperator.html @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/app/static/minder/ui/directive/templateList/templateList.directive.js b/app/static/minder/ui/directive/templateList/templateList.directive.js new file mode 100644 index 0000000..0f19624 --- /dev/null +++ b/app/static/minder/ui/directive/templateList/templateList.directive.js @@ -0,0 +1,15 @@ +angular.module('kityminderEditor') + .directive('templateList', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/templateList/templateList.html', + scope: { + minder: '=' + }, + replace: true, + link: function($scope) { + $scope.templateList = kityminder.Minder.getTemplateList(); + + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/templateList/templateList.html b/app/static/minder/ui/directive/templateList/templateList.html new file mode 100644 index 0000000..ca321c3 --- /dev/null +++ b/app/static/minder/ui/directive/templateList/templateList.html @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/app/static/minder/ui/directive/themeList/themeList.directive.js b/app/static/minder/ui/directive/themeList/themeList.directive.js new file mode 100644 index 0000000..44f1234 --- /dev/null +++ b/app/static/minder/ui/directive/themeList/themeList.directive.js @@ -0,0 +1,54 @@ +angular.module('kityminderEditor') + .directive('themeList', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/themeList/themeList.html', + replace: true, + link: function($scope) { + var themeList = kityminder.Minder.getThemeList(); + + //$scope.themeList = themeList; + + $scope.getThemeThumbStyle = function (theme) { + var themeObj = themeList[theme]; + if (!themeObj) { + return; + } + var style = { + 'color': themeObj['root-color'], + 'border-radius': themeObj['root-radius'] / 2 + }; + + if (themeObj['root-background']) { + style['background'] = themeObj['root-background'].toString(); + } + + return style; + }; + + // 维护 theme key 列表以保证列表美观(不按字母顺序排序) + $scope.themeKeyList = [ + 'classic', + 'classic-compact', + 'fresh-blue', + 'fresh-blue-compat', + 'fresh-green', + 'fresh-green-compat', + 'fresh-pink', + 'fresh-pink-compat', + 'fresh-purple', + 'fresh-purple-compat', + 'fresh-red', + 'fresh-red-compat', + 'fresh-soil', + 'fresh-soil-compat', + 'snow', + 'snow-compact', + 'tianpan', + 'tianpan-compact', + 'fish', + 'wire' + ]; + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/themeList/themeList.html b/app/static/minder/ui/directive/themeList/themeList.html new file mode 100644 index 0000000..cea4a9f --- /dev/null +++ b/app/static/minder/ui/directive/themeList/themeList.html @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/app/static/minder/ui/directive/topTab/topTab.directive.js b/app/static/minder/ui/directive/topTab/topTab.directive.js new file mode 100644 index 0000000..2397c00 --- /dev/null +++ b/app/static/minder/ui/directive/topTab/topTab.directive.js @@ -0,0 +1,81 @@ +angular.module('kityminderEditor') + .directive('topTab', function() { + return { + restrict: 'A', + templateUrl: 'ui/directive/topTab/topTab.html', + scope: { + minder: '=topTab', + editor: '=' + }, + link: function(scope) { + + /* + * + * 用户选择一个新的选项卡会执行 setCurTab 和 foldTopTab 两个函数 + * 用户点击原来的选项卡会执行 foldTopTop 一个函数 + * + * 也就是每次选择新的选项卡都会执行 setCurTab,初始化的时候也会执行 setCurTab 函数 + * 因此用 executedCurTab 记录是否已经执行了 setCurTab 函数 + * 用 isInit 记录是否是初始化的状态,在任意一个函数时候 isInit 设置为 false + * 用 isOpen 记录是否打开了 topTab + * + * 因此用到了三个 mutex + * */ + var executedCurTab = false; + var isInit = true; + var isOpen = true; + + scope.setCurTab = function(tabName) { + setTimeout(function() { + //console.log('set cur tab to : ' + tabName); + executedCurTab = true; + //isOpen = false; + if (tabName != 'idea') { + isInit = false; + } + }); + }; + + scope.toggleTopTab = function() { + setTimeout(function() { + if(!executedCurTab || isInit) { + isInit = false; + + isOpen ? closeTopTab(): openTopTab(); + isOpen = !isOpen; + } + + executedCurTab = false; + }); + }; + + function closeTopTab() { + var $tabContent = $('.tab-content'); + var $minderEditor = $('.minder-editor'); + + $tabContent.animate({ + height: 0, + display: 'none' + }); + + $minderEditor.animate({ + top: '32px' + }); + } + + function openTopTab() { + var $tabContent = $('.tab-content'); + var $minderEditor = $('.minder-editor'); + + $tabContent.animate({ + height: '60px', + display: 'block' + }); + + $minderEditor.animate({ + top: '92px' + }); + } + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/topTab/topTab.html b/app/static/minder/ui/directive/topTab/topTab.html new file mode 100644 index 0000000..1dc7293 --- /dev/null +++ b/app/static/minder/ui/directive/topTab/topTab.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/static/minder/ui/directive/undoRedo/undoRedo.directive.js b/app/static/minder/ui/directive/undoRedo/undoRedo.directive.js new file mode 100644 index 0000000..c48f98d --- /dev/null +++ b/app/static/minder/ui/directive/undoRedo/undoRedo.directive.js @@ -0,0 +1,14 @@ +angular.module('kityminderEditor') + .directive('undoRedo', function() { + return { + restrict: 'E', + templateUrl: 'ui/directive/undoRedo/undoRedo.html', + scope: { + editor: '=' + }, + replace: true, + link: function($scope) { + + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/directive/undoRedo/undoRedo.html b/app/static/minder/ui/directive/undoRedo/undoRedo.html new file mode 100644 index 0000000..5941a51 --- /dev/null +++ b/app/static/minder/ui/directive/undoRedo/undoRedo.html @@ -0,0 +1,16 @@ +
+
+ + +
+
+ + +
+
\ No newline at end of file diff --git a/app/static/minder/ui/filter/command.filters.js b/app/static/minder/ui/filter/command.filters.js new file mode 100644 index 0000000..a197cef --- /dev/null +++ b/app/static/minder/ui/filter/command.filters.js @@ -0,0 +1,12 @@ +angular.module('kityminderEditor') + .filter('commandState', function() { + return function(minder, command) { + return minder.queryCommandState(command); + } + }) + .filter('commandValue', function() { + return function(minder, command) { + return minder.queryCommandValue(command); + } + }); + diff --git a/app/static/minder/ui/filter/lang.filter.js b/app/static/minder/ui/filter/lang.filter.js new file mode 100644 index 0000000..d355baf --- /dev/null +++ b/app/static/minder/ui/filter/lang.filter.js @@ -0,0 +1,19 @@ +angular.module('kityminderEditor') + .filter('lang', ['config', 'lang.zh-cn', function(config, lang) { + return function(text, block) { + var defaultLang = config.get('defaultLang'); + + if (lang[defaultLang] == undefined) { + return '未发现对应语言包,请检查 lang.xxx.service.js!'; + } else { + + var dict = lang[defaultLang]; + block.split('/').forEach(function(ele, idx) { + dict = dict[ele]; + }); + + return dict[text] || null; + } + + }; + }]); \ No newline at end of file diff --git a/app/static/minder/ui/images/iconpriority.png b/app/static/minder/ui/images/iconpriority.png new file mode 100644 index 0000000..8daa2e0 Binary files /dev/null and b/app/static/minder/ui/images/iconpriority.png differ diff --git a/app/static/minder/ui/images/iconprogress.png b/app/static/minder/ui/images/iconprogress.png new file mode 100644 index 0000000..9aedd0a Binary files /dev/null and b/app/static/minder/ui/images/iconprogress.png differ diff --git a/app/static/minder/ui/images/icons.png b/app/static/minder/ui/images/icons.png new file mode 100644 index 0000000..11f380c Binary files /dev/null and b/app/static/minder/ui/images/icons.png differ diff --git a/app/static/minder/ui/images/template.png b/app/static/minder/ui/images/template.png new file mode 100644 index 0000000..e0283be Binary files /dev/null and b/app/static/minder/ui/images/template.png differ diff --git a/app/static/minder/ui/kityminder.app.js b/app/static/minder/ui/kityminder.app.js new file mode 100644 index 0000000..c75de30 --- /dev/null +++ b/app/static/minder/ui/kityminder.app.js @@ -0,0 +1,15 @@ +angular.module('kityminderEditor', [ + 'ui.bootstrap', + 'ui.codemirror', + 'ui.colorpicker' +]) + .config(function($sceDelegateProvider) { + $sceDelegateProvider.resourceUrlWhitelist([ + // Allow same origin resource loads. + 'self', + // Allow loading from our assets domain. Notice the difference between * and **. + 'http://agroup.baidu.com:8910/**', + 'http://cq01-fe-rdtest01.vm.baidu.com:8910/**', + 'http://agroup.baidu.com:8911/**' + ]); + }); \ No newline at end of file diff --git a/app/static/minder/ui/service/commandBinder.service.js b/app/static/minder/ui/service/commandBinder.service.js new file mode 100644 index 0000000..8af4896 --- /dev/null +++ b/app/static/minder/ui/service/commandBinder.service.js @@ -0,0 +1,12 @@ +angular.module('kityminderEditor').service('commandBinder', function() { + return { + bind: function(minder, command, scope) { + + minder.on('interactchange', function() { + scope.commandDisabled = minder.queryCommandState(command) === -1; + scope.commandValue = minder.queryCommandValue(command); + scope.$apply(); + }); + } + }; +}); \ No newline at end of file diff --git a/app/static/minder/ui/service/config.service.js b/app/static/minder/ui/service/config.service.js new file mode 100644 index 0000000..c9de02e --- /dev/null +++ b/app/static/minder/ui/service/config.service.js @@ -0,0 +1,68 @@ +angular.module('kityminderEditor') + .provider('config', function() { + + this.config = { + // 右侧面板最小宽度 + ctrlPanelMin: 250, + + // 右侧面板宽度 + ctrlPanelWidth: parseInt(window.localStorage.__dev_minder_ctrlPanelWidth) || 250, + + // 分割线宽度 + dividerWidth: 3, + + // 默认语言 + defaultLang: 'zh-cn', + + // 放大缩小比例 + zoom: [10, 20, 30, 50, 80, 100, 120, 150, 200], + + // 图片上传接口 + imageUpload: 'server/imageUpload.php' + }; + + this.set = function(key, value) { + var supported = Object.keys(this.config); + var configObj = {}; + + // 支持全配置 + if (typeof key === 'object') { + configObj = key; + } + else { + configObj[key] = value; + } + + for (var i in configObj) { + if (configObj.hasOwnProperty(i) && supported.indexOf(i) !== -1) { + this.config[i] = configObj[i]; + } + else { + console.error('Unsupported config key: ', key, ', please choose in :', supported.join(', ')); + return false; + } + } + + return true; + }; + + this.$get = function () { + var me = this; + + return { + get: function (key) { + if (arguments.length === 0) { + return me.config; + } + + if (me.config.hasOwnProperty(key)) { + return me.config[key]; + } + + console.warn('Missing config key pair for : ', key); + return ''; + } + + }; + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/service/lang.zh-cn.service.js b/app/static/minder/ui/service/lang.zh-cn.service.js new file mode 100644 index 0000000..e53ab3c --- /dev/null +++ b/app/static/minder/ui/service/lang.zh-cn.service.js @@ -0,0 +1,423 @@ +angular.module('kityminderEditor') + .service('lang.zh-cn', function() { + return { + 'zh-cn': { + 'template': { + 'default': '思维导图', + 'tianpan': '天盘图', + 'structure': '组织结构图', + 'filetree': '目录组织图', + 'right': '逻辑结构图', + 'fish-bone': '鱼骨头图' + }, + 'theme': { + 'classic': '脑图经典', + 'classic-compact': '紧凑经典', + 'snow': '温柔冷光', + 'snow-compact': '紧凑冷光', + 'fish': '鱼骨图', + 'wire': '线框', + 'fresh-red': '清新红', + 'fresh-soil': '泥土黄', + 'fresh-green': '文艺绿', + 'fresh-blue': '天空蓝', + 'fresh-purple': '浪漫紫', + 'fresh-pink': '脑残粉', + 'fresh-red-compat': '紧凑红', + 'fresh-soil-compat': '紧凑黄', + 'fresh-green-compat': '紧凑绿', + 'fresh-blue-compat': '紧凑蓝', + 'fresh-purple-compat': '紧凑紫', + 'fresh-pink-compat': '紧凑粉', + 'tianpan':'经典天盘', + 'tianpan-compact': '紧凑天盘' + }, + 'maintopic': '中心主题', + 'topic': '分支主题', + 'panels': { + 'history': '历史', + 'template': '模板', + 'theme': '皮肤', + 'layout': '布局', + 'style': '样式', + 'font': '文字', + 'color': '颜色', + 'background': '背景', + 'insert': '插入', + 'arrange': '调整', + 'nodeop': '当前', + 'priority': '优先级', + 'progress': '进度', + 'resource': '资源', + 'note': '备注', + 'attachment': '附件', + 'word': '文字' + }, + 'error_message': { + 'title': '哎呀,脑图出错了', + + 'err_load': '加载脑图失败', + 'err_save': '保存脑图失败', + 'err_network': '网络错误', + 'err_doc_resolve': '文档解析失败', + 'err_unknown': '发生了奇怪的错误', + 'err_localfile_read': '文件读取错误', + 'err_download': '文件下载失败', + 'err_remove_share': '取消分享失败', + 'err_create_share': '分享失败', + 'err_mkdir': '目录创建失败', + 'err_ls': '读取目录失败', + 'err_share_data': '加载分享内容出错', + 'err_share_sync_fail': '分享内容同步失败', + 'err_move_file': '文件移动失败', + 'err_rename': '重命名失败', + + 'unknownreason': '可能是外星人篡改了代码...', + 'pcs_code': { + 3: "不支持此接口", + 4: "没有权限执行此操作", + 5: "IP未授权", + 110: "用户会话已过期,请重新登录", + 31001: "数据库查询错误", + 31002: "数据库连接错误", + 31003: "数据库返回空结果", + 31021: "网络错误", + 31022: "暂时无法连接服务器", + 31023: "输入参数错误", + 31024: "app id为空", + 31025: "后端存储错误", + 31041: "用户的cookie不是合法的百度cookie", + 31042: "用户未登陆", + 31043: "用户未激活", + 31044: "用户未授权", + 31045: "用户不存在", + 31046: "用户已经存在", + 31061: "文件已经存在", + 31062: "文件名非法", + 31063: "文件父目录不存在", + 31064: "无权访问此文件", + 31065: "目录已满", + 31066: "文件不存在", + 31067: "文件处理出错", + 31068: "文件创建失败", + 31069: "文件拷贝失败", + 31070: "文件删除失败", + 31071: "不能读取文件元信息", + 31072: "文件移动失败", + 31073: "文件重命名失败", + 31079: "未找到文件MD5,请使用上传API上传整个文件。", + 31081: "superfile创建失败", + 31082: "superfile 块列表为空", + 31083: "superfile 更新失败", + 31101: "tag系统内部错误", + 31102: "tag参数错误", + 31103: "tag系统错误", + 31110: "未授权设置此目录配额", + 31111: "配额管理只支持两级目录", + 31112: "超出配额", + 31113: "配额不能超出目录祖先的配额", + 31114: "配额不能比子目录配额小", + 31141: "请求缩略图服务失败", + 31201: "签名错误", + 31202: "文件不存在", + 31203: "设置acl失败", + 31204: "请求acl验证失败", + 31205: "获取acl失败", + 31206: "acl不存在", + 31207: "bucket已存在", + 31208: "用户请求错误", + 31209: "服务器错误", + 31210: "服务器不支持", + 31211: "禁止访问", + 31212: "服务不可用", + 31213: "重试出错", + 31214: "上传文件data失败", + 31215: "上传文件meta失败", + 31216: "下载文件data失败", + 31217: "下载文件meta失败", + 31218: "容量超出限额", + 31219: "请求数超出限额", + 31220: "流量超出限额", + 31298: "服务器返回值KEY非法", + 31299: "服务器返回值KEY不存在" + } + }, + 'ui': { + 'shared_file_title': '[分享的] {0} (只读)', + 'load_share_for_edit': '正在加载分享的文件...', + 'share_sync_success': '分享内容已同步', + 'recycle_clear_confirm': '确认清空回收站么?清空后的文件无法恢复。', + + 'fullscreen_exit_hint': '按 Esc 或 F11 退出全屏', + + 'error_detail': '详细信息', + 'copy_and_feedback': '复制并反馈', + 'move_file_confirm': '确定把 "{0}" 移动到 "{1}" 吗?', + 'rename': '重命名', + 'rename_success': '{0} 重命名成功', + 'move_success': '{0} 移动成功到 {1}', + + 'command': { + 'appendsiblingnode': '插入同级主题', + 'appendparentnode': '插入上级主题', + 'appendchildnode': '插入下级主题', + 'removenode': '删除', + 'editnode': '编辑', + 'arrangeup': '上移', + 'arrangedown': '下移', + 'resetlayout': '整理布局', + 'expandtoleaf': '展开全部节点', + 'expandtolevel1': '展开到一级节点', + 'expandtolevel2': '展开到二级节点', + 'expandtolevel3': '展开到三级节点', + 'expandtolevel4': '展开到四级节点', + 'expandtolevel5': '展开到五级节点', + 'expandtolevel6': '展开到六级节点', + 'fullscreen': '全屏', + 'outline': '大纲' + }, + + 'search':'搜索', + + 'expandtoleaf': '展开', + + 'back': '返回', + + 'undo': '撤销 (Ctrl + Z)', + 'redo': '重做 (Ctrl + Y)', + + 'tabs': { + 'idea': '思路', + 'appearence': '外观', + 'view': '视图' + }, + + 'quickvisit': { + 'new': '新建 (Ctrl + Alt + N)', + 'save': '保存 (Ctrl + S)', + 'share': '分享 (Ctrl + Alt + S)', + 'feedback': '反馈问题(F1)', + 'editshare': '编辑' + }, + + 'menu': { + + 'mainmenutext': '百度脑图', // 主菜单按钮文本 + + 'newtab': '新建', + 'opentab': '打开', + 'savetab': '保存', + 'sharetab': '分享', + 'preferencetab': '设置', + 'helptab': '帮助', + 'feedbacktab': '反馈', + 'recenttab': '最近使用', + 'netdisktab': '百度云存储', + 'localtab': '本地文件', + 'drafttab': '草稿箱', + 'downloadtab': '导出到本地', + 'createsharetab': '当前脑图', + 'managesharetab': '已分享', + + 'newheader': '新建脑图', + 'openheader': '打开', + 'saveheader': '保存到', + 'draftheader': '草稿箱', + 'shareheader': '分享我的脑图', + 'downloadheader': '导出到指定格式', + 'preferenceheader': '偏好设置', + 'helpheader': '帮助', + 'feedbackheader': '反馈' + }, + + 'mydocument': '我的文档', + 'emptydir': '目录为空!', + 'pickfile': '选择文件...', + 'acceptfile': '支持的格式:{0}', + 'dropfile': '或将文件拖至此处', + 'unsupportedfile': '不支持的文件格式', + 'untitleddoc': '未命名文档', + 'overrideconfirm': '{0} 已存在,确认覆盖吗?', + 'checklogin': '检查登录状态中...', + 'loggingin': '正在登录...', + 'recent': '最近打开', + 'clearrecent': '清空', + 'clearrecentconfirm': '确认清空最近文档列表?', + 'cleardraft': '清空', + 'cleardraftconfirm': '确认清空草稿箱?', + + 'none_share': '不分享', + 'public_share': '公开分享', + 'password_share': '私密分享', + 'email_share': '邮件邀请', + 'url_share': '脑图 URL 地址:', + 'sns_share': '社交网络分享:', + 'sns_share_text': '“{0}” - 我用百度脑图制作的思维导图,快看看吧!(地址:{1})', + 'none_share_description': '不分享当前脑图', + 'public_share_description': '创建任何人可见的分享', + 'share_button_text': '创建', + 'password_share_description': '创建需要密码才可见的分享', + 'email_share_description': '创建指定人可见的分享,您还可以允许他们编辑', + 'ondev': '敬请期待!', + 'create_share_failed': '分享失败:{0}', + 'remove_share_failed': '删除失败:{1}', + 'copy': '复制', + 'copied': '已复制', + 'shared_tip': '当前脑图被 {0} 分享,你可以修改之后保存到自己的网盘上或再次分享', + 'current_share': '当前脑图', + 'manage_share': '我的分享', + 'share_remove_action': '不分享该脑图', + 'share_view_action': '打开分享地址', + 'share_edit_action': '编辑分享的文件', + + 'login': '登录', + 'logout': '注销', + 'switchuser': '切换账户', + 'userinfo': '个人信息', + 'gotonetdisk': '我的网盘', + 'requirelogin': '请 后使用', + 'saveas': '保存为', + 'filename': '文件名', + 'fileformat': '保存格式', + 'save': '保存', + 'mkdir': '新建目录', + 'recycle': '回收站', + 'newdir': '未命名目录', + + 'bold': '加粗', + 'italic': '斜体', + 'forecolor': '字体颜色', + 'fontfamily': '字体', + 'fontsize': '字号', + 'layoutstyle': '主题', + 'node': '节点操作', + 'saveto': '另存为', + 'hand': '允许拖拽', + 'camera': '定位根节点', + 'zoom-in': '放大(Ctrl+)', + 'zoom-out': '缩小(Ctrl-)', + 'markers': '标签', + 'resource': '资源', + 'help': '帮助', + 'preference': '偏好设置', + 'expandnode': '展开到叶子', + 'collapsenode': '收起到一级节点', + 'template': '模板', + 'theme': '皮肤', + 'clearstyle': '清除样式', + 'copystyle': '复制样式', + 'pastestyle': '粘贴样式', + 'appendsiblingnode': '同级主题', + 'appendchildnode': '下级主题', + 'arrangeup': '前调', + 'arrangedown': '后调', + 'editnode': '编辑', + 'removenode': '移除', + 'priority': '优先级', + 'progress': { + 'p1': '未开始', + 'p2': '完成 1/8', + 'p3': '完成 1/4', + 'p4': '完成 3/8', + 'p5': '完成一半', + 'p6': '完成 5/8', + 'p7': '完成 3/4', + 'p8': '完成 7/8', + 'p9': '已完成', + 'p0': '清除进度' + }, + 'link': '链接', + 'image': '图片', + 'note': '备注', + 'insertlink': '插入链接', + 'insertimage': '插入图片', + 'insertnote': '插入备注', + 'removelink': '移除已有链接', + 'removeimage': '移除已有图片', + 'removenote': '移除已有备注', + 'resetlayout': '整理', + + 'justnow': '刚刚', + 'minutesago': '{0} 分钟前', + 'hoursago': '{0} 小时前', + 'yesterday': '昨天', + 'daysago': '{0} 天前', + 'longago': '很久之前', + + 'redirect': '您正在打开连接 {0},百度脑图不能保证连接的安全性,是否要继续?', + 'navigator': '导航器', + + 'unsavedcontent': '当前文件还没有保存到网盘:\n\n{0}\n\n虽然未保存的数据会缓存在草稿箱,但是清除浏览器缓存会导致草稿箱清除。', + + 'shortcuts': '快捷键', + 'contact': '联系与反馈', + 'email': '邮件组', + 'qq_group': 'QQ 群', + 'github_issue': 'Github', + 'baidu_tieba': '贴吧', + + 'clipboardunsupported': '您的浏览器不支持剪贴板,请使用快捷键复制', + + 'load_success': '{0} 加载成功', + 'save_success': '{0} 已保存于 {1}', + 'autosave_success': '{0} 已自动保存于 {1}', + + 'selectall': '全选', + 'selectrevert': '反选', + 'selectsiblings': '选择兄弟节点', + 'selectlevel': '选择同级节点', + 'selectpath': '选择路径', + 'selecttree': '选择子树' + }, + 'popupcolor': { + 'clearColor': '清空颜色', + 'standardColor': '标准颜色', + 'themeColor': '主题颜色' + }, + 'dialogs': { + 'markers': { + 'static': { + 'lang_input_text': '文本内容:', + 'lang_input_url': '链接地址:', + 'lang_input_title': '标题:', + 'lang_input_target': '是否在新窗口:' + }, + 'priority': '优先级', + 'none': '无', + 'progress': { + 'title': '进度', + 'notdone': '未完成', + 'done1': '完成 1/8', + 'done2': '完成 1/4', + 'done3': '完成 3/8', + 'done4': '完成 1/2', + 'done5': '完成 5/8', + 'done6': '完成 3/4', + 'done7': '完成 7/8', + 'done': '已完成' + } + }, + 'help': { + + }, + 'hyperlink': {}, + 'image': {}, + 'resource': {} + }, + 'hyperlink': { + 'hyperlink': '链接...', + 'unhyperlink': '移除链接' + }, + 'image': { + 'image': '图片...', + 'removeimage': '移除图片' + }, + 'marker': { + 'marker': '进度/优先级...' + }, + 'resource': { + 'resource': '资源...' + } + } + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/service/memory.service.js b/app/static/minder/ui/service/memory.service.js new file mode 100644 index 0000000..5c2f464 --- /dev/null +++ b/app/static/minder/ui/service/memory.service.js @@ -0,0 +1,62 @@ +/** + * @fileOverview + * + * UI 状态的 LocalStorage 的存取文件,未来可能在离线编辑的时候升级 + * + * @author: zhangbobell + * @email : zhangbobell@163.com + * + * @copyright: Baidu FEX, 2015 + */ +angular.module('kityminderEditor') + .service('memory', function() { + + function isQuotaExceeded(e) { + var quotaExceeded = false; + if (e) { + if (e.code) { + switch (e.code) { + case 22: + quotaExceeded = true; + break; + case 1014: + // Firefox + if (e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { + quotaExceeded = true; + } + break; + } + } else if (e.number === -2147024882) { + // Internet Explorer 8 + quotaExceeded = true; + } + } + return quotaExceeded; + } + + return { + get: function(key) { + var value = window.localStorage.getItem(key); + return null || JSON.parse(value); + }, + + set: function(key, value) { + try { + window.localStorage.setItem(key, JSON.stringify(value)); + return true; + } catch(e) { + if (isQuotaExceeded(e)) { + return false; + } + } + }, + remove: function(key) { + var value = window.localStorage.getItem(key); + window.localStorage.removeItem(key); + return value; + }, + clear: function() { + window.localStorage.clear(); + } + } +}); \ No newline at end of file diff --git a/app/static/minder/ui/service/minder.service.js b/app/static/minder/ui/service/minder.service.js new file mode 100644 index 0000000..fba861d --- /dev/null +++ b/app/static/minder/ui/service/minder.service.js @@ -0,0 +1,20 @@ +angular.module('kityminderEditor') + .service('minder.service', function() { + + var callbackQueue = []; + + function registerEvent(callback) { + callbackQueue.push(callback); + } + + function executeCallback() { + callbackQueue.forEach(function(ele) { + ele.apply(this, arguments); + }) + } + + return { + registerEvent: registerEvent, + executeCallback: executeCallback + } + }); \ No newline at end of file diff --git a/app/static/minder/ui/service/resource.service.js b/app/static/minder/ui/service/resource.service.js new file mode 100644 index 0000000..ff2e283 --- /dev/null +++ b/app/static/minder/ui/service/resource.service.js @@ -0,0 +1,49 @@ +angular.module('kityminderEditor') + .service('resourceService', ['$document', function($document) { + var openScope = null; + + this.open = function( dropdownScope ) { + if ( !openScope ) { + $document.bind('click', closeDropdown); + $document.bind('keydown', escapeKeyBind); + } + + if ( openScope && openScope !== dropdownScope ) { + openScope.resourceListOpen = false; + } + + openScope = dropdownScope; + }; + + this.close = function( dropdownScope ) { + if ( openScope === dropdownScope ) { + openScope = null; + $document.unbind('click', closeDropdown); + $document.unbind('keydown', escapeKeyBind); + } + }; + + var closeDropdown = function( evt ) { + // This method may still be called during the same mouse event that + // unbound this event handler. So check openScope before proceeding. + //console.log(evt, openScope); + if (!openScope) { return; } + + var toggleElement = openScope.getToggleElement(); + if ( evt && toggleElement && toggleElement[0].contains(evt.target) ) { + return; + } + + openScope.$apply(function() { + console.log('to close the resourcelist'); + openScope.resourceListOpen = false; + }); + }; + + var escapeKeyBind = function( evt ) { + if ( evt.which === 27 ) { + openScope.focusToggleElement(); + closeDropdown(); + } + }; +}]) \ No newline at end of file diff --git a/app/static/minder/ui/service/revokeDialog.service.js b/app/static/minder/ui/service/revokeDialog.service.js new file mode 100644 index 0000000..a49942e --- /dev/null +++ b/app/static/minder/ui/service/revokeDialog.service.js @@ -0,0 +1,82 @@ +angular.module('kityminderEditor').service('revokeDialog', ['$modal', 'minder.service', function($modal, minderService) { + + minderService.registerEvent(function() { + + // 触发导入节点或导出节点对话框 + var minder = window.minder; + var editor = window.editor; + var parentFSM = editor.hotbox.getParentFSM(); + + + minder.on('importNodeData', function() { + parentFSM.jump('modal', 'import-text-modal'); + + var importModal = $modal.open({ + animation: true, + templateUrl: 'ui/dialog/imExportNode/imExportNode.tpl.html', + controller: 'imExportNode.ctrl', + size: 'md', + resolve: { + title: function() { + return '导入节点'; + }, + defaultValue: function() { + return ''; + }, + type: function() { + return 'import'; + } + } + }); + + importModal.result.then(function(result) { + try{ + minder.Text2Children(minder.getSelectedNode(), result); + } catch(e) { + alert(e); + } + parentFSM.jump('normal', 'import-text-finish'); + editor.receiver.selectAll(); + }, function() { + parentFSM.jump('normal', 'import-text-finish'); + editor.receiver.selectAll(); + }); + }); + + minder.on('exportNodeData', function() { + parentFSM.jump('modal', 'export-text-modal'); + + var exportModal = $modal.open({ + animation: true, + templateUrl: 'ui/dialog/imExportNode/imExportNode.tpl.html', + controller: 'imExportNode.ctrl', + size: 'md', + resolve: { + title: function() { + return '导出节点'; + }, + defaultValue: function() { + var selectedNode = minder.getSelectedNode(), + Node2Text = window.kityminder.data.getRegisterProtocol('text').Node2Text; + + return Node2Text(selectedNode); + }, + type: function() { + return 'export'; + } + } + }); + + exportModal.result.then(function(result) { + parentFSM.jump('normal', 'export-text-finish'); + editor.receiver.selectAll(); + }, function() { + parentFSM.jump('normal', 'export-text-finish'); + editor.receiver.selectAll(); + }); + }); + + }); + + return {}; +}]); \ No newline at end of file diff --git a/app/static/minder/ui/service/server.service.js b/app/static/minder/ui/service/server.service.js new file mode 100644 index 0000000..a6dadd7 --- /dev/null +++ b/app/static/minder/ui/service/server.service.js @@ -0,0 +1,26 @@ +/** + * @fileOverview + * + * 与后端交互的服务 + * + * @author: zhangbobell + * @email : zhangbobell@163.com + * + * @copyright: Baidu FEX, 2015 + */ +angular.module('kityminderEditor') + .service('server', ['config', '$http', function(config, $http) { + + return { + uploadImage: function(file) { + var url = config.get('imageUpload'); + var fd = new FormData(); + fd.append('upload_file', file); + + return $http.post(url, fd, { + transformRequest: angular.identity, + headers: {'Content-Type': undefined} + }); + } + } + }]); \ No newline at end of file diff --git a/app/static/minder/ui/service/valueTransfer.service.js b/app/static/minder/ui/service/valueTransfer.service.js new file mode 100644 index 0000000..498a9f6 --- /dev/null +++ b/app/static/minder/ui/service/valueTransfer.service.js @@ -0,0 +1,4 @@ +angular.module('kityminderEditor') + .service('valueTransfer', function() { + return {}; + }); \ No newline at end of file diff --git a/app/static/scripts/minder/test_minders.js b/app/static/scripts/minder/test_minders.js new file mode 100644 index 0000000..c0d3ea7 --- /dev/null +++ b/app/static/scripts/minder/test_minders.js @@ -0,0 +1,351 @@ +$(function () { + + //1.初始化Table + var oTable = new TableInit(); + oTable.Init(); + + +}); + +var TableInit = function () { + var oTableInit = new Object(); + //初始化Table + oTableInit.Init = function () { + $('#tb_test_minders').bootstrapTable({ + url: '/get_minders.json', //请求后台的URL(*) + method: 'get', //请求方式(*) + toolbar: '#toolbar', //工具按钮用哪个容器 + striped: true, //是否显示行间隔色 + cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*) + pagination: true, //是否显示分页(*) + sortable: true, //是否启用排序 + sortOrder: "asc", //排序方式 + queryParams: oTableInit.queryParams,//传递参数(*) + sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*) + pageNumber:1, //初始化加载第一页,默认第一页 + pageSize: 10, //每页的记录行数(*) + pageList: [10, 25, 50, 100, 500], //可供选择的每页的行数(*) + search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大 + strictSearch: false, + showColumns: true, //是否显示所有的列 + showRefresh: true, //是否显示刷新按钮 + minimumCountColumns: 2, //最少允许的列数 + clickToSelect: true, //是否启用点击选中行 + height: 500, //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度 + uniqueId: "id", //每一行的唯一标识,一般为主键列 + showToggle:true, //是否显示详细视图和列表视图的切换按钮 + cardView: false, //是否显示详细视图 + detailView: false, //是否显示父子表 + columns: [{ + checkbox: true + }, { + field: 'id', + title: 'id' + }, { + field: 'name', + title: '名称' + },{ + field: 'module', + title: '模块' + },{ + field: 'description', + title: '说明' + }, + { + field: 'operate', + title: '操作', + align: 'center', + formatter: function (value, row, index) { + var a = '编辑信息 '; + var d = '查看内容 '; + var e = '编辑内容 '; + var b = '复制 '; + var c = '删除 '; + return a+e+d+b+c; + } + } + ] + }); + }; + + //得到查询的参数 + oTableInit.queryParams = function (params) { + var temp = { //这里的键的名字和控制器的变量名必须一直,这边改动,控制器也需要改成一样的 + limit: params.limit, //页面大小 + offset: params.offset, //页码 + name: $("#name").val() + }; + return temp; + }; + return oTableInit; +}; + +function searchMinders(){ + var name=$('#name').val(); + $('#tb_test_minders').bootstrapTable('refresh', {url: '/get_minders.json',query:{'name': name}}); +} + + // 编辑表单 +function get_edit_minder_info(active_id) + { +// alert(active_id) + if(!active_id) + { + alert('Error!'); + return false; + } + // var form_data = new Array(); + + $.ajax( + { + url: "/get_minders.json", + data:{"id":active_id,"type":"edit"}, + type: "get", + dataType:"json", + beforeSend:function() + { + // $("#tip").html("正在处理..."); + return true; + }, + success:function(data) + { + console.log(data); + console.log(data.code); + console.log(data.minder); + console.log(data.code==200); + if(data.code == 200) + { + console.log('start'); + // 解析json数据 + var data = data; + var data_obj = data.minder; + console.log(data_obj.id); + console.log(data_obj.name); + console.log(data_obj.module); + console.log(data_obj.description); + + // 赋值 + $("#id").val(data_obj.id); + $("#name").val(data_obj.name); + $("#module").val(data_obj.module); + $("#description").val(data_obj.description); + } + + else + { + $("#tip").html("失败,请重试"); + alert('操作失败'); + } + }, + error:function() + { + alert('请求出错'); + }, + complete:function() + { + // $('#tips').hide(); + } + }); + + return false; + } + + +// submit form +function submitAddMinderForm() { +// $("#new_test_minder").validate(); + $.ajax( + { + url: "/save_new_test_minder.json", + data:{"type":"add","name":$("#name").val(),"module":$("#module").val(),"description":$("#description").val()}, + type: "post", + dataType:"json", + beforeSend:function() + { + return true; + }, + success:function(data) + { + console.log(data); + if(data) + { + // 解析json数据 + var data = data; + if(data.code==200){ + alert('success!'); + window.location.href=('/test_minders'); + // alert + }else{ + alert('code is :'+data.code+' and message is :'+data.msg); + } + } + + else + { + // $("#tip").html("失败,请重试"); + console.log(data); + window.location.href=('/test_minders'); + } + }, + error:function() + { + console.log(data); + window.location.href=('/test_minders'); + }, + complete:function() + { + // $('#tips').hide(); + window.location.href=('/test_minders'); + } +}); + } + +// submit form +function submitEditForm() { +// $("#edit_test_minder").validate(); + $.ajax( + { + url: "/save_new_test_minder.json", + data:{"id":$("#id").val(),"type":"update","name":$("#name").val(),"module":$("#module").val(),"description":$("#description").val()}, + type: "post", + dataType:"json", + beforeSend:function() + { + return true; + }, + success:function(data) + { + console.log(data); + if(data) + { + // 解析json数据 + var data = data; + if(data.code==200){ + alert('success!'); + window.location.href=('/test_minders'); + // alert + }else{ + alert('code is :'+data.code+' and message is :'+data.msg); + } + } + + else + { + // $("#tip").html("失败,请重试"); + window.location.href=('/test_minders'); + console.log(data); + } + }, + error:function() + { + console.log(data); + window.location.href=('/test_minders'); + }, + complete:function() + { + // $('#tips').hide(); + window.location.href=('/test_minders'); + } +}); + } + + + +function copy_minder(){ + var minder_id = document.getElementById('minderId').value; +// alert(minder_id); + if (minder_id != ""){ + copy_minder_save(minder_id); + + }else{ + alert('id is null!'); + } + +} + +function copy_minder_save(minder_id){ + $.ajax( + { + url: "/copy_test_minder.json", + data:{"id":minder_id}, + type: "post", + dataType:"json", + beforeSend:function() + { + return true; + }, + success:function(data) + { + if(data) + { + // 解析json数据 + var data = data; + if(data.code==200){ + alert('success!'); + window.location.href=('/edit_minder?id='+data.id); + // alert + }else{ + alert('code is :'+data.code+' and message is :'+data.msg); + } + } + + else + { + // $("#tip").html("失败,请重试"); + alert('操作失败'); + } + }, + error:function() + { + alert('请求出错'); + }, + complete:function() + { + // $('#tips').hide(); + } +}); +} + + +function delete_test_minder(minder_id){ + $.ajax( + { + url: "/delete_test_minder.json", + data:{"id":minder_id}, + type: "post", + dataType:"json", + beforeSend:function() + { + return true; + }, + success:function(data) + { + if(data) + { + // 解析json数据 + var data = data; + if(data.code==200){ + alert('success!'); + window.location.href=('/test_minders'); + // alert + }else{ + alert('code is :'+data.code+' and message is :'+data.msg); + } + } + + else + { + // $("#tip").html("失败,请重试"); + alert('操作失败'); + } + }, + error:function() + { + alert('请求出错'); + }, + complete:function() + { + // $('#tips').hide(); + } +}); +} diff --git a/app/templates/base.html b/app/templates/base.html index f75061a..ded7929 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -35,8 +35,10 @@
  • 节点管理
  • 步骤说明
  • -
  • 新接口管理
  • -
  • 单元测试
  • + +
  • 新接口管理
  • +
  • 单元测试
  • +
  • 脑图