├── _CNAME ├── data └── data.csv ├── pre-commit ├── css └── style.css ├── index.html ├── README.MD ├── js ├── mustache.min.js └── list.js └── license.md /_CNAME: -------------------------------------------------------------------------------- 1 | expo.your_hackathon.site 2 | -------------------------------------------------------------------------------- /data/data.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nealrs/expo/HEAD/data/data.csv -------------------------------------------------------------------------------- /pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #-*- mode: python -*- 3 | 4 | import csv 5 | import json 6 | import os 7 | import sys 8 | 9 | d = {} 10 | #c = open('data/'+sys.argv[1]+'.csv', 'rtU') 11 | c = open('data/data.csv', 'rtU') 12 | 13 | # only encodes project name, table/expo, sponsors, and link. 14 | # and yes, unicode sucks and so i'm clobbering all the impossible / trouble maker characters. 15 | 16 | try: 17 | reader = csv.reader(c) 18 | for row in reader: 19 | d[row[2].decode('utf-8', 'ignore').encode('ascii', 'ignore')] = {"expo": row[0].decode('utf-8', 'ignore').encode('ascii', 'ignore'), "table": row[1].decode('utf-8', 'ignore').encode('ascii'), "sponsors": row[3].decode('utf-8', 'ignore').encode('ascii', 'ignore'), "link": row[4].decode('utf-8', 'ignore').encode('ascii')} 20 | 21 | finally: 22 | c.close() 23 | 24 | #print json.dumps(d) 25 | 26 | #with open('data/'+sys.argv[1]+'.json', 'w') as j: 27 | with open('data/json', 'w') as j: 28 | json.dump(d, j) 29 | 30 | print "creating json file. you MAY need to maker another commit & push it up." 31 | sys.exit(0) 32 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | .container {max-width: 800px; margin: 0 auto; overflow: auto;} 2 | 3 | h3 {padding-top: 18px;} 4 | h1 { 5 | font-size: 36px; 6 | padding-top: .5rem; 7 | margin-top:0px; 8 | margin-bottom:0px; 9 | } 10 | 11 | table { 12 | border-spacing: 0; width: 100%; 13 | background-color: #FFF; 14 | border-collapse: collapse; 15 | } 16 | 17 | tbody tr:nth-child(odd) { 18 | background-color: #F0F0F0; 19 | 20 | } 21 | 22 | th, td { 23 | text-align: left; 24 | vertical-align: middle; 25 | padding: 8px; 26 | } 27 | 28 | th.number, 29 | td.number { 30 | width: 10%; 31 | } 32 | 33 | th.name, 34 | td.name { 35 | width: 40%; 36 | } 37 | 38 | th.prize, 39 | td.prize { 40 | width: 40%; 41 | } 42 | 43 | th.cat, 44 | td.cat { 45 | width: 10%; 46 | } 47 | 48 | h1 a, #footer a{ 49 | text-decoration: none; 50 | border:none; 51 | } 52 | 53 | td a {line-height: 24px;} 54 | tr {height: 50px;} 55 | ul, ol {text-indent: 0; margin: 0; padding-left: 20px;} 56 | ul li {padding-bottom: 6px; line-height: 22px;} 57 | 58 | .half {max-width: 50%; display: inline-block; vertical-align: top;} 59 | .half:nth-child(odd) {padding-left: 20px;} 60 | 61 | /* older css */ 62 | 63 | body { 64 | font-family: sans-serif; 65 | font-size: 16px; 66 | 67 | color: #062946; 68 | background-color:#fff; 69 | 70 | margin: 0; 71 | padding: 0; 72 | overflow: auto; 73 | } 74 | 75 | 76 | img {width: 100%;} 77 | hr {border: 2px solid #CCF4FF;} 78 | 79 | p a, a { 80 | color: #062946; 81 | text-decoration: none; 82 | padding-bottom: 0px; 83 | border-bottom: 2px #CCCCCC dotted; 84 | } 85 | a:hover {color: #36648B;} 86 | a:active {color: #36648B;} 87 | small {padding: 10px 0px;} 88 | p, ol {line-height: 1.4;} 89 | text {font-size: 12px;} 90 | 91 | body.index p:nth-of-type(2) {font-size: 30px;} 92 | body.index table {border: 4px solid #CCF4FF; padding: 18px;} 93 | .home-link {color: #47CCFC;} 94 | 95 | /* funsies */ 96 | /*::selection {background: #44FFB4;} 97 | ::-moz-selection {background: #44FFB4;}*/ 98 | 99 | /* filter css */ 100 | 101 | input { 102 | border: 1px solid #ccc; 103 | margin: 16px 0px; 104 | width: 90%; 105 | font-size: 16px; 106 | padding: 8px; 107 | font-family: sans-serif; 108 | } 109 | .search_container{ 110 | text-align:center; 111 | } 112 | 113 | #header { 114 | width:800px; 115 | background-color:#fff; 116 | color:#062946; 117 | z-index:999999; 118 | text-align:center; 119 | } 120 | 121 | #footer{ 122 | background-color: #fff; 123 | color: #062946; 124 | text-align: center; 125 | padding-bottom: 1rem; 126 | } 127 | 128 | #hackathon { 129 | margin: 30px 0 10px 0; 130 | } 131 | 132 | 133 | @media (max-width: 768px) { 134 | #header { 135 | width: 100%; 136 | } 137 | 138 | input { 139 | width: 90%; 140 | margin-left: 8px; 141 | } 142 | 143 | th.number, 144 | td.number { 145 | width: 20%; 146 | } 147 | 148 | th.name, 149 | td.name { 150 | width: 30%; 151 | } 152 | 153 | th.prize, 154 | td.prize { 155 | width: 50%; 156 | } 157 | 158 | th.cat, 159 | td.cat { 160 | display:none; 161 | } 162 | 163 | #hackathon { 164 | margin: 30px 0 10px 8px; 165 | } 166 | 167 | #footer p{ 168 | text-align:left; 169 | padding:0 10px; 170 | } 171 | } 172 | 173 | @media print { 174 | body { 175 | color: black !important; 176 | background: #FFF; 177 | } 178 | 179 | a { 180 | color: black !important; 181 | } 182 | 183 | #header, #footer { 184 | background-color:#fff; 185 | color: black; 186 | } 187 | .search_container{ 188 | background-color:#fff; 189 | } 190 | 191 | th.cat, 192 | td.cat { 193 | display:none; 194 | } 195 | 196 | tr { 197 | page-break-inside:avoid; 198 | page-break-after:auto; 199 | } 200 | 201 | tbody tr{ 202 | background-color: #fff !important; 203 | border-top: 1px solid #ccc; 204 | border-bottom: 1px solid #ccc; 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | HackathonName Expo 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 | 44 |
45 |
46 | 47 | 72 |
73 | 82 | 83 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # Devpost Expo / Table Number App 2 | 3 | ## What is it? 4 | 5 | This is a [mobile-ready website](http://nealrs.github.io/expo/) for distributing and filtering table numbers at your hackathon expo. [Here's an example](http://nealrs.github.io/mhacks6/) from MHacks 6, where we had over 250 projects. 6 | 7 | Everything is rendered client-side and the site is hosted on GitHub pages, so there's no backend / scaling issues to worry about. All you have to do is update the `data.csv` file and push it up to your `gh-pages` branch. 8 | 9 | [You can read about the history of this project](http://devpost.com/software/hackathon-table-numbers) on Devpost. 10 | 11 | ## How to use this app 12 | 13 | ### Local setup 14 | 15 | 1. [Fork this repository](https://github.com/nealrs/expo#fork-destination-box) or clone it to your local machine 16 | 17 | `git clone https://github.com/nealrs/expo.git` 18 | 19 | 2. Fire up a local webserver in your development directory (just for testing) 20 | 21 | `python -m SimpleHTTPServer` 22 | 23 | If you want to livereload changes, I suggest using [livereload](https://github.com/lepture/python-livereload). Otherwise you'll have to press refresh in your browser a lot (no big deal). 24 | 25 | 3. Go to [http://localhost:8000](http://localhost:8000) ( [localhost:35729](http://localhost:35729) if you're using livereload) to see the local app. 26 | 27 | It should look like this: 28 | 29 | ![](http://i.imgur.com/sf0FlXd.png) 30 | 31 | ### Adding your hackathon data 32 | 33 | 1. Open up `index.html` and locate the following code blocks: 34 | 35 | ```html 36 | HackathonName Expo 37 | 38 |
39 | 42 |
43 |
44 | ``` 45 | 46 | - Change `HackathonName` to the name of your hackathon (e.g. PennApps XII) 47 | - Change `DevpostURL` to your hackathon's Devpost URL (e.g. http://mhacks6.devpost.com) 48 | - Add your own favicon & hackathon logo, we've put some placeholders in for now. 49 | 50 | 2. Open `data.csv` in **MS Excel or another spreadsheet app** 51 | 52 | ![](http://i.imgur.com/uDbPhe3.png) 53 | 54 | There are 5 columns in this sheet: 55 | - `expo` - Expo number (optional for large hackathons) 56 | - `table` - Table number 57 | - `project` - Project Name 58 | - `sponsors` - Applicable sponsor prizes 59 | - `link` - Link to project's Devpost page 60 | - `category` - Optional data field for additional filtering 61 | - `special`- Additional optional data field 62 | 63 | This is where you'll paste in submission data & assign table numbers. If you don't need the optional `category` or `special` columns, you can delete them from the spreadsheet, and also comment them out in the code as shown: 64 | 65 | ```html 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | {{#data}} 77 | 78 | 79 | 80 | 81 | 82 | 83 | {{/data}} 84 | 85 |
TableProjectSponsor Prizes
E{{expo}} T{{table}}{{project}}{{sponsors}}
86 | ``` 87 | 88 | I'd also recommend commenting out the `E{{expo}} ` tag unless you're running multiple expos. 89 | 90 | 3. Once the submission deadline is over, Go to the metrics tab on your hackathon dashboard and run a submissions export, _without_ PII. 91 | 92 | ![](http://i.imgur.com/8YIT03y.png) 93 | 94 | You'll receive a download link via email. Once you download the export, (it's a CSV) open it up in Excel and copy the following columns into their matching columns in `data.csv`: 95 | 96 | - `Submission Title` (A) -> `project` (C) 97 | - `Submission Url` (B) -> `link` (E) 98 | - `Sponsor Prizes` (usually G or H) -> `sponsors` (D) 99 | - Repeat for `category` or `special` if you're using them. 100 | 101 | Save your CSV! 102 | 103 | 4. Assign Expo & table numbers 104 | 105 | The app _does not_ automatically assign table / expo numbers. We leave that up to you. There's no one-size-fits-all solution, so you can use whatever system works for you. However, every row should have a unique combination of Expo & table numbers. 106 | 107 | Once you're done, go back to your browser and make sure everything is loads correctly. 108 | 109 | **NOTE** Using Excel or a spreadsheet app is crucial right now. Do _not_ edit `data.csv` with a text editor. Quinlan, I'm looking at you :unamused:) 110 | 111 | **ALSO** You must save this file as a CSV and commit+push it GitHub to update the list online. 112 | 113 | 5. Once you're satisfied, save everything, commit it, and push it up to your `gh-pages` branch. 114 | 115 | Your table numbers will be live at http://your_github_username.github.io/expo 116 | 117 | ### Custom URLs 118 | 119 | If you have your own landing page / site for your hackathon, we suggest setting up a CNAME for a more user friendly URL. e.g. http://expo.funhacks.com. (It's a lot easier than http://derp78.github.com/hackathonname.) 120 | 121 | If you need help setting up a CNAME, [read this](https://help.github.com/articles/setting-up-a-custom-domain-with-github-pages/). 122 | 123 | # Filters & sponsors 124 | 125 | Finding specific hacks, filtering for keywords, and providing sponsors with their judging lists is SUPER EASY with the expo app. 126 | 127 | 1. You can use the search box to filter the entire table (all columns) based on any text string -- like hardware: 128 | 129 | ![](http://i.imgur.com/blRIYqK.png) 130 | 131 | 2. You can set the filter by using URL parameters 132 | 133 | Try this, add `?filter=SOME_API_NAME` to your url to create a unique, filtered list for each of your sponsors. For example, here's a list of hacks that mention Twilio: 134 | 135 | ![](http://i.imgur.com/OAh4bwU.png) 136 | 137 | Email them the link so they know exactly which tables to go to -- or take it a step further and print them a copy. The app contains custom print styles that save paper & ink. 138 | 139 | ![](http://i.imgur.com/ap9ITUW.png) 140 | 141 | ### Mobile browsing 142 | 143 | We've included some 'sensible' mobile styles, which hide the category / special columns on small screens and collapse the borders. 144 | 145 | ## Dasss it! 146 | -------------------------------------------------------------------------------- /js/mustache.min.js: -------------------------------------------------------------------------------- 1 | (function defineMustache(global,factory){if(typeof exports==="object"&&exports&&typeof exports.nodeName!=="string"){factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],factory)}else{global.Mustache={};factory(Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)==="[object Array]"};function isFunction(object){return typeof object==="function"}function typeStr(obj){return isArray(obj)?"array":typeof obj}function escapeRegExp(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function hasProperty(obj,propName){return obj!=null&&typeof obj==="object"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};function escapeHtml(string){return String(string).replace(/[&<>"'\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){value=context.view;names=name.split(".");index=0;while(value!=null&&index")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | {one line to give the program's name and a brief idea of what it does.} 635 | Copyright (C) {year} {name of author} 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | {project} Copyright (C) {year} {fullname} 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /js/list.js: -------------------------------------------------------------------------------- 1 | ;(function(){ 2 | 3 | /** 4 | * Require the given path. 5 | * 6 | * @param {String} path 7 | * @return {Object} exports 8 | * @api public 9 | */ 10 | 11 | function require(path, parent, orig) { 12 | var resolved = require.resolve(path); 13 | 14 | // lookup failed 15 | if (null == resolved) { 16 | orig = orig || path; 17 | parent = parent || 'root'; 18 | var err = new Error('Failed to require "' + orig + '" from "' + parent + '"'); 19 | err.path = orig; 20 | err.parent = parent; 21 | err.require = true; 22 | throw err; 23 | } 24 | 25 | var module = require.modules[resolved]; 26 | 27 | // perform real require() 28 | // by invoking the module's 29 | // registered function 30 | if (!module._resolving && !module.exports) { 31 | var mod = {}; 32 | mod.exports = {}; 33 | mod.client = mod.component = true; 34 | module._resolving = true; 35 | module.call(this, mod.exports, require.relative(resolved), mod); 36 | delete module._resolving; 37 | module.exports = mod.exports; 38 | } 39 | 40 | return module.exports; 41 | } 42 | 43 | /** 44 | * Registered modules. 45 | */ 46 | 47 | require.modules = {}; 48 | 49 | /** 50 | * Registered aliases. 51 | */ 52 | 53 | require.aliases = {}; 54 | 55 | /** 56 | * Resolve `path`. 57 | * 58 | * Lookup: 59 | * 60 | * - PATH/index.js 61 | * - PATH.js 62 | * - PATH 63 | * 64 | * @param {String} path 65 | * @return {String} path or null 66 | * @api private 67 | */ 68 | 69 | require.resolve = function(path) { 70 | if (path.charAt(0) === '/') path = path.slice(1); 71 | 72 | var paths = [ 73 | path, 74 | path + '.js', 75 | path + '.json', 76 | path + '/index.js', 77 | path + '/index.json' 78 | ]; 79 | 80 | for (var i = 0; i < paths.length; i++) { 81 | var path = paths[i]; 82 | if (require.modules.hasOwnProperty(path)) return path; 83 | if (require.aliases.hasOwnProperty(path)) return require.aliases[path]; 84 | } 85 | }; 86 | 87 | /** 88 | * Normalize `path` relative to the current path. 89 | * 90 | * @param {String} curr 91 | * @param {String} path 92 | * @return {String} 93 | * @api private 94 | */ 95 | 96 | require.normalize = function(curr, path) { 97 | var segs = []; 98 | 99 | if ('.' != path.charAt(0)) return path; 100 | 101 | curr = curr.split('/'); 102 | path = path.split('/'); 103 | 104 | for (var i = 0; i < path.length; ++i) { 105 | if ('..' == path[i]) { 106 | curr.pop(); 107 | } else if ('.' != path[i] && '' != path[i]) { 108 | segs.push(path[i]); 109 | } 110 | } 111 | 112 | return curr.concat(segs).join('/'); 113 | }; 114 | 115 | /** 116 | * Register module at `path` with callback `definition`. 117 | * 118 | * @param {String} path 119 | * @param {Function} definition 120 | * @api private 121 | */ 122 | 123 | require.register = function(path, definition) { 124 | require.modules[path] = definition; 125 | }; 126 | 127 | /** 128 | * Alias a module definition. 129 | * 130 | * @param {String} from 131 | * @param {String} to 132 | * @api private 133 | */ 134 | 135 | require.alias = function(from, to) { 136 | if (!require.modules.hasOwnProperty(from)) { 137 | throw new Error('Failed to alias "' + from + '", it does not exist'); 138 | } 139 | require.aliases[to] = from; 140 | }; 141 | 142 | /** 143 | * Return a require function relative to the `parent` path. 144 | * 145 | * @param {String} parent 146 | * @return {Function} 147 | * @api private 148 | */ 149 | 150 | require.relative = function(parent) { 151 | var p = require.normalize(parent, '..'); 152 | 153 | /** 154 | * lastIndexOf helper. 155 | */ 156 | 157 | function lastIndexOf(arr, obj) { 158 | var i = arr.length; 159 | while (i--) { 160 | if (arr[i] === obj) return i; 161 | } 162 | return -1; 163 | } 164 | 165 | /** 166 | * The relative require() itself. 167 | */ 168 | 169 | function localRequire(path) { 170 | var resolved = localRequire.resolve(path); 171 | return require(resolved, parent, path); 172 | } 173 | 174 | /** 175 | * Resolve relative to the parent. 176 | */ 177 | 178 | localRequire.resolve = function(path) { 179 | var c = path.charAt(0); 180 | if ('/' == c) return path.slice(1); 181 | if ('.' == c) return require.normalize(p, path); 182 | 183 | // resolve deps by returning 184 | // the dep in the nearest "deps" 185 | // directory 186 | var segs = parent.split('/'); 187 | var i = lastIndexOf(segs, 'deps') + 1; 188 | if (!i) i = 0; 189 | path = segs.slice(0, i + 1).join('/') + '/deps/' + path; 190 | return path; 191 | }; 192 | 193 | /** 194 | * Check if module is defined at `path`. 195 | */ 196 | 197 | localRequire.exists = function(path) { 198 | return require.modules.hasOwnProperty(localRequire.resolve(path)); 199 | }; 200 | 201 | return localRequire; 202 | }; 203 | require.register("component-classes/index.js", function(exports, require, module){ 204 | /** 205 | * Module dependencies. 206 | */ 207 | 208 | var index = require('indexof'); 209 | 210 | /** 211 | * Whitespace regexp. 212 | */ 213 | 214 | var re = /\s+/; 215 | 216 | /** 217 | * toString reference. 218 | */ 219 | 220 | var toString = Object.prototype.toString; 221 | 222 | /** 223 | * Wrap `el` in a `ClassList`. 224 | * 225 | * @param {Element} el 226 | * @return {ClassList} 227 | * @api public 228 | */ 229 | 230 | module.exports = function(el){ 231 | return new ClassList(el); 232 | }; 233 | 234 | /** 235 | * Initialize a new ClassList for `el`. 236 | * 237 | * @param {Element} el 238 | * @api private 239 | */ 240 | 241 | function ClassList(el) { 242 | if (!el) throw new Error('A DOM element reference is required'); 243 | this.el = el; 244 | this.list = el.classList; 245 | } 246 | 247 | /** 248 | * Add class `name` if not already present. 249 | * 250 | * @param {String} name 251 | * @return {ClassList} 252 | * @api public 253 | */ 254 | 255 | ClassList.prototype.add = function(name){ 256 | // classList 257 | if (this.list) { 258 | this.list.add(name); 259 | return this; 260 | } 261 | 262 | // fallback 263 | var arr = this.array(); 264 | var i = index(arr, name); 265 | if (!~i) arr.push(name); 266 | this.el.className = arr.join(' '); 267 | return this; 268 | }; 269 | 270 | /** 271 | * Remove class `name` when present, or 272 | * pass a regular expression to remove 273 | * any which match. 274 | * 275 | * @param {String|RegExp} name 276 | * @return {ClassList} 277 | * @api public 278 | */ 279 | 280 | ClassList.prototype.remove = function(name){ 281 | if ('[object RegExp]' == toString.call(name)) { 282 | return this.removeMatching(name); 283 | } 284 | 285 | // classList 286 | if (this.list) { 287 | this.list.remove(name); 288 | return this; 289 | } 290 | 291 | // fallback 292 | var arr = this.array(); 293 | var i = index(arr, name); 294 | if (~i) arr.splice(i, 1); 295 | this.el.className = arr.join(' '); 296 | return this; 297 | }; 298 | 299 | /** 300 | * Remove all classes matching `re`. 301 | * 302 | * @param {RegExp} re 303 | * @return {ClassList} 304 | * @api private 305 | */ 306 | 307 | ClassList.prototype.removeMatching = function(re){ 308 | var arr = this.array(); 309 | for (var i = 0; i < arr.length; i++) { 310 | if (re.test(arr[i])) { 311 | this.remove(arr[i]); 312 | } 313 | } 314 | return this; 315 | }; 316 | 317 | /** 318 | * Toggle class `name`, can force state via `force`. 319 | * 320 | * For browsers that support classList, but do not support `force` yet, 321 | * the mistake will be detected and corrected. 322 | * 323 | * @param {String} name 324 | * @param {Boolean} force 325 | * @return {ClassList} 326 | * @api public 327 | */ 328 | 329 | ClassList.prototype.toggle = function(name, force){ 330 | // classList 331 | if (this.list) { 332 | if ("undefined" !== typeof force) { 333 | if (force !== this.list.toggle(name, force)) { 334 | this.list.toggle(name); // toggle again to correct 335 | } 336 | } else { 337 | this.list.toggle(name); 338 | } 339 | return this; 340 | } 341 | 342 | // fallback 343 | if ("undefined" !== typeof force) { 344 | if (!force) { 345 | this.remove(name); 346 | } else { 347 | this.add(name); 348 | } 349 | } else { 350 | if (this.has(name)) { 351 | this.remove(name); 352 | } else { 353 | this.add(name); 354 | } 355 | } 356 | 357 | return this; 358 | }; 359 | 360 | /** 361 | * Return an array of classes. 362 | * 363 | * @return {Array} 364 | * @api public 365 | */ 366 | 367 | ClassList.prototype.array = function(){ 368 | var str = this.el.className.replace(/^\s+|\s+$/g, ''); 369 | var arr = str.split(re); 370 | if ('' === arr[0]) arr.shift(); 371 | return arr; 372 | }; 373 | 374 | /** 375 | * Check if class `name` is present. 376 | * 377 | * @param {String} name 378 | * @return {ClassList} 379 | * @api public 380 | */ 381 | 382 | ClassList.prototype.has = 383 | ClassList.prototype.contains = function(name){ 384 | return this.list 385 | ? this.list.contains(name) 386 | : !! ~index(this.array(), name); 387 | }; 388 | 389 | }); 390 | require.register("segmentio-extend/index.js", function(exports, require, module){ 391 | 392 | module.exports = function extend (object) { 393 | // Takes an unlimited number of extenders. 394 | var args = Array.prototype.slice.call(arguments, 1); 395 | 396 | // For each extender, copy their properties on our object. 397 | for (var i = 0, source; source = args[i]; i++) { 398 | if (!source) continue; 399 | for (var property in source) { 400 | object[property] = source[property]; 401 | } 402 | } 403 | 404 | return object; 405 | }; 406 | }); 407 | require.register("component-indexof/index.js", function(exports, require, module){ 408 | module.exports = function(arr, obj){ 409 | if (arr.indexOf) return arr.indexOf(obj); 410 | for (var i = 0; i < arr.length; ++i) { 411 | if (arr[i] === obj) return i; 412 | } 413 | return -1; 414 | }; 415 | }); 416 | require.register("component-event/index.js", function(exports, require, module){ 417 | var bind = window.addEventListener ? 'addEventListener' : 'attachEvent', 418 | unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent', 419 | prefix = bind !== 'addEventListener' ? 'on' : ''; 420 | 421 | /** 422 | * Bind `el` event `type` to `fn`. 423 | * 424 | * @param {Element} el 425 | * @param {String} type 426 | * @param {Function} fn 427 | * @param {Boolean} capture 428 | * @return {Function} 429 | * @api public 430 | */ 431 | 432 | exports.bind = function(el, type, fn, capture){ 433 | el[bind](prefix + type, fn, capture || false); 434 | return fn; 435 | }; 436 | 437 | /** 438 | * Unbind `el` event `type`'s callback `fn`. 439 | * 440 | * @param {Element} el 441 | * @param {String} type 442 | * @param {Function} fn 443 | * @param {Boolean} capture 444 | * @return {Function} 445 | * @api public 446 | */ 447 | 448 | exports.unbind = function(el, type, fn, capture){ 449 | el[unbind](prefix + type, fn, capture || false); 450 | return fn; 451 | }; 452 | }); 453 | require.register("timoxley-to-array/index.js", function(exports, require, module){ 454 | /** 455 | * Convert an array-like object into an `Array`. 456 | * If `collection` is already an `Array`, then will return a clone of `collection`. 457 | * 458 | * @param {Array | Mixed} collection An `Array` or array-like object to convert e.g. `arguments` or `NodeList` 459 | * @return {Array} Naive conversion of `collection` to a new `Array`. 460 | * @api public 461 | */ 462 | 463 | module.exports = function toArray(collection) { 464 | if (typeof collection === 'undefined') return [] 465 | if (collection === null) return [null] 466 | if (collection === window) return [window] 467 | if (typeof collection === 'string') return [collection] 468 | if (isArray(collection)) return collection 469 | if (typeof collection.length != 'number') return [collection] 470 | if (typeof collection === 'function' && collection instanceof Function) return [collection] 471 | 472 | var arr = [] 473 | for (var i = 0; i < collection.length; i++) { 474 | if (Object.prototype.hasOwnProperty.call(collection, i) || i in collection) { 475 | arr.push(collection[i]) 476 | } 477 | } 478 | if (!arr.length) return [] 479 | return arr 480 | } 481 | 482 | function isArray(arr) { 483 | return Object.prototype.toString.call(arr) === "[object Array]"; 484 | } 485 | 486 | }); 487 | require.register("javve-events/index.js", function(exports, require, module){ 488 | var events = require('event'), 489 | toArray = require('to-array'); 490 | 491 | /** 492 | * Bind `el` event `type` to `fn`. 493 | * 494 | * @param {Element} el, NodeList, HTMLCollection or Array 495 | * @param {String} type 496 | * @param {Function} fn 497 | * @param {Boolean} capture 498 | * @api public 499 | */ 500 | 501 | exports.bind = function(el, type, fn, capture){ 502 | el = toArray(el); 503 | for ( var i = 0; i < el.length; i++ ) { 504 | events.bind(el[i], type, fn, capture); 505 | } 506 | }; 507 | 508 | /** 509 | * Unbind `el` event `type`'s callback `fn`. 510 | * 511 | * @param {Element} el, NodeList, HTMLCollection or Array 512 | * @param {String} type 513 | * @param {Function} fn 514 | * @param {Boolean} capture 515 | * @api public 516 | */ 517 | 518 | exports.unbind = function(el, type, fn, capture){ 519 | el = toArray(el); 520 | for ( var i = 0; i < el.length; i++ ) { 521 | events.unbind(el[i], type, fn, capture); 522 | } 523 | }; 524 | 525 | }); 526 | require.register("javve-get-by-class/index.js", function(exports, require, module){ 527 | /** 528 | * Find all elements with class `className` inside `container`. 529 | * Use `single = true` to increase performance in older browsers 530 | * when only one element is needed. 531 | * 532 | * @param {String} className 533 | * @param {Element} container 534 | * @param {Boolean} single 535 | * @api public 536 | */ 537 | 538 | module.exports = (function() { 539 | if (document.getElementsByClassName) { 540 | return function(container, className, single) { 541 | if (single) { 542 | return container.getElementsByClassName(className)[0]; 543 | } else { 544 | return container.getElementsByClassName(className); 545 | } 546 | }; 547 | } else if (document.querySelector) { 548 | return function(container, className, single) { 549 | className = '.' + className; 550 | if (single) { 551 | return container.querySelector(className); 552 | } else { 553 | return container.querySelectorAll(className); 554 | } 555 | }; 556 | } else { 557 | return function(container, className, single) { 558 | var classElements = [], 559 | tag = '*'; 560 | if (container == null) { 561 | container = document; 562 | } 563 | var els = container.getElementsByTagName(tag); 564 | var elsLen = els.length; 565 | var pattern = new RegExp("(^|\\s)"+className+"(\\s|$)"); 566 | for (var i = 0, j = 0; i < elsLen; i++) { 567 | if ( pattern.test(els[i].className) ) { 568 | if (single) { 569 | return els[i]; 570 | } else { 571 | classElements[j] = els[i]; 572 | j++; 573 | } 574 | } 575 | } 576 | return classElements; 577 | }; 578 | } 579 | })(); 580 | 581 | }); 582 | require.register("javve-get-attribute/index.js", function(exports, require, module){ 583 | /** 584 | * Return the value for `attr` at `element`. 585 | * 586 | * @param {Element} el 587 | * @param {String} attr 588 | * @api public 589 | */ 590 | 591 | module.exports = function(el, attr) { 592 | var result = (el.getAttribute && el.getAttribute(attr)) || null; 593 | if( !result ) { 594 | var attrs = el.attributes; 595 | var length = attrs.length; 596 | for(var i = 0; i < length; i++) { 597 | if (attr[i] !== undefined) { 598 | if(attr[i].nodeName === attr) { 599 | result = attr[i].nodeValue; 600 | } 601 | } 602 | } 603 | } 604 | return result; 605 | } 606 | }); 607 | require.register("javve-natural-sort/index.js", function(exports, require, module){ 608 | /* 609 | * Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license 610 | * Author: Jim Palmer (based on chunking idea from Dave Koelle) 611 | */ 612 | 613 | module.exports = function(a, b, options) { 614 | var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi, 615 | sre = /(^[ ]*|[ ]*$)/g, 616 | dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, 617 | hre = /^0x[0-9a-f]+$/i, 618 | ore = /^0/, 619 | options = options || {}, 620 | i = function(s) { return options.insensitive && (''+s).toLowerCase() || ''+s }, 621 | // convert all to strings strip whitespace 622 | x = i(a).replace(sre, '') || '', 623 | y = i(b).replace(sre, '') || '', 624 | // chunk/tokenize 625 | xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'), 626 | yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'), 627 | // numeric, hex or date detection 628 | xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)), 629 | yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null, 630 | oFxNcL, oFyNcL, 631 | mult = options.desc ? -1 : 1; 632 | // first try and sort Hex codes or Dates 633 | if (yD) 634 | if ( xD < yD ) return -1 * mult; 635 | else if ( xD > yD ) return 1 * mult; 636 | // natural sorting through split numeric strings and default strings 637 | for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) { 638 | // find floats not starting with '0', string or 0 if not defined (Clint Priest) 639 | oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0; 640 | oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0; 641 | // handle numeric vs string comparison - number < string - (Kyle Adams) 642 | if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { return (isNaN(oFxNcL)) ? 1 : -1; } 643 | // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' 644 | else if (typeof oFxNcL !== typeof oFyNcL) { 645 | oFxNcL += ''; 646 | oFyNcL += ''; 647 | } 648 | if (oFxNcL < oFyNcL) return -1 * mult; 649 | if (oFxNcL > oFyNcL) return 1 * mult; 650 | } 651 | return 0; 652 | }; 653 | 654 | /* 655 | var defaultSort = getSortFunction(); 656 | 657 | module.exports = function(a, b, options) { 658 | if (arguments.length == 1) { 659 | options = a; 660 | return getSortFunction(options); 661 | } else { 662 | return defaultSort(a,b); 663 | } 664 | } 665 | */ 666 | }); 667 | require.register("javve-to-string/index.js", function(exports, require, module){ 668 | module.exports = function(s) { 669 | s = (s === undefined) ? "" : s; 670 | s = (s === null) ? "" : s; 671 | s = s.toString(); 672 | return s; 673 | }; 674 | 675 | }); 676 | require.register("component-type/index.js", function(exports, require, module){ 677 | /** 678 | * toString ref. 679 | */ 680 | 681 | var toString = Object.prototype.toString; 682 | 683 | /** 684 | * Return the type of `val`. 685 | * 686 | * @param {Mixed} val 687 | * @return {String} 688 | * @api public 689 | */ 690 | 691 | module.exports = function(val){ 692 | switch (toString.call(val)) { 693 | case '[object Date]': return 'date'; 694 | case '[object RegExp]': return 'regexp'; 695 | case '[object Arguments]': return 'arguments'; 696 | case '[object Array]': return 'array'; 697 | case '[object Error]': return 'error'; 698 | } 699 | 700 | if (val === null) return 'null'; 701 | if (val === undefined) return 'undefined'; 702 | if (val !== val) return 'nan'; 703 | if (val && val.nodeType === 1) return 'element'; 704 | 705 | return typeof val.valueOf(); 706 | }; 707 | 708 | }); 709 | require.register("list.js/index.js", function(exports, require, module){ 710 | /* 711 | ListJS with beta 1.0.0 712 | By Jonny Strömberg (www.jonnystromberg.com, www.listjs.com) 713 | */ 714 | (function( window, undefined ) { 715 | "use strict"; 716 | 717 | var document = window.document, 718 | getByClass = require('get-by-class'), 719 | extend = require('extend'), 720 | indexOf = require('indexof'); 721 | 722 | var List = function(id, options, values) { 723 | 724 | var self = this, 725 | init, 726 | Item = require('./src/item')(self), 727 | addAsync = require('./src/add-async')(self), 728 | parse = require('./src/parse')(self); 729 | 730 | init = { 731 | start: function() { 732 | self.listClass = "list"; 733 | self.searchClass = "search"; 734 | self.sortClass = "sort"; 735 | self.page = 200; 736 | self.i = 1; 737 | self.items = []; 738 | self.visibleItems = []; 739 | self.matchingItems = []; 740 | self.searched = false; 741 | self.filtered = false; 742 | self.handlers = { 'updated': [] }; 743 | self.plugins = {}; 744 | self.helpers = { 745 | getByClass: getByClass, 746 | extend: extend, 747 | indexOf: indexOf 748 | }; 749 | 750 | extend(self, options); 751 | 752 | self.listContainer = (typeof(id) === 'string') ? document.getElementById(id) : id; 753 | if (!self.listContainer) { return; } 754 | self.list = getByClass(self.listContainer, self.listClass, true); 755 | 756 | self.templater = require('./src/templater')(self); 757 | self.search = require('./src/search')(self); 758 | self.filter = require('./src/filter')(self); 759 | self.sort = require('./src/sort')(self); 760 | 761 | this.items(); 762 | self.update(); 763 | this.plugins(); 764 | }, 765 | items: function() { 766 | parse(self.list); 767 | if (values !== undefined) { 768 | self.add(values); 769 | } 770 | }, 771 | plugins: function() { 772 | for (var i = 0; i < self.plugins.length; i++) { 773 | var plugin = self.plugins[i]; 774 | self[plugin.name] = plugin; 775 | plugin.init(self); 776 | } 777 | } 778 | }; 779 | 780 | 781 | /* 782 | * Add object to list 783 | */ 784 | this.add = function(values, callback) { 785 | if (callback) { 786 | addAsync(values, callback); 787 | return; 788 | } 789 | var added = [], 790 | notCreate = false; 791 | if (values[0] === undefined){ 792 | values = [values]; 793 | } 794 | for (var i = 0, il = values.length; i < il; i++) { 795 | var item = null; 796 | if (values[i] instanceof Item) { 797 | item = values[i]; 798 | item.reload(); 799 | } else { 800 | notCreate = (self.items.length > self.page) ? true : false; 801 | item = new Item(values[i], undefined, notCreate); 802 | } 803 | self.items.push(item); 804 | added.push(item); 805 | } 806 | self.update(); 807 | return added; 808 | }; 809 | 810 | this.show = function(i, page) { 811 | this.i = i; 812 | this.page = page; 813 | self.update(); 814 | return self; 815 | }; 816 | 817 | /* Removes object from list. 818 | * Loops through the list and removes objects where 819 | * property "valuename" === value 820 | */ 821 | this.remove = function(valueName, value, options) { 822 | var found = 0; 823 | for (var i = 0, il = self.items.length; i < il; i++) { 824 | if (self.items[i].values()[valueName] == value) { 825 | self.templater.remove(self.items[i], options); 826 | self.items.splice(i,1); 827 | il--; 828 | i--; 829 | found++; 830 | } 831 | } 832 | self.update(); 833 | return found; 834 | }; 835 | 836 | /* Gets the objects in the list which 837 | * property "valueName" === value 838 | */ 839 | this.get = function(valueName, value) { 840 | var matchedItems = []; 841 | for (var i = 0, il = self.items.length; i < il; i++) { 842 | var item = self.items[i]; 843 | if (item.values()[valueName] == value) { 844 | matchedItems.push(item); 845 | } 846 | } 847 | return matchedItems; 848 | }; 849 | 850 | /* 851 | * Get size of the list 852 | */ 853 | this.size = function() { 854 | return self.items.length; 855 | }; 856 | 857 | /* 858 | * Removes all items from the list 859 | */ 860 | this.clear = function() { 861 | self.templater.clear(); 862 | self.items = []; 863 | return self; 864 | }; 865 | 866 | this.on = function(event, callback) { 867 | self.handlers[event].push(callback); 868 | return self; 869 | }; 870 | 871 | this.off = function(event, callback) { 872 | var e = self.handlers[event]; 873 | var index = indexOf(e, callback); 874 | if (index > -1) { 875 | e.splice(index, 1); 876 | } 877 | return self; 878 | }; 879 | 880 | this.trigger = function(event) { 881 | var i = self.handlers[event].length; 882 | while(i--) { 883 | self.handlers[event][i](self); 884 | } 885 | return self; 886 | }; 887 | 888 | this.reset = { 889 | filter: function() { 890 | var is = self.items, 891 | il = is.length; 892 | while (il--) { 893 | is[il].filtered = false; 894 | } 895 | return self; 896 | }, 897 | search: function() { 898 | var is = self.items, 899 | il = is.length; 900 | while (il--) { 901 | is[il].found = false; 902 | } 903 | return self; 904 | } 905 | }; 906 | 907 | this.update = function() { 908 | var is = self.items, 909 | il = is.length; 910 | 911 | self.visibleItems = []; 912 | self.matchingItems = []; 913 | self.templater.clear(); 914 | for (var i = 0; i < il; i++) { 915 | if (is[i].matching() && ((self.matchingItems.length+1) >= self.i && self.visibleItems.length < self.page)) { 916 | is[i].show(); 917 | self.visibleItems.push(is[i]); 918 | self.matchingItems.push(is[i]); 919 | } else if (is[i].matching()) { 920 | self.matchingItems.push(is[i]); 921 | is[i].hide(); 922 | } else { 923 | is[i].hide(); 924 | } 925 | } 926 | self.trigger('updated'); 927 | return self; 928 | }; 929 | 930 | init.start(); 931 | }; 932 | 933 | module.exports = List; 934 | 935 | })(window); 936 | 937 | }); 938 | require.register("list.js/src/search.js", function(exports, require, module){ 939 | var events = require('events'), 940 | getByClass = require('get-by-class'), 941 | toString = require('to-string'); 942 | 943 | module.exports = function(list) { 944 | var item, 945 | text, 946 | columns, 947 | searchString, 948 | customSearch; 949 | 950 | var prepare = { 951 | resetList: function() { 952 | list.i = 1; 953 | list.templater.clear(); 954 | customSearch = undefined; 955 | }, 956 | setOptions: function(args) { 957 | if (args.length == 2 && args[1] instanceof Array) { 958 | columns = args[1]; 959 | } else if (args.length == 2 && typeof(args[1]) == "function") { 960 | customSearch = args[1]; 961 | } else if (args.length == 3) { 962 | columns = args[1]; 963 | customSearch = args[2]; 964 | } 965 | }, 966 | setColumns: function() { 967 | columns = (columns === undefined) ? prepare.toArray(list.items[0].values()) : columns; 968 | }, 969 | setSearchString: function(s) { 970 | s = toString(s).toLowerCase(); 971 | s = s.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&"); // Escape regular expression characters 972 | searchString = s; 973 | }, 974 | toArray: function(values) { 975 | var tmpColumn = []; 976 | for (var name in values) { 977 | tmpColumn.push(name); 978 | } 979 | return tmpColumn; 980 | } 981 | }; 982 | var search = { 983 | list: function() { 984 | for (var k = 0, kl = list.items.length; k < kl; k++) { 985 | search.item(list.items[k]); 986 | } 987 | }, 988 | item: function(item) { 989 | item.found = false; 990 | for (var j = 0, jl = columns.length; j < jl; j++) { 991 | if (search.values(item.values(), columns[j])) { 992 | item.found = true; 993 | return; 994 | } 995 | } 996 | }, 997 | values: function(values, column) { 998 | if (values.hasOwnProperty(column)) { 999 | text = toString(values[column]).toLowerCase(); 1000 | if ((searchString !== "") && (text.search(searchString) > -1)) { 1001 | return true; 1002 | } 1003 | } 1004 | return false; 1005 | }, 1006 | reset: function() { 1007 | list.reset.search(); 1008 | list.searched = false; 1009 | } 1010 | }; 1011 | 1012 | var searchMethod = function(str) { 1013 | list.trigger('searchStart'); 1014 | 1015 | prepare.resetList(); 1016 | prepare.setSearchString(str); 1017 | prepare.setOptions(arguments); // str, cols|searchFunction, searchFunction 1018 | prepare.setColumns(); 1019 | 1020 | if (searchString === "" ) { 1021 | search.reset(); 1022 | } else { 1023 | list.searched = true; 1024 | if (customSearch) { 1025 | customSearch(searchString, columns); 1026 | } else { 1027 | search.list(); 1028 | } 1029 | } 1030 | 1031 | list.update(); 1032 | list.trigger('searchComplete'); 1033 | return list.visibleItems; 1034 | }; 1035 | 1036 | list.handlers.searchStart = list.handlers.searchStart || []; 1037 | list.handlers.searchComplete = list.handlers.searchComplete || []; 1038 | 1039 | events.bind(getByClass(list.listContainer, list.searchClass), 'keyup', function(e) { 1040 | var target = e.target || e.srcElement, // IE have srcElement 1041 | alreadyCleared = (target.value === "" && !list.searched); 1042 | if (!alreadyCleared) { // If oninput already have resetted the list, do nothing 1043 | searchMethod(target.value); 1044 | } 1045 | }); 1046 | 1047 | // Used to detect click on HTML5 clear button 1048 | events.bind(getByClass(list.listContainer, list.searchClass), 'input', function(e) { 1049 | var target = e.target || e.srcElement; 1050 | if (target.value === "") { 1051 | searchMethod(''); 1052 | } 1053 | }); 1054 | 1055 | list.helpers.toString = toString; 1056 | return searchMethod; 1057 | }; 1058 | 1059 | }); 1060 | require.register("list.js/src/sort.js", function(exports, require, module){ 1061 | var naturalSort = require('natural-sort'), 1062 | classes = require('classes'), 1063 | events = require('events'), 1064 | getByClass = require('get-by-class'), 1065 | getAttribute = require('get-attribute'); 1066 | 1067 | module.exports = function(list) { 1068 | list.sortFunction = list.sortFunction || function(itemA, itemB, options) { 1069 | options.desc = options.order == "desc" ? true : false; // Natural sort uses this format 1070 | return naturalSort(itemA.values()[options.valueName], itemB.values()[options.valueName], options); 1071 | }; 1072 | 1073 | var buttons = { 1074 | els: undefined, 1075 | clear: function() { 1076 | for (var i = 0, il = buttons.els.length; i < il; i++) { 1077 | classes(buttons.els[i]).remove('asc'); 1078 | classes(buttons.els[i]).remove('desc'); 1079 | } 1080 | }, 1081 | getOrder: function(btn) { 1082 | var predefinedOrder = getAttribute(btn, 'data-order'); 1083 | if (predefinedOrder == "asc" || predefinedOrder == "desc") { 1084 | return predefinedOrder; 1085 | } else if (classes(btn).has('desc')) { 1086 | return "asc"; 1087 | } else if (classes(btn).has('asc')) { 1088 | return "desc"; 1089 | } else { 1090 | return "asc"; 1091 | } 1092 | }, 1093 | getInSensitive: function(btn, options) { 1094 | var insensitive = getAttribute(btn, 'data-insensitive'); 1095 | if (insensitive === "true") { 1096 | options.insensitive = true; 1097 | } else { 1098 | options.insensitive = false; 1099 | } 1100 | }, 1101 | setOrder: function(options) { 1102 | for (var i = 0, il = buttons.els.length; i < il; i++) { 1103 | var btn = buttons.els[i]; 1104 | if (getAttribute(btn, 'data-sort') !== options.valueName) { 1105 | continue; 1106 | } 1107 | var predefinedOrder = getAttribute(btn, 'data-order'); 1108 | if (predefinedOrder == "asc" || predefinedOrder == "desc") { 1109 | if (predefinedOrder == options.order) { 1110 | classes(btn).add(options.order); 1111 | } 1112 | } else { 1113 | classes(btn).add(options.order); 1114 | } 1115 | } 1116 | } 1117 | }; 1118 | var sort = function() { 1119 | list.trigger('sortStart'); 1120 | options = {}; 1121 | 1122 | var target = arguments[0].currentTarget || arguments[0].srcElement || undefined; 1123 | 1124 | if (target) { 1125 | options.valueName = getAttribute(target, 'data-sort'); 1126 | buttons.getInSensitive(target, options); 1127 | options.order = buttons.getOrder(target); 1128 | } else { 1129 | options = arguments[1] || options; 1130 | options.valueName = arguments[0]; 1131 | options.order = options.order || "asc"; 1132 | options.insensitive = (typeof options.insensitive == "undefined") ? true : options.insensitive; 1133 | } 1134 | buttons.clear(); 1135 | buttons.setOrder(options); 1136 | 1137 | options.sortFunction = options.sortFunction || list.sortFunction; 1138 | list.items.sort(function(a, b) { 1139 | return options.sortFunction(a, b, options); 1140 | }); 1141 | list.update(); 1142 | list.trigger('sortComplete'); 1143 | }; 1144 | 1145 | // Add handlers 1146 | list.handlers.sortStart = list.handlers.sortStart || []; 1147 | list.handlers.sortComplete = list.handlers.sortComplete || []; 1148 | 1149 | buttons.els = getByClass(list.listContainer, list.sortClass); 1150 | events.bind(buttons.els, 'click', sort); 1151 | list.on('searchStart', buttons.clear); 1152 | list.on('filterStart', buttons.clear); 1153 | 1154 | // Helpers 1155 | list.helpers.classes = classes; 1156 | list.helpers.naturalSort = naturalSort; 1157 | list.helpers.events = events; 1158 | list.helpers.getAttribute = getAttribute; 1159 | 1160 | return sort; 1161 | }; 1162 | 1163 | }); 1164 | require.register("list.js/src/item.js", function(exports, require, module){ 1165 | module.exports = function(list) { 1166 | return function(initValues, element, notCreate) { 1167 | var item = this; 1168 | 1169 | this._values = {}; 1170 | 1171 | this.found = false; // Show if list.searched == true and this.found == true 1172 | this.filtered = false;// Show if list.filtered == true and this.filtered == true 1173 | 1174 | var init = function(initValues, element, notCreate) { 1175 | if (element === undefined) { 1176 | if (notCreate) { 1177 | item.values(initValues, notCreate); 1178 | } else { 1179 | item.values(initValues); 1180 | } 1181 | } else { 1182 | item.elm = element; 1183 | var values = list.templater.get(item, initValues); 1184 | item.values(values); 1185 | } 1186 | }; 1187 | this.values = function(newValues, notCreate) { 1188 | if (newValues !== undefined) { 1189 | for(var name in newValues) { 1190 | item._values[name] = newValues[name]; 1191 | } 1192 | if (notCreate !== true) { 1193 | list.templater.set(item, item.values()); 1194 | } 1195 | } else { 1196 | return item._values; 1197 | } 1198 | }; 1199 | this.show = function() { 1200 | list.templater.show(item); 1201 | }; 1202 | this.hide = function() { 1203 | list.templater.hide(item); 1204 | }; 1205 | this.matching = function() { 1206 | return ( 1207 | (list.filtered && list.searched && item.found && item.filtered) || 1208 | (list.filtered && !list.searched && item.filtered) || 1209 | (!list.filtered && list.searched && item.found) || 1210 | (!list.filtered && !list.searched) 1211 | ); 1212 | }; 1213 | this.visible = function() { 1214 | return (item.elm.parentNode == list.list) ? true : false; 1215 | }; 1216 | init(initValues, element, notCreate); 1217 | }; 1218 | }; 1219 | 1220 | }); 1221 | require.register("list.js/src/templater.js", function(exports, require, module){ 1222 | var getByClass = require('get-by-class'); 1223 | 1224 | var Templater = function(list) { 1225 | var itemSource = getItemSource(list.item), 1226 | templater = this; 1227 | 1228 | function getItemSource(item) { 1229 | if (item === undefined) { 1230 | var nodes = list.list.childNodes, 1231 | items = []; 1232 | 1233 | for (var i = 0, il = nodes.length; i < il; i++) { 1234 | // Only textnodes have a data attribute 1235 | if (nodes[i].data === undefined) { 1236 | return nodes[i]; 1237 | } 1238 | } 1239 | return null; 1240 | } else if (item.indexOf("<") !== -1) { // Try create html element of list, do not work for tables!! 1241 | var div = document.createElement('div'); 1242 | div.innerHTML = item; 1243 | return div.firstChild; 1244 | } else { 1245 | return document.getElementById(list.item); 1246 | } 1247 | } 1248 | 1249 | /* Get values from element */ 1250 | this.get = function(item, valueNames) { 1251 | templater.create(item); 1252 | var values = {}; 1253 | for(var i = 0, il = valueNames.length; i < il; i++) { 1254 | var elm = getByClass(item.elm, valueNames[i], true); 1255 | values[valueNames[i]] = elm ? elm.innerHTML : ""; 1256 | } 1257 | return values; 1258 | }; 1259 | 1260 | /* Sets values at element */ 1261 | this.set = function(item, values) { 1262 | if (!templater.create(item)) { 1263 | for(var v in values) { 1264 | if (values.hasOwnProperty(v)) { 1265 | // TODO speed up if possible 1266 | var elm = getByClass(item.elm, v, true); 1267 | if (elm) { 1268 | /* src attribute for image tag & text for other tags */ 1269 | if (elm.tagName === "IMG" && values[v] !== "") { 1270 | elm.src = values[v]; 1271 | } else { 1272 | elm.innerHTML = values[v]; 1273 | } 1274 | } 1275 | } 1276 | } 1277 | } 1278 | }; 1279 | 1280 | this.create = function(item) { 1281 | if (item.elm !== undefined) { 1282 | return false; 1283 | } 1284 | /* If item source does not exists, use the first item in list as 1285 | source for new items */ 1286 | var newItem = itemSource.cloneNode(true); 1287 | newItem.removeAttribute('id'); 1288 | item.elm = newItem; 1289 | templater.set(item, item.values()); 1290 | return true; 1291 | }; 1292 | this.remove = function(item) { 1293 | list.list.removeChild(item.elm); 1294 | }; 1295 | this.show = function(item) { 1296 | templater.create(item); 1297 | list.list.appendChild(item.elm); 1298 | }; 1299 | this.hide = function(item) { 1300 | if (item.elm !== undefined && item.elm.parentNode === list.list) { 1301 | list.list.removeChild(item.elm); 1302 | } 1303 | }; 1304 | this.clear = function() { 1305 | /* .innerHTML = ''; fucks up IE */ 1306 | if (list.list.hasChildNodes()) { 1307 | while (list.list.childNodes.length >= 1) 1308 | { 1309 | list.list.removeChild(list.list.firstChild); 1310 | } 1311 | } 1312 | }; 1313 | }; 1314 | 1315 | module.exports = function(list) { 1316 | return new Templater(list); 1317 | }; 1318 | 1319 | }); 1320 | require.register("list.js/src/filter.js", function(exports, require, module){ 1321 | module.exports = function(list) { 1322 | 1323 | // Add handlers 1324 | list.handlers.filterStart = list.handlers.filterStart || []; 1325 | list.handlers.filterComplete = list.handlers.filterComplete || []; 1326 | 1327 | return function(filterFunction) { 1328 | list.trigger('filterStart'); 1329 | list.i = 1; // Reset paging 1330 | list.reset.filter(); 1331 | if (filterFunction === undefined) { 1332 | list.filtered = false; 1333 | } else { 1334 | list.filtered = true; 1335 | var is = list.items; 1336 | for (var i = 0, il = is.length; i < il; i++) { 1337 | var item = is[i]; 1338 | if (filterFunction(item)) { 1339 | item.filtered = true; 1340 | } else { 1341 | item.filtered = false; 1342 | } 1343 | } 1344 | } 1345 | list.update(); 1346 | list.trigger('filterComplete'); 1347 | return list.visibleItems; 1348 | }; 1349 | }; 1350 | 1351 | }); 1352 | require.register("list.js/src/add-async.js", function(exports, require, module){ 1353 | module.exports = function(list) { 1354 | return function(values, callback, items) { 1355 | var valuesToAdd = values.splice(0, 100); 1356 | items = items || []; 1357 | items = items.concat(list.add(valuesToAdd)); 1358 | if (values.length > 0) { 1359 | setTimeout(function() { 1360 | addAsync(values, callback, items); 1361 | }, 10); 1362 | } else { 1363 | list.update(); 1364 | callback(items); 1365 | } 1366 | }; 1367 | }; 1368 | }); 1369 | require.register("list.js/src/parse.js", function(exports, require, module){ 1370 | module.exports = function(list) { 1371 | 1372 | var Item = require('./item')(list); 1373 | 1374 | var getChildren = function(parent) { 1375 | var nodes = parent.childNodes, 1376 | items = []; 1377 | for (var i = 0, il = nodes.length; i < il; i++) { 1378 | // Only textnodes have a data attribute 1379 | if (nodes[i].data === undefined) { 1380 | items.push(nodes[i]); 1381 | } 1382 | } 1383 | return items; 1384 | }; 1385 | 1386 | var parse = function(itemElements, valueNames) { 1387 | for (var i = 0, il = itemElements.length; i < il; i++) { 1388 | list.items.push(new Item(valueNames, itemElements[i])); 1389 | } 1390 | }; 1391 | var parseAsync = function(itemElements, valueNames) { 1392 | var itemsToIndex = itemElements.splice(0, 100); // TODO: If < 100 items, what happens in IE etc? 1393 | parse(itemsToIndex, valueNames); 1394 | if (itemElements.length > 0) { 1395 | setTimeout(function() { 1396 | init.items.indexAsync(itemElements, valueNames); 1397 | }, 10); 1398 | } else { 1399 | list.update(); 1400 | // TODO: Add indexed callback 1401 | } 1402 | }; 1403 | 1404 | return function() { 1405 | var itemsToIndex = getChildren(list.list), 1406 | valueNames = list.valueNames; 1407 | 1408 | if (list.indexAsync) { 1409 | parseAsync(itemsToIndex, valueNames); 1410 | } else { 1411 | parse(itemsToIndex, valueNames); 1412 | } 1413 | }; 1414 | }; 1415 | 1416 | }); 1417 | 1418 | 1419 | 1420 | 1421 | 1422 | 1423 | 1424 | 1425 | 1426 | 1427 | 1428 | 1429 | 1430 | 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | require.alias("component-classes/index.js", "list.js/deps/classes/index.js"); 1438 | require.alias("component-classes/index.js", "classes/index.js"); 1439 | require.alias("component-indexof/index.js", "component-classes/deps/indexof/index.js"); 1440 | 1441 | require.alias("segmentio-extend/index.js", "list.js/deps/extend/index.js"); 1442 | require.alias("segmentio-extend/index.js", "extend/index.js"); 1443 | 1444 | require.alias("component-indexof/index.js", "list.js/deps/indexof/index.js"); 1445 | require.alias("component-indexof/index.js", "indexof/index.js"); 1446 | 1447 | require.alias("javve-events/index.js", "list.js/deps/events/index.js"); 1448 | require.alias("javve-events/index.js", "events/index.js"); 1449 | require.alias("component-event/index.js", "javve-events/deps/event/index.js"); 1450 | 1451 | require.alias("timoxley-to-array/index.js", "javve-events/deps/to-array/index.js"); 1452 | 1453 | require.alias("javve-get-by-class/index.js", "list.js/deps/get-by-class/index.js"); 1454 | require.alias("javve-get-by-class/index.js", "get-by-class/index.js"); 1455 | 1456 | require.alias("javve-get-attribute/index.js", "list.js/deps/get-attribute/index.js"); 1457 | require.alias("javve-get-attribute/index.js", "get-attribute/index.js"); 1458 | 1459 | require.alias("javve-natural-sort/index.js", "list.js/deps/natural-sort/index.js"); 1460 | require.alias("javve-natural-sort/index.js", "natural-sort/index.js"); 1461 | 1462 | require.alias("javve-to-string/index.js", "list.js/deps/to-string/index.js"); 1463 | require.alias("javve-to-string/index.js", "list.js/deps/to-string/index.js"); 1464 | require.alias("javve-to-string/index.js", "to-string/index.js"); 1465 | require.alias("javve-to-string/index.js", "javve-to-string/index.js"); 1466 | require.alias("component-type/index.js", "list.js/deps/type/index.js"); 1467 | require.alias("component-type/index.js", "type/index.js"); 1468 | if (typeof exports == "object") { 1469 | module.exports = require("list.js"); 1470 | } else if (typeof define == "function" && define.amd) { 1471 | define(function(){ return require("list.js"); }); 1472 | } else { 1473 | this["List"] = require("list.js"); 1474 | }})(); --------------------------------------------------------------------------------