mirror of
https://github.com/atlanticbiomedical/biomedjs.git
synced 2025-07-02 00:47:26 -04:00
Latest Code
This commit is contained in:
@ -4,12 +4,18 @@ var mongoose = require('mongoose'),
|
||||
|
||||
var md5 = require('MD5');
|
||||
var fs = require('fs');
|
||||
|
||||
var markdown = require('markdown').markdown;
|
||||
var log = require('log4node');
|
||||
|
||||
exports.index = function(req, res) {
|
||||
var criteria = {};
|
||||
var page = req.param('page');
|
||||
if (page) {
|
||||
criteria = { pages: page };
|
||||
}
|
||||
|
||||
log.info('posts.index');
|
||||
var query = Post.find()
|
||||
var query = Post.find(criteria)
|
||||
.populate('author', 'name')
|
||||
.sort('-createdOn')
|
||||
.exec(function(err, results) {
|
||||
@ -32,19 +38,64 @@ exports.get = function(req, res, next) {
|
||||
});
|
||||
};
|
||||
|
||||
function renderHtml(input) {
|
||||
if (input) {
|
||||
try {
|
||||
return markdown.toHTML(input);
|
||||
} catch (err) {
|
||||
console.log('Failed to render html', err);
|
||||
return input;
|
||||
}
|
||||
} else {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
function cleanTags(tags) {
|
||||
if (!tags) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!Array.isArray(tags)) {
|
||||
tags = [tags];
|
||||
}
|
||||
|
||||
var results = [];
|
||||
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
var tag = tags[i].toString()
|
||||
.replace(/^#/, '')
|
||||
.replace(/(\W|\d)/g, '$1 ')
|
||||
.replace(/\b\w+/g, function(txt) {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||
})
|
||||
.replace(/\s/g, '')
|
||||
|
||||
if (tag) {
|
||||
results.push(tag);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
exports.create = function(req, res, next) {
|
||||
log.info('posts.create %j', req.body);
|
||||
|
||||
var post = new Post({
|
||||
title: req.body.title,
|
||||
preview: req.body.preview,
|
||||
previewHtml: renderHtml(req.body.preview),
|
||||
details: req.body.details,
|
||||
detailsHtml: renderHtml(req.body.details),
|
||||
image: req.body.image,
|
||||
gallery: req.body.gallery,
|
||||
status: req.body.status,
|
||||
createdOn: req.body.createdOn,
|
||||
postedOn: req.body.postedOn,
|
||||
author: req.user
|
||||
author: req.user,
|
||||
pages: req.body.pages,
|
||||
tags: cleanTags(req.body.tags),
|
||||
});
|
||||
|
||||
return post.save(function(err) {
|
||||
@ -60,13 +111,17 @@ exports.update = function(req, res, next) {
|
||||
console.log('updating post');
|
||||
|
||||
return Post.findById(id, function(err, post) {
|
||||
post.title = req.body.title;
|
||||
post.preview = req.body.preview;
|
||||
post.details = req.body.details;
|
||||
post.image = req.body.image;
|
||||
post.gallery = req.body.gallery;
|
||||
post.status = req.body.status;
|
||||
post.postedOn = req.body.postedOn;
|
||||
post.title = req.body.title;
|
||||
post.preview = req.body.preview;
|
||||
post.previewHtml = renderHtml(req.body.preview);
|
||||
post.details = req.body.details;
|
||||
post.detailsHtml = renderHtml(req.body.details);
|
||||
post.image = req.body.image;
|
||||
post.gallery = req.body.gallery;
|
||||
post.status = req.body.status;
|
||||
post.postedOn = req.body.postedOn;
|
||||
post.pages = req.body.pages;
|
||||
post.tags = cleanTags(req.body.tags);
|
||||
|
||||
return post.save(function(err) {
|
||||
if (err)
|
||||
|
@ -130,18 +130,47 @@ module.exports = function(config, calendar) {
|
||||
if (!notify)
|
||||
return callback(null);
|
||||
|
||||
var to = generateToLine(techs).concat(req.body.emails);
|
||||
if (!to)
|
||||
return callback(null);
|
||||
var description = generateDescription(client, workorder, req.user, null, techs);
|
||||
var techDescription = appendNotes(description, client);
|
||||
|
||||
server.send({
|
||||
text: generateDescription(client, workorder, req.user, null, techs),
|
||||
from: config.email.user,
|
||||
to: to,
|
||||
subject: 'Workorder created: ' + workorder.biomedId
|
||||
}, function(err, message) {
|
||||
callback(err);
|
||||
});
|
||||
var to = req.body.emails;
|
||||
var techTo = generateToLine(techs);
|
||||
|
||||
var subject = 'Workorder created: ' + workorder.biomedId;
|
||||
|
||||
console.log('-------------------------');
|
||||
console.log(to);
|
||||
|
||||
async.waterfall([
|
||||
function(cb) {
|
||||
if (to && to.length > 0) {
|
||||
var msg = {
|
||||
text: description,
|
||||
from: config.email.user,
|
||||
to: to,
|
||||
subject: subject
|
||||
};
|
||||
console.log(msg);
|
||||
server.send(msg, function(err, message) { cb(err); });
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
},
|
||||
function(cb) {
|
||||
if (techTo) {
|
||||
var msg = {
|
||||
text: techDescription,
|
||||
from: config.email.user,
|
||||
to: techTo,
|
||||
subject: subject
|
||||
};
|
||||
console.log(msg);
|
||||
server.send(msg, function(err, message) { cb(err); });
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
], callback);
|
||||
},
|
||||
function(callback) {
|
||||
workorder.save(function(err, result) { callback(err, result); });
|
||||
@ -265,18 +294,45 @@ module.exports = function(config, calendar) {
|
||||
if (!notify)
|
||||
return callback(null);
|
||||
|
||||
var to = generateToLine(techs);
|
||||
if (!to)
|
||||
return callback(null);
|
||||
|
||||
server.send({
|
||||
text: generateDescription(client, workorder, createdBy, modifiedBy, techs),
|
||||
from: config.email.user,
|
||||
to: to,
|
||||
subject: 'Workorder updated: ' + workorder.biomedId
|
||||
}, function(err, message) {
|
||||
callback(err);
|
||||
});
|
||||
|
||||
var description = generateDescription(client, workorder, createdBy, modifiedBy, techs);
|
||||
var techDescription = appendNotes(description, client);
|
||||
|
||||
var to = req.body.emails;
|
||||
var techTo = generateToLine(techs);
|
||||
|
||||
var subject = 'Workorder updated: ' + workorder.biomedId;
|
||||
|
||||
async.waterfall([
|
||||
function(cb) {
|
||||
if (to && to.length > 0) {
|
||||
var msg = {
|
||||
text: description,
|
||||
from: config.email.user,
|
||||
to: to,
|
||||
subject: subject
|
||||
};
|
||||
console.log(msg);
|
||||
server.send(msg, function(err, message) { cb(err); });
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
},
|
||||
function(cb) {
|
||||
if (techTo) {
|
||||
var msg = {
|
||||
text: techDescription,
|
||||
from: config.email.user,
|
||||
to: techTo,
|
||||
subject: subject
|
||||
};
|
||||
console.log(msg);
|
||||
server.send(msg, function(err, message) { cb(err); });
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
], callback);
|
||||
},
|
||||
function(callback) {
|
||||
workorder.save(function(err) {
|
||||
@ -332,6 +388,26 @@ function generateLocation(client) {
|
||||
return sprintf("%(street1)s %(street2)s %(city)s, %(state)s. %(zip)s", data);
|
||||
}
|
||||
|
||||
function appendNotes(message, client) {
|
||||
var template =
|
||||
"%(message)s\n" +
|
||||
"Tech Notes:\n" +
|
||||
" %(notes)s\n" +
|
||||
"\n";
|
||||
|
||||
if (client.notes && client.notes['tech']) {
|
||||
var resources = {
|
||||
message: message || '',
|
||||
notes: client.notes['tech'] || ''
|
||||
};
|
||||
|
||||
return sprintf(template, resources);
|
||||
} else {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function generateDescription(client, workorder, createdBy, modifiedBy) {
|
||||
var template =
|
||||
"Workorder ID:\n" +
|
||||
|
@ -5,13 +5,17 @@ var mongoose = require('mongoose'),
|
||||
var postSchema = new Schema({
|
||||
title: { type: String },
|
||||
preview: { type: String },
|
||||
previewHtml: { type: String },
|
||||
details: { type: String },
|
||||
detailsHtml: { type: String },
|
||||
image: { type: String },
|
||||
gallery: [{ type: String }],
|
||||
status: { type: String },
|
||||
createdOn: { type: Date },
|
||||
postedOn: { type: Date },
|
||||
author: { type: ObjectId, ref: 'User' }
|
||||
author: { type: ObjectId, ref: 'User' },
|
||||
tags: [{ type: String }],
|
||||
pages: [{ type: String }]
|
||||
});
|
||||
|
||||
var Post = module.exports = mongoose.model('Post', postSchema);
|
||||
|
@ -63,6 +63,8 @@ html(lang="en", ng-app="biomed", ng-controller="biomed.PageCtrl")
|
||||
a(href='/admin')
|
||||
i.icon-wrench
|
||||
| Admin
|
||||
li.day-of-year
|
||||
{{dayOfYear}}
|
||||
.container-fluid
|
||||
ng-view
|
||||
!{js}
|
||||
|
@ -38,7 +38,7 @@ html(lang="en", ng-app="site", ng-controller="site.PageCtrl")
|
||||
.controls
|
||||
.dropzone(dropzone='titleImageOptions')
|
||||
|
||||
.control-group
|
||||
.control-group(ng-show='model.image')
|
||||
label.control-label Gallery
|
||||
.controls
|
||||
.dropzone(dropzone='galleryImageOptions')
|
||||
|
@ -1,4 +1,5 @@
|
||||
var express = require('express');
|
||||
var ClusterStore = require('strong-cluster-connect-store')(express.session);
|
||||
|
||||
module.exports = function(app, config, passport, piler) {
|
||||
app.set('showStackError', true);
|
||||
@ -16,9 +17,7 @@ module.exports = function(app, config, passport, piler) {
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.methodOverride());
|
||||
|
||||
app.use(express.session({
|
||||
secret: 'atlantic_biomed_server_secret'
|
||||
}));
|
||||
app.use(express.session({ store: new ClusterStore(), secret: 'atlantic_biomed_server_secret' }));
|
||||
|
||||
// use passport session
|
||||
app.use(passport.initialize());
|
||||
|
22
launcher.js
Normal file
22
launcher.js
Normal file
@ -0,0 +1,22 @@
|
||||
var cluster = require('cluster');
|
||||
|
||||
require('strong-cluster-connect-store').setup();
|
||||
|
||||
cluster.setupMaster({
|
||||
exec: 'server.js'
|
||||
});
|
||||
|
||||
var cpus = 1;
|
||||
for (var i = 0; i < cpus; i++) {
|
||||
cluster.fork();
|
||||
}
|
||||
|
||||
cluster.on('online', function(worker) {
|
||||
console.log('worker ' + worker.process.pid + ' started.');
|
||||
});
|
||||
|
||||
cluster.on('exit', function(worker, code, signal) {
|
||||
console.log('worker ' + worker.process.pid + ' died');
|
||||
cluster.fork();
|
||||
});
|
||||
|
1
node_modules/.bin/md2html
generated
vendored
Symbolic link
1
node_modules/.bin/md2html
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../markdown/bin/md2html.js
|
2
node_modules/markdown/.npmignore
generated
vendored
Normal file
2
node_modules/markdown/.npmignore
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.seed.yml
|
||||
test
|
7
node_modules/markdown/.travis.yml
generated
vendored
Normal file
7
node_modules/markdown/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.6"
|
||||
- "0.8"
|
||||
- "0.9"
|
||||
- "0.10"
|
||||
- "0.11"
|
35
node_modules/markdown/Changes.markdown
generated
vendored
Normal file
35
node_modules/markdown/Changes.markdown
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
# Changelog for markdown
|
||||
|
||||
## v0.5.0 - 2013-07-26
|
||||
|
||||
There might be other bug fixes then the ones listed - I've been a bit lax at
|
||||
updating the changes file, sorry :(
|
||||
|
||||
- Fix 'undefined' appearing in output for some cases with blockquotes
|
||||
- Fix (multiple) global variable leaks. Ooops
|
||||
- Fix IE8 issues (#68, #74, #97)
|
||||
- Fix IE8 issue (#86)
|
||||
- Handle windows line endings (#58)
|
||||
- Allow spaces in img/link paths (#48)
|
||||
- Add explicit text of the license to the readme (#74)
|
||||
- Style tweaks by Xhmikosr (#83, #81, #82)
|
||||
- Build now tested by TravisCI thanks to sebs (#85)
|
||||
- Fix 'cuddled' header parsing (#94)
|
||||
- Fix images inside links mistakenly requiring a title attribute to parse
|
||||
correctly (#71)
|
||||
|
||||
|
||||
## v0.4.0 - 2012-06-09
|
||||
|
||||
- Fix for anchors enclosed by parenthesis (issue #46)
|
||||
- `npm test` will now run the entire test suite cleanly. (switch tests over to
|
||||
node-tap). (#21)
|
||||
- Allow inline elements to appear inside link text (#27)
|
||||
- Improve link parsing when link is inside parenthesis (#38)
|
||||
- Actually render image references (#36)
|
||||
- Improve link parsing when multiple on a line (#5)
|
||||
- Make it work in IE7/8 (#37)
|
||||
- Fix blockquote merging/implicit conversion between string/String (#44, #24)
|
||||
- md2html can now process stdin (#43)
|
||||
- Fix jslint warnings (#42)
|
||||
- Fix to correctly render self-closing tags (#40, #35, #28)
|
185
node_modules/markdown/README.markdown
generated
vendored
Normal file
185
node_modules/markdown/README.markdown
generated
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
# markdown-js
|
||||
|
||||
Yet another markdown parser, this time for JavaScript. There's a few
|
||||
options that precede this project but they all treat markdown to HTML
|
||||
conversion as a single step process. You pass markdown in and get HTML
|
||||
out, end of story. We had some pretty particular views on how the
|
||||
process should actually look, which include:
|
||||
|
||||
* producing well-formed HTML. This means that `em` and `strong` nesting
|
||||
is important, as is the ability to output as both HTML and XHTML
|
||||
|
||||
* having an intermediate representation to allow processing of parsed
|
||||
data (we in fact have two, both [JsonML]: a markdown tree and an HTML tree)
|
||||
|
||||
* being easily extensible to add new dialects without having to
|
||||
rewrite the entire parsing mechanics
|
||||
|
||||
* having a good test suite. The only test suites we could find tested
|
||||
massive blocks of input, and passing depended on outputting the HTML
|
||||
with exactly the same whitespace as the original implementation
|
||||
|
||||
[JsonML]: http://jsonml.org/ "JSON Markup Language"
|
||||
|
||||
## Installation
|
||||
|
||||
Just the `markdown` library:
|
||||
|
||||
npm install markdown
|
||||
|
||||
Optionally, install `md2html` into your path
|
||||
|
||||
npm install -g markdown
|
||||
|
||||
## Usage
|
||||
|
||||
### Node
|
||||
|
||||
The simple way to use it with node is:
|
||||
|
||||
```js
|
||||
var markdown = require( "markdown" ).markdown;
|
||||
console.log( markdown.toHTML( "Hello *World*!" ) );
|
||||
```
|
||||
|
||||
### Browser
|
||||
|
||||
It also works in a browser; here is a complete example:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<textarea id="text-input" oninput="this.editor.update()"
|
||||
rows="6" cols="60">Type **Markdown** here.</textarea>
|
||||
<div id="preview"> </div>
|
||||
<script src="lib/markdown.js"></script>
|
||||
<script>
|
||||
function Editor(input, preview) {
|
||||
this.update = function () {
|
||||
preview.innerHTML = markdown.toHTML(input.value);
|
||||
};
|
||||
input.editor = this;
|
||||
this.update();
|
||||
}
|
||||
var $ = function (id) { return document.getElementById(id); };
|
||||
new Editor($("text-input"), $("preview"));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### Command line
|
||||
|
||||
Assuming you've installed the `md2html` script (see Installation,
|
||||
above), you can convert markdown to html:
|
||||
|
||||
```bash
|
||||
# read from a file
|
||||
md2html /path/to/doc.md > /path/to/doc.html
|
||||
|
||||
# or from stdin
|
||||
echo 'Hello *World*!' | md2html
|
||||
```
|
||||
|
||||
### More options
|
||||
|
||||
If you want more control check out the documentation in
|
||||
[lib/markdown.js] which details all the methods and parameters
|
||||
available (including examples!). One day we'll get the docs generated
|
||||
and hosted somewhere for nicer browsing.
|
||||
|
||||
[lib/markdown.js]: http://github.com/evilstreak/markdown-js/blob/master/lib/markdown.js
|
||||
|
||||
Meanwhile, here's an example of using the multi-step processing to
|
||||
make wiki-style linking work by filling in missing link references:
|
||||
|
||||
```js
|
||||
var md = require( "markdown" ).markdown,
|
||||
text = "[Markdown] is a simple text-based [markup language]\n" +
|
||||
"created by [John Gruber]\n\n" +
|
||||
"[John Gruber]: http://daringfireball.net";
|
||||
|
||||
// parse the markdown into a tree and grab the link references
|
||||
var tree = md.parse( text ),
|
||||
refs = tree[ 1 ].references;
|
||||
|
||||
// iterate through the tree finding link references
|
||||
( function find_link_refs( jsonml ) {
|
||||
if ( jsonml[ 0 ] === "link_ref" ) {
|
||||
var ref = jsonml[ 1 ].ref;
|
||||
|
||||
// if there's no reference, define a wiki link
|
||||
if ( !refs[ ref ] ) {
|
||||
refs[ ref ] = {
|
||||
href: "http://en.wikipedia.org/wiki/" + ref.replace(/\s+/, "_" )
|
||||
};
|
||||
}
|
||||
}
|
||||
else if ( Array.isArray( jsonml[ 1 ] ) ) {
|
||||
jsonml[ 1 ].forEach( find_link_refs );
|
||||
}
|
||||
else if ( Array.isArray( jsonml[ 2 ] ) ) {
|
||||
jsonml[ 2 ].forEach( find_link_refs );
|
||||
}
|
||||
} )( tree );
|
||||
|
||||
// convert the tree into html
|
||||
var html = md.renderJsonML( md.toHTMLTree( tree ) );
|
||||
console.log( html );
|
||||
```
|
||||
|
||||
## Intermediate Representation
|
||||
|
||||
Internally the process to convert a chunk of markdown into a chunk of
|
||||
HTML has three steps:
|
||||
|
||||
1. Parse the markdown into a JsonML tree. Any references found in the
|
||||
parsing are stored in the attribute hash of the root node under the
|
||||
key `references`.
|
||||
|
||||
2. Convert the markdown tree into an HTML tree. Rename any nodes that
|
||||
need it (`bulletlist` to `ul` for example) and lookup any references
|
||||
used by links or images. Remove the references attribute once done.
|
||||
|
||||
3. Stringify the HTML tree being careful not to wreck whitespace where
|
||||
whitespace is important (surrounding inline elements for example).
|
||||
|
||||
Each step of this process can be called individually if you need to do
|
||||
some processing or modification of the data at an intermediate stage.
|
||||
For example, you may want to grab a list of all URLs linked to in the
|
||||
document before rendering it to HTML which you could do by recursing
|
||||
through the HTML tree looking for `a` nodes.
|
||||
|
||||
## Running tests
|
||||
|
||||
To run the tests under node you will need tap installed (it's listed as a
|
||||
`devDependencies` so `npm install` from the checkout should be enough), then do
|
||||
|
||||
$ npm test
|
||||
|
||||
## Contributing
|
||||
|
||||
Do the usual github fork and pull request dance. Add yourself to the
|
||||
contributors section of [package.json](/package.json) too if you want to.
|
||||
|
||||
## License
|
||||
|
||||
Released under the MIT license.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
52
node_modules/markdown/bin/md2html.js
generated
vendored
Executable file
52
node_modules/markdown/bin/md2html.js
generated
vendored
Executable file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env node
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var fs = require("fs")
|
||||
, markdown = require("markdown").markdown
|
||||
, nopt = require("nopt")
|
||||
, stream
|
||||
, opts
|
||||
, buffer = ""
|
||||
;
|
||||
|
||||
opts = nopt(
|
||||
{ "dialect": [ "Gruber", "Maruku"]
|
||||
, "help": Boolean
|
||||
}
|
||||
);
|
||||
|
||||
if (opts.help) {
|
||||
var name = process.argv[1].split("/").pop()
|
||||
console.warn( require("util").format(
|
||||
"usage: %s [--dialect=DIALECT] FILE\n\nValid dialects are Gruber (the default) or Maruku",
|
||||
name
|
||||
) );
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
var fullpath = opts.argv.remain[0];
|
||||
|
||||
if (fullpath && fullpath !== "-") {
|
||||
stream = fs.createReadStream(fullpath);
|
||||
} else {
|
||||
stream = process.stdin;
|
||||
}
|
||||
stream.resume();
|
||||
stream.setEncoding("utf8");
|
||||
|
||||
stream.on("error", function(error) {
|
||||
console.error(error.toString());
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
stream.on("data", function(data) {
|
||||
buffer += data;
|
||||
});
|
||||
|
||||
stream.on("end", function() {
|
||||
var html = markdown.toHTML(buffer, opts.dialect);
|
||||
console.log(html);
|
||||
});
|
||||
|
||||
}())
|
3
node_modules/markdown/lib/index.js
generated
vendored
Normal file
3
node_modules/markdown/lib/index.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
// super simple module for the most common nodejs use case.
|
||||
exports.markdown = require("./markdown");
|
||||
exports.parse = exports.markdown.toHTML;
|
1725
node_modules/markdown/lib/markdown.js
generated
vendored
Normal file
1725
node_modules/markdown/lib/markdown.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10
node_modules/markdown/markdown-js.sublime-project
generated
vendored
Normal file
10
node_modules/markdown/markdown-js.sublime-project
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"folders":
|
||||
[
|
||||
{
|
||||
"path": "/Users/ash/code/js/markdown-js",
|
||||
"folder_exclude_patterns": ["node_modules"],
|
||||
"file_exclude_patterns": ["*.sublime-*"]
|
||||
}
|
||||
]
|
||||
}
|
1993
node_modules/markdown/markdown-js.sublime-workspace
generated
vendored
Normal file
1993
node_modules/markdown/markdown-js.sublime-workspace
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/markdown/node_modules/.bin/nopt
generated
vendored
Symbolic link
1
node_modules/markdown/node_modules/.bin/nopt
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../nopt/bin/nopt.js
|
1
node_modules/markdown/node_modules/nopt/.npmignore
generated
vendored
Normal file
1
node_modules/markdown/node_modules/nopt/.npmignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules
|
23
node_modules/markdown/node_modules/nopt/LICENSE
generated
vendored
Normal file
23
node_modules/markdown/node_modules/nopt/LICENSE
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
210
node_modules/markdown/node_modules/nopt/README.md
generated
vendored
Normal file
210
node_modules/markdown/node_modules/nopt/README.md
generated
vendored
Normal file
@ -0,0 +1,210 @@
|
||||
If you want to write an option parser, and have it be good, there are
|
||||
two ways to do it. The Right Way, and the Wrong Way.
|
||||
|
||||
The Wrong Way is to sit down and write an option parser. We've all done
|
||||
that.
|
||||
|
||||
The Right Way is to write some complex configurable program with so many
|
||||
options that you go half-insane just trying to manage them all, and put
|
||||
it off with duct-tape solutions until you see exactly to the core of the
|
||||
problem, and finally snap and write an awesome option parser.
|
||||
|
||||
If you want to write an option parser, don't write an option parser.
|
||||
Write a package manager, or a source control system, or a service
|
||||
restarter, or an operating system. You probably won't end up with a
|
||||
good one of those, but if you don't give up, and you are relentless and
|
||||
diligent enough in your procrastination, you may just end up with a very
|
||||
nice option parser.
|
||||
|
||||
## USAGE
|
||||
|
||||
// my-program.js
|
||||
var nopt = require("nopt")
|
||||
, Stream = require("stream").Stream
|
||||
, path = require("path")
|
||||
, knownOpts = { "foo" : [String, null]
|
||||
, "bar" : [Stream, Number]
|
||||
, "baz" : path
|
||||
, "bloo" : [ "big", "medium", "small" ]
|
||||
, "flag" : Boolean
|
||||
, "pick" : Boolean
|
||||
, "many" : [String, Array]
|
||||
}
|
||||
, shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
|
||||
, "b7" : ["--bar", "7"]
|
||||
, "m" : ["--bloo", "medium"]
|
||||
, "p" : ["--pick"]
|
||||
, "f" : ["--flag"]
|
||||
}
|
||||
// everything is optional.
|
||||
// knownOpts and shorthands default to {}
|
||||
// arg list defaults to process.argv
|
||||
// slice defaults to 2
|
||||
, parsed = nopt(knownOpts, shortHands, process.argv, 2)
|
||||
console.log(parsed)
|
||||
|
||||
This would give you support for any of the following:
|
||||
|
||||
```bash
|
||||
$ node my-program.js --foo "blerp" --no-flag
|
||||
{ "foo" : "blerp", "flag" : false }
|
||||
|
||||
$ node my-program.js ---bar 7 --foo "Mr. Hand" --flag
|
||||
{ bar: 7, foo: "Mr. Hand", flag: true }
|
||||
|
||||
$ node my-program.js --foo "blerp" -f -----p
|
||||
{ foo: "blerp", flag: true, pick: true }
|
||||
|
||||
$ node my-program.js -fp --foofoo
|
||||
{ foo: "Mr. Foo", flag: true, pick: true }
|
||||
|
||||
$ node my-program.js --foofoo -- -fp # -- stops the flag parsing.
|
||||
{ foo: "Mr. Foo", argv: { remain: ["-fp"] } }
|
||||
|
||||
$ node my-program.js --blatzk 1000 -fp # unknown opts are ok.
|
||||
{ blatzk: 1000, flag: true, pick: true }
|
||||
|
||||
$ node my-program.js --blatzk true -fp # but they need a value
|
||||
{ blatzk: true, flag: true, pick: true }
|
||||
|
||||
$ node my-program.js --no-blatzk -fp # unless they start with "no-"
|
||||
{ blatzk: false, flag: true, pick: true }
|
||||
|
||||
$ node my-program.js --baz b/a/z # known paths are resolved.
|
||||
{ baz: "/Users/isaacs/b/a/z" }
|
||||
|
||||
# if Array is one of the types, then it can take many
|
||||
# values, and will always be an array. The other types provided
|
||||
# specify what types are allowed in the list.
|
||||
|
||||
$ node my-program.js --many 1 --many null --many foo
|
||||
{ many: ["1", "null", "foo"] }
|
||||
|
||||
$ node my-program.js --many foo
|
||||
{ many: ["foo"] }
|
||||
```
|
||||
|
||||
Read the tests at the bottom of `lib/nopt.js` for more examples of
|
||||
what this puppy can do.
|
||||
|
||||
## Types
|
||||
|
||||
The following types are supported, and defined on `nopt.typeDefs`
|
||||
|
||||
* String: A normal string. No parsing is done.
|
||||
* path: A file system path. Gets resolved against cwd if not absolute.
|
||||
* url: A url. If it doesn't parse, it isn't accepted.
|
||||
* Number: Must be numeric.
|
||||
* Date: Must parse as a date. If it does, and `Date` is one of the options,
|
||||
then it will return a Date object, not a string.
|
||||
* Boolean: Must be either `true` or `false`. If an option is a boolean,
|
||||
then it does not need a value, and its presence will imply `true` as
|
||||
the value. To negate boolean flags, do `--no-whatever` or `--whatever
|
||||
false`
|
||||
* NaN: Means that the option is strictly not allowed. Any value will
|
||||
fail.
|
||||
* Stream: An object matching the "Stream" class in node. Valuable
|
||||
for use when validating programmatically. (npm uses this to let you
|
||||
supply any WriteStream on the `outfd` and `logfd` config options.)
|
||||
* Array: If `Array` is specified as one of the types, then the value
|
||||
will be parsed as a list of options. This means that multiple values
|
||||
can be specified, and that the value will always be an array.
|
||||
|
||||
If a type is an array of values not on this list, then those are
|
||||
considered valid values. For instance, in the example above, the
|
||||
`--bloo` option can only be one of `"big"`, `"medium"`, or `"small"`,
|
||||
and any other value will be rejected.
|
||||
|
||||
When parsing unknown fields, `"true"`, `"false"`, and `"null"` will be
|
||||
interpreted as their JavaScript equivalents, and numeric values will be
|
||||
interpreted as a number.
|
||||
|
||||
You can also mix types and values, or multiple types, in a list. For
|
||||
instance `{ blah: [Number, null] }` would allow a value to be set to
|
||||
either a Number or null. When types are ordered, this implies a
|
||||
preference, and the first type that can be used to properly interpret
|
||||
the value will be used.
|
||||
|
||||
To define a new type, add it to `nopt.typeDefs`. Each item in that
|
||||
hash is an object with a `type` member and a `validate` method. The
|
||||
`type` member is an object that matches what goes in the type list. The
|
||||
`validate` method is a function that gets called with `validate(data,
|
||||
key, val)`. Validate methods should assign `data[key]` to the valid
|
||||
value of `val` if it can be handled properly, or return boolean
|
||||
`false` if it cannot.
|
||||
|
||||
You can also call `nopt.clean(data, types, typeDefs)` to clean up a
|
||||
config object and remove its invalid properties.
|
||||
|
||||
## Error Handling
|
||||
|
||||
By default, nopt outputs a warning to standard error when invalid
|
||||
options are found. You can change this behavior by assigning a method
|
||||
to `nopt.invalidHandler`. This method will be called with
|
||||
the offending `nopt.invalidHandler(key, val, types)`.
|
||||
|
||||
If no `nopt.invalidHandler` is assigned, then it will console.error
|
||||
its whining. If it is assigned to boolean `false` then the warning is
|
||||
suppressed.
|
||||
|
||||
## Abbreviations
|
||||
|
||||
Yes, they are supported. If you define options like this:
|
||||
|
||||
```javascript
|
||||
{ "foolhardyelephants" : Boolean
|
||||
, "pileofmonkeys" : Boolean }
|
||||
```
|
||||
|
||||
Then this will work:
|
||||
|
||||
```bash
|
||||
node program.js --foolhar --pil
|
||||
node program.js --no-f --pileofmon
|
||||
# etc.
|
||||
```
|
||||
|
||||
## Shorthands
|
||||
|
||||
Shorthands are a hash of shorter option names to a snippet of args that
|
||||
they expand to.
|
||||
|
||||
If multiple one-character shorthands are all combined, and the
|
||||
combination does not unambiguously match any other option or shorthand,
|
||||
then they will be broken up into their constituent parts. For example:
|
||||
|
||||
```json
|
||||
{ "s" : ["--loglevel", "silent"]
|
||||
, "g" : "--global"
|
||||
, "f" : "--force"
|
||||
, "p" : "--parseable"
|
||||
, "l" : "--long"
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
npm ls -sgflp
|
||||
# just like doing this:
|
||||
npm ls --loglevel silent --global --force --long --parseable
|
||||
```
|
||||
|
||||
## The Rest of the args
|
||||
|
||||
The config object returned by nopt is given a special member called
|
||||
`argv`, which is an object with the following fields:
|
||||
|
||||
* `remain`: The remaining args after all the parsing has occurred.
|
||||
* `original`: The args as they originally appeared.
|
||||
* `cooked`: The args after flags and shorthands are expanded.
|
||||
|
||||
## Slicing
|
||||
|
||||
Node programs are called with more or less the exact argv as it appears
|
||||
in C land, after the v8 and node-specific options have been plucked off.
|
||||
As such, `argv[0]` is always `node` and `argv[1]` is always the
|
||||
JavaScript program being run.
|
||||
|
||||
That's usually not very useful to you. So they're sliced off by
|
||||
default. If you want them, then you can pass in `0` as the last
|
||||
argument, or any other number that you'd like to slice off the start of
|
||||
the list.
|
51
node_modules/markdown/node_modules/nopt/bin/nopt.js
generated
vendored
Executable file
51
node_modules/markdown/node_modules/nopt/bin/nopt.js
generated
vendored
Executable file
@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env node
|
||||
var nopt = require("../lib/nopt")
|
||||
, types = { num: Number
|
||||
, bool: Boolean
|
||||
, help: Boolean
|
||||
, list: Array
|
||||
, "num-list": [Number, Array]
|
||||
, "str-list": [String, Array]
|
||||
, "bool-list": [Boolean, Array]
|
||||
, str: String
|
||||
, clear: Boolean
|
||||
, config: Boolean
|
||||
, length: Number
|
||||
}
|
||||
, shorthands = { s: [ "--str", "astring" ]
|
||||
, b: [ "--bool" ]
|
||||
, nb: [ "--no-bool" ]
|
||||
, tft: [ "--bool-list", "--no-bool-list", "--bool-list", "true" ]
|
||||
, "?": ["--help"]
|
||||
, h: ["--help"]
|
||||
, H: ["--help"]
|
||||
, n: [ "--num", "125" ]
|
||||
, c: ["--config"]
|
||||
, l: ["--length"]
|
||||
}
|
||||
, parsed = nopt( types
|
||||
, shorthands
|
||||
, process.argv
|
||||
, 2 )
|
||||
|
||||
console.log("parsed", parsed)
|
||||
|
||||
if (parsed.help) {
|
||||
console.log("")
|
||||
console.log("nopt cli tester")
|
||||
console.log("")
|
||||
console.log("types")
|
||||
console.log(Object.keys(types).map(function M (t) {
|
||||
var type = types[t]
|
||||
if (Array.isArray(type)) {
|
||||
return [t, type.map(function (type) { return type.name })]
|
||||
}
|
||||
return [t, type && type.name]
|
||||
}).reduce(function (s, i) {
|
||||
s[i[0]] = i[1]
|
||||
return s
|
||||
}, {}))
|
||||
console.log("")
|
||||
console.log("shorthands")
|
||||
console.log(shorthands)
|
||||
}
|
30
node_modules/markdown/node_modules/nopt/examples/my-program.js
generated
vendored
Executable file
30
node_modules/markdown/node_modules/nopt/examples/my-program.js
generated
vendored
Executable file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
//process.env.DEBUG_NOPT = 1
|
||||
|
||||
// my-program.js
|
||||
var nopt = require("../lib/nopt")
|
||||
, Stream = require("stream").Stream
|
||||
, path = require("path")
|
||||
, knownOpts = { "foo" : [String, null]
|
||||
, "bar" : [Stream, Number]
|
||||
, "baz" : path
|
||||
, "bloo" : [ "big", "medium", "small" ]
|
||||
, "flag" : Boolean
|
||||
, "pick" : Boolean
|
||||
}
|
||||
, shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
|
||||
, "b7" : ["--bar", "7"]
|
||||
, "m" : ["--bloo", "medium"]
|
||||
, "p" : ["--pick"]
|
||||
, "f" : ["--flag", "true"]
|
||||
, "g" : ["--flag"]
|
||||
, "s" : "--flag"
|
||||
}
|
||||
// everything is optional.
|
||||
// knownOpts and shorthands default to {}
|
||||
// arg list defaults to process.argv
|
||||
// slice defaults to 2
|
||||
, parsed = nopt(knownOpts, shortHands, process.argv, 2)
|
||||
|
||||
console.log("parsed =\n"+ require("util").inspect(parsed))
|
612
node_modules/markdown/node_modules/nopt/lib/nopt.js
generated
vendored
Normal file
612
node_modules/markdown/node_modules/nopt/lib/nopt.js
generated
vendored
Normal file
@ -0,0 +1,612 @@
|
||||
// info about each config option.
|
||||
|
||||
var debug = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG
|
||||
? function () { console.error.apply(console, arguments) }
|
||||
: function () {}
|
||||
|
||||
var url = require("url")
|
||||
, path = require("path")
|
||||
, Stream = require("stream").Stream
|
||||
, abbrev = require("abbrev")
|
||||
|
||||
module.exports = exports = nopt
|
||||
exports.clean = clean
|
||||
|
||||
exports.typeDefs =
|
||||
{ String : { type: String, validate: validateString }
|
||||
, Boolean : { type: Boolean, validate: validateBoolean }
|
||||
, url : { type: url, validate: validateUrl }
|
||||
, Number : { type: Number, validate: validateNumber }
|
||||
, path : { type: path, validate: validatePath }
|
||||
, Stream : { type: Stream, validate: validateStream }
|
||||
, Date : { type: Date, validate: validateDate }
|
||||
}
|
||||
|
||||
function nopt (types, shorthands, args, slice) {
|
||||
args = args || process.argv
|
||||
types = types || {}
|
||||
shorthands = shorthands || {}
|
||||
if (typeof slice !== "number") slice = 2
|
||||
|
||||
debug(types, shorthands, args, slice)
|
||||
|
||||
args = args.slice(slice)
|
||||
var data = {}
|
||||
, key
|
||||
, remain = []
|
||||
, cooked = args
|
||||
, original = args.slice(0)
|
||||
|
||||
parse(args, data, remain, types, shorthands)
|
||||
// now data is full
|
||||
clean(data, types, exports.typeDefs)
|
||||
data.argv = {remain:remain,cooked:cooked,original:original}
|
||||
Object.defineProperty(data.argv, 'toString', { value: function () {
|
||||
return this.original.map(JSON.stringify).join(" ")
|
||||
}, enumerable: false })
|
||||
return data
|
||||
}
|
||||
|
||||
function clean (data, types, typeDefs) {
|
||||
typeDefs = typeDefs || exports.typeDefs
|
||||
var remove = {}
|
||||
, typeDefault = [false, true, null, String, Number, Array]
|
||||
|
||||
Object.keys(data).forEach(function (k) {
|
||||
if (k === "argv") return
|
||||
var val = data[k]
|
||||
, isArray = Array.isArray(val)
|
||||
, type = types[k]
|
||||
if (!isArray) val = [val]
|
||||
if (!type) type = typeDefault
|
||||
if (type === Array) type = typeDefault.concat(Array)
|
||||
if (!Array.isArray(type)) type = [type]
|
||||
|
||||
debug("val=%j", val)
|
||||
debug("types=", type)
|
||||
val = val.map(function (val) {
|
||||
// if it's an unknown value, then parse false/true/null/numbers/dates
|
||||
if (typeof val === "string") {
|
||||
debug("string %j", val)
|
||||
val = val.trim()
|
||||
if ((val === "null" && ~type.indexOf(null))
|
||||
|| (val === "true" &&
|
||||
(~type.indexOf(true) || ~type.indexOf(Boolean)))
|
||||
|| (val === "false" &&
|
||||
(~type.indexOf(false) || ~type.indexOf(Boolean)))) {
|
||||
val = JSON.parse(val)
|
||||
debug("jsonable %j", val)
|
||||
} else if (~type.indexOf(Number) && !isNaN(val)) {
|
||||
debug("convert to number", val)
|
||||
val = +val
|
||||
} else if (~type.indexOf(Date) && !isNaN(Date.parse(val))) {
|
||||
debug("convert to date", val)
|
||||
val = new Date(val)
|
||||
}
|
||||
}
|
||||
|
||||
if (!types.hasOwnProperty(k)) {
|
||||
return val
|
||||
}
|
||||
|
||||
// allow `--no-blah` to set 'blah' to null if null is allowed
|
||||
if (val === false && ~type.indexOf(null) &&
|
||||
!(~type.indexOf(false) || ~type.indexOf(Boolean))) {
|
||||
val = null
|
||||
}
|
||||
|
||||
var d = {}
|
||||
d[k] = val
|
||||
debug("prevalidated val", d, val, types[k])
|
||||
if (!validate(d, k, val, types[k], typeDefs)) {
|
||||
if (exports.invalidHandler) {
|
||||
exports.invalidHandler(k, val, types[k], data)
|
||||
} else if (exports.invalidHandler !== false) {
|
||||
debug("invalid: "+k+"="+val, types[k])
|
||||
}
|
||||
return remove
|
||||
}
|
||||
debug("validated val", d, val, types[k])
|
||||
return d[k]
|
||||
}).filter(function (val) { return val !== remove })
|
||||
|
||||
if (!val.length) delete data[k]
|
||||
else if (isArray) {
|
||||
debug(isArray, data[k], val)
|
||||
data[k] = val
|
||||
} else data[k] = val[0]
|
||||
|
||||
debug("k=%s val=%j", k, val, data[k])
|
||||
})
|
||||
}
|
||||
|
||||
function validateString (data, k, val) {
|
||||
data[k] = String(val)
|
||||
}
|
||||
|
||||
function validatePath (data, k, val) {
|
||||
data[k] = path.resolve(String(val))
|
||||
return true
|
||||
}
|
||||
|
||||
function validateNumber (data, k, val) {
|
||||
debug("validate Number %j %j %j", k, val, isNaN(val))
|
||||
if (isNaN(val)) return false
|
||||
data[k] = +val
|
||||
}
|
||||
|
||||
function validateDate (data, k, val) {
|
||||
debug("validate Date %j %j %j", k, val, Date.parse(val))
|
||||
var s = Date.parse(val)
|
||||
if (isNaN(s)) return false
|
||||
data[k] = new Date(val)
|
||||
}
|
||||
|
||||
function validateBoolean (data, k, val) {
|
||||
if (val instanceof Boolean) val = val.valueOf()
|
||||
else if (typeof val === "string") {
|
||||
if (!isNaN(val)) val = !!(+val)
|
||||
else if (val === "null" || val === "false") val = false
|
||||
else val = true
|
||||
} else val = !!val
|
||||
data[k] = val
|
||||
}
|
||||
|
||||
function validateUrl (data, k, val) {
|
||||
val = url.parse(String(val))
|
||||
if (!val.host) return false
|
||||
data[k] = val.href
|
||||
}
|
||||
|
||||
function validateStream (data, k, val) {
|
||||
if (!(val instanceof Stream)) return false
|
||||
data[k] = val
|
||||
}
|
||||
|
||||
function validate (data, k, val, type, typeDefs) {
|
||||
// arrays are lists of types.
|
||||
if (Array.isArray(type)) {
|
||||
for (var i = 0, l = type.length; i < l; i ++) {
|
||||
if (type[i] === Array) continue
|
||||
if (validate(data, k, val, type[i], typeDefs)) return true
|
||||
}
|
||||
delete data[k]
|
||||
return false
|
||||
}
|
||||
|
||||
// an array of anything?
|
||||
if (type === Array) return true
|
||||
|
||||
// NaN is poisonous. Means that something is not allowed.
|
||||
if (type !== type) {
|
||||
debug("Poison NaN", k, val, type)
|
||||
delete data[k]
|
||||
return false
|
||||
}
|
||||
|
||||
// explicit list of values
|
||||
if (val === type) {
|
||||
debug("Explicitly allowed %j", val)
|
||||
// if (isArray) (data[k] = data[k] || []).push(val)
|
||||
// else data[k] = val
|
||||
data[k] = val
|
||||
return true
|
||||
}
|
||||
|
||||
// now go through the list of typeDefs, validate against each one.
|
||||
var ok = false
|
||||
, types = Object.keys(typeDefs)
|
||||
for (var i = 0, l = types.length; i < l; i ++) {
|
||||
debug("test type %j %j %j", k, val, types[i])
|
||||
var t = typeDefs[types[i]]
|
||||
if (t && type === t.type) {
|
||||
var d = {}
|
||||
ok = false !== t.validate(d, k, val)
|
||||
val = d[k]
|
||||
if (ok) {
|
||||
// if (isArray) (data[k] = data[k] || []).push(val)
|
||||
// else data[k] = val
|
||||
data[k] = val
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
debug("OK? %j (%j %j %j)", ok, k, val, types[i])
|
||||
|
||||
if (!ok) delete data[k]
|
||||
return ok
|
||||
}
|
||||
|
||||
function parse (args, data, remain, types, shorthands) {
|
||||
debug("parse", args, data, remain)
|
||||
|
||||
var key = null
|
||||
, abbrevs = abbrev(Object.keys(types))
|
||||
, shortAbbr = abbrev(Object.keys(shorthands))
|
||||
|
||||
for (var i = 0; i < args.length; i ++) {
|
||||
var arg = args[i]
|
||||
debug("arg", arg)
|
||||
|
||||
if (arg.match(/^-{2,}$/)) {
|
||||
// done with keys.
|
||||
// the rest are args.
|
||||
remain.push.apply(remain, args.slice(i + 1))
|
||||
args[i] = "--"
|
||||
break
|
||||
}
|
||||
var hadEq = false
|
||||
if (arg.charAt(0) === "-" && arg.length > 1) {
|
||||
if (arg.indexOf("=") !== -1) {
|
||||
hadEq = true
|
||||
var v = arg.split("=")
|
||||
arg = v.shift()
|
||||
v = v.join("=")
|
||||
args.splice.apply(args, [i, 1].concat([arg, v]))
|
||||
}
|
||||
|
||||
// see if it's a shorthand
|
||||
// if so, splice and back up to re-parse it.
|
||||
var shRes = resolveShort(arg, shorthands, shortAbbr, abbrevs)
|
||||
debug("arg=%j shRes=%j", arg, shRes)
|
||||
if (shRes) {
|
||||
debug(arg, shRes)
|
||||
args.splice.apply(args, [i, 1].concat(shRes))
|
||||
if (arg !== shRes[0]) {
|
||||
i --
|
||||
continue
|
||||
}
|
||||
}
|
||||
arg = arg.replace(/^-+/, "")
|
||||
var no = null
|
||||
while (arg.toLowerCase().indexOf("no-") === 0) {
|
||||
no = !no
|
||||
arg = arg.substr(3)
|
||||
}
|
||||
|
||||
if (abbrevs[arg]) arg = abbrevs[arg]
|
||||
|
||||
var isArray = types[arg] === Array ||
|
||||
Array.isArray(types[arg]) && types[arg].indexOf(Array) !== -1
|
||||
|
||||
// allow unknown things to be arrays if specified multiple times.
|
||||
if (!types.hasOwnProperty(arg) && data.hasOwnProperty(arg)) {
|
||||
if (!Array.isArray(data[arg]))
|
||||
data[arg] = [data[arg]]
|
||||
isArray = true
|
||||
}
|
||||
|
||||
var val
|
||||
, la = args[i + 1]
|
||||
|
||||
var isBool = typeof no === 'boolean' ||
|
||||
types[arg] === Boolean ||
|
||||
Array.isArray(types[arg]) && types[arg].indexOf(Boolean) !== -1 ||
|
||||
(typeof types[arg] === 'undefined' && !hadEq) ||
|
||||
(la === "false" &&
|
||||
(types[arg] === null ||
|
||||
Array.isArray(types[arg]) && ~types[arg].indexOf(null)))
|
||||
|
||||
if (isBool) {
|
||||
// just set and move along
|
||||
val = !no
|
||||
// however, also support --bool true or --bool false
|
||||
if (la === "true" || la === "false") {
|
||||
val = JSON.parse(la)
|
||||
la = null
|
||||
if (no) val = !val
|
||||
i ++
|
||||
}
|
||||
|
||||
// also support "foo":[Boolean, "bar"] and "--foo bar"
|
||||
if (Array.isArray(types[arg]) && la) {
|
||||
if (~types[arg].indexOf(la)) {
|
||||
// an explicit type
|
||||
val = la
|
||||
i ++
|
||||
} else if ( la === "null" && ~types[arg].indexOf(null) ) {
|
||||
// null allowed
|
||||
val = null
|
||||
i ++
|
||||
} else if ( !la.match(/^-{2,}[^-]/) &&
|
||||
!isNaN(la) &&
|
||||
~types[arg].indexOf(Number) ) {
|
||||
// number
|
||||
val = +la
|
||||
i ++
|
||||
} else if ( !la.match(/^-[^-]/) && ~types[arg].indexOf(String) ) {
|
||||
// string
|
||||
val = la
|
||||
i ++
|
||||
}
|
||||
}
|
||||
|
||||
if (isArray) (data[arg] = data[arg] || []).push(val)
|
||||
else data[arg] = val
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if (la && la.match(/^-{2,}$/)) {
|
||||
la = undefined
|
||||
i --
|
||||
}
|
||||
|
||||
val = la === undefined ? true : la
|
||||
if (isArray) (data[arg] = data[arg] || []).push(val)
|
||||
else data[arg] = val
|
||||
|
||||
i ++
|
||||
continue
|
||||
}
|
||||
remain.push(arg)
|
||||
}
|
||||
}
|
||||
|
||||
function resolveShort (arg, shorthands, shortAbbr, abbrevs) {
|
||||
// handle single-char shorthands glommed together, like
|
||||
// npm ls -glp, but only if there is one dash, and only if
|
||||
// all of the chars are single-char shorthands, and it's
|
||||
// not a match to some other abbrev.
|
||||
arg = arg.replace(/^-+/, '')
|
||||
|
||||
// if it's an exact known option, then don't go any further
|
||||
if (abbrevs[arg] === arg)
|
||||
return null
|
||||
|
||||
// if it's an exact known shortopt, same deal
|
||||
if (shorthands[arg]) {
|
||||
// make it an array, if it's a list of words
|
||||
if (shorthands[arg] && !Array.isArray(shorthands[arg]))
|
||||
shorthands[arg] = shorthands[arg].split(/\s+/)
|
||||
|
||||
return shorthands[arg]
|
||||
}
|
||||
|
||||
// first check to see if this arg is a set of single-char shorthands
|
||||
var singles = shorthands.___singles
|
||||
if (!singles) {
|
||||
singles = Object.keys(shorthands).filter(function (s) {
|
||||
return s.length === 1
|
||||
}).reduce(function (l,r) {
|
||||
l[r] = true
|
||||
return l
|
||||
}, {})
|
||||
shorthands.___singles = singles
|
||||
debug('shorthand singles', singles)
|
||||
}
|
||||
|
||||
var chrs = arg.split("").filter(function (c) {
|
||||
return singles[c]
|
||||
})
|
||||
|
||||
if (chrs.join("") === arg) return chrs.map(function (c) {
|
||||
return shorthands[c]
|
||||
}).reduce(function (l, r) {
|
||||
return l.concat(r)
|
||||
}, [])
|
||||
|
||||
|
||||
// if it's an arg abbrev, and not a literal shorthand, then prefer the arg
|
||||
if (abbrevs[arg] && !shorthands[arg])
|
||||
return null
|
||||
|
||||
// if it's an abbr for a shorthand, then use that
|
||||
if (shortAbbr[arg])
|
||||
arg = shortAbbr[arg]
|
||||
|
||||
// make it an array, if it's a list of words
|
||||
if (shorthands[arg] && !Array.isArray(shorthands[arg]))
|
||||
shorthands[arg] = shorthands[arg].split(/\s+/)
|
||||
|
||||
return shorthands[arg]
|
||||
}
|
||||
|
||||
if (module === require.main) {
|
||||
var assert = require("assert")
|
||||
, util = require("util")
|
||||
|
||||
, shorthands =
|
||||
{ s : ["--loglevel", "silent"]
|
||||
, d : ["--loglevel", "info"]
|
||||
, dd : ["--loglevel", "verbose"]
|
||||
, ddd : ["--loglevel", "silly"]
|
||||
, noreg : ["--no-registry"]
|
||||
, reg : ["--registry"]
|
||||
, "no-reg" : ["--no-registry"]
|
||||
, silent : ["--loglevel", "silent"]
|
||||
, verbose : ["--loglevel", "verbose"]
|
||||
, h : ["--usage"]
|
||||
, H : ["--usage"]
|
||||
, "?" : ["--usage"]
|
||||
, help : ["--usage"]
|
||||
, v : ["--version"]
|
||||
, f : ["--force"]
|
||||
, desc : ["--description"]
|
||||
, "no-desc" : ["--no-description"]
|
||||
, "local" : ["--no-global"]
|
||||
, l : ["--long"]
|
||||
, p : ["--parseable"]
|
||||
, porcelain : ["--parseable"]
|
||||
, g : ["--global"]
|
||||
}
|
||||
|
||||
, types =
|
||||
{ aoa: Array
|
||||
, nullstream: [null, Stream]
|
||||
, date: Date
|
||||
, str: String
|
||||
, browser : String
|
||||
, cache : path
|
||||
, color : ["always", Boolean]
|
||||
, depth : Number
|
||||
, description : Boolean
|
||||
, dev : Boolean
|
||||
, editor : path
|
||||
, force : Boolean
|
||||
, global : Boolean
|
||||
, globalconfig : path
|
||||
, group : [String, Number]
|
||||
, gzipbin : String
|
||||
, logfd : [Number, Stream]
|
||||
, loglevel : ["silent","win","error","warn","info","verbose","silly"]
|
||||
, long : Boolean
|
||||
, "node-version" : [false, String]
|
||||
, npaturl : url
|
||||
, npat : Boolean
|
||||
, "onload-script" : [false, String]
|
||||
, outfd : [Number, Stream]
|
||||
, parseable : Boolean
|
||||
, pre: Boolean
|
||||
, prefix: path
|
||||
, proxy : url
|
||||
, "rebuild-bundle" : Boolean
|
||||
, registry : url
|
||||
, searchopts : String
|
||||
, searchexclude: [null, String]
|
||||
, shell : path
|
||||
, t: [Array, String]
|
||||
, tag : String
|
||||
, tar : String
|
||||
, tmp : path
|
||||
, "unsafe-perm" : Boolean
|
||||
, usage : Boolean
|
||||
, user : String
|
||||
, username : String
|
||||
, userconfig : path
|
||||
, version : Boolean
|
||||
, viewer: path
|
||||
, _exit : Boolean
|
||||
}
|
||||
|
||||
; [["-v", {version:true}, []]
|
||||
,["---v", {version:true}, []]
|
||||
,["ls -s --no-reg connect -d",
|
||||
{loglevel:"info",registry:null},["ls","connect"]]
|
||||
,["ls ---s foo",{loglevel:"silent"},["ls","foo"]]
|
||||
,["ls --registry blargle", {}, ["ls"]]
|
||||
,["--no-registry", {registry:null}, []]
|
||||
,["--no-color true", {color:false}, []]
|
||||
,["--no-color false", {color:true}, []]
|
||||
,["--no-color", {color:false}, []]
|
||||
,["--color false", {color:false}, []]
|
||||
,["--color --logfd 7", {logfd:7,color:true}, []]
|
||||
,["--color=true", {color:true}, []]
|
||||
,["--logfd=10", {logfd:10}, []]
|
||||
,["--tmp=/tmp -tar=gtar",{tmp:"/tmp",tar:"gtar"},[]]
|
||||
,["--tmp=tmp -tar=gtar",
|
||||
{tmp:path.resolve(process.cwd(), "tmp"),tar:"gtar"},[]]
|
||||
,["--logfd x", {}, []]
|
||||
,["a -true -- -no-false", {true:true},["a","-no-false"]]
|
||||
,["a -no-false", {false:false},["a"]]
|
||||
,["a -no-no-true", {true:true}, ["a"]]
|
||||
,["a -no-no-no-false", {false:false}, ["a"]]
|
||||
,["---NO-no-No-no-no-no-nO-no-no"+
|
||||
"-No-no-no-no-no-no-no-no-no"+
|
||||
"-no-no-no-no-NO-NO-no-no-no-no-no-no"+
|
||||
"-no-body-can-do-the-boogaloo-like-I-do"
|
||||
,{"body-can-do-the-boogaloo-like-I-do":false}, []]
|
||||
,["we are -no-strangers-to-love "+
|
||||
"--you-know=the-rules --and=so-do-i "+
|
||||
"---im-thinking-of=a-full-commitment "+
|
||||
"--no-you-would-get-this-from-any-other-guy "+
|
||||
"--no-gonna-give-you-up "+
|
||||
"-no-gonna-let-you-down=true "+
|
||||
"--no-no-gonna-run-around false "+
|
||||
"--desert-you=false "+
|
||||
"--make-you-cry false "+
|
||||
"--no-tell-a-lie "+
|
||||
"--no-no-and-hurt-you false"
|
||||
,{"strangers-to-love":false
|
||||
,"you-know":"the-rules"
|
||||
,"and":"so-do-i"
|
||||
,"you-would-get-this-from-any-other-guy":false
|
||||
,"gonna-give-you-up":false
|
||||
,"gonna-let-you-down":false
|
||||
,"gonna-run-around":false
|
||||
,"desert-you":false
|
||||
,"make-you-cry":false
|
||||
,"tell-a-lie":false
|
||||
,"and-hurt-you":false
|
||||
},["we", "are"]]
|
||||
,["-t one -t two -t three"
|
||||
,{t: ["one", "two", "three"]}
|
||||
,[]]
|
||||
,["-t one -t null -t three four five null"
|
||||
,{t: ["one", "null", "three"]}
|
||||
,["four", "five", "null"]]
|
||||
,["-t foo"
|
||||
,{t:["foo"]}
|
||||
,[]]
|
||||
,["--no-t"
|
||||
,{t:["false"]}
|
||||
,[]]
|
||||
,["-no-no-t"
|
||||
,{t:["true"]}
|
||||
,[]]
|
||||
,["-aoa one -aoa null -aoa 100"
|
||||
,{aoa:["one", null, 100]}
|
||||
,[]]
|
||||
,["-str 100"
|
||||
,{str:"100"}
|
||||
,[]]
|
||||
,["--color always"
|
||||
,{color:"always"}
|
||||
,[]]
|
||||
,["--no-nullstream"
|
||||
,{nullstream:null}
|
||||
,[]]
|
||||
,["--nullstream false"
|
||||
,{nullstream:null}
|
||||
,[]]
|
||||
,["--notadate=2011-01-25"
|
||||
,{notadate: "2011-01-25"}
|
||||
,[]]
|
||||
,["--date 2011-01-25"
|
||||
,{date: new Date("2011-01-25")}
|
||||
,[]]
|
||||
,["-cl 1"
|
||||
,{config: true, length: 1}
|
||||
,[]
|
||||
,{config: Boolean, length: Number, clear: Boolean}
|
||||
,{c: "--config", l: "--length"}]
|
||||
,["--acount bla"
|
||||
,{"acount":true}
|
||||
,["bla"]
|
||||
,{account: Boolean, credentials: Boolean, options: String}
|
||||
,{a:"--account", c:"--credentials",o:"--options"}]
|
||||
,["--clear"
|
||||
,{clear:true}
|
||||
,[]
|
||||
,{clear:Boolean,con:Boolean,len:Boolean,exp:Boolean,add:Boolean,rep:Boolean}
|
||||
,{c:"--con",l:"--len",e:"--exp",a:"--add",r:"--rep"}]
|
||||
,["--file -"
|
||||
,{"file":"-"}
|
||||
,[]
|
||||
,{file:String}
|
||||
,{}]
|
||||
,["--file -"
|
||||
,{"file":true}
|
||||
,["-"]
|
||||
,{file:Boolean}
|
||||
,{}]
|
||||
].forEach(function (test) {
|
||||
var argv = test[0].split(/\s+/)
|
||||
, opts = test[1]
|
||||
, rem = test[2]
|
||||
, actual = nopt(test[3] || types, test[4] || shorthands, argv, 0)
|
||||
, parsed = actual.argv
|
||||
delete actual.argv
|
||||
console.log(util.inspect(actual, false, 2, true), parsed.remain)
|
||||
for (var i in opts) {
|
||||
var e = JSON.stringify(opts[i])
|
||||
, a = JSON.stringify(actual[i] === undefined ? null : actual[i])
|
||||
if (e && typeof e === "object") {
|
||||
assert.deepEqual(e, a)
|
||||
} else {
|
||||
assert.equal(e, a)
|
||||
}
|
||||
}
|
||||
assert.deepEqual(rem, parsed.remain)
|
||||
})
|
||||
}
|
3
node_modules/markdown/node_modules/nopt/node_modules/abbrev/CONTRIBUTING.md
generated
vendored
Normal file
3
node_modules/markdown/node_modules/nopt/node_modules/abbrev/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
To get started, <a
|
||||
href="http://www.clahub.com/agreements/isaacs/abbrev-js">sign the
|
||||
Contributor License Agreement</a>.
|
23
node_modules/markdown/node_modules/nopt/node_modules/abbrev/LICENSE
generated
vendored
Normal file
23
node_modules/markdown/node_modules/nopt/node_modules/abbrev/LICENSE
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
23
node_modules/markdown/node_modules/nopt/node_modules/abbrev/README.md
generated
vendored
Normal file
23
node_modules/markdown/node_modules/nopt/node_modules/abbrev/README.md
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
# abbrev-js
|
||||
|
||||
Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
|
||||
|
||||
Usage:
|
||||
|
||||
var abbrev = require("abbrev");
|
||||
abbrev("foo", "fool", "folding", "flop");
|
||||
|
||||
// returns:
|
||||
{ fl: 'flop'
|
||||
, flo: 'flop'
|
||||
, flop: 'flop'
|
||||
, fol: 'folding'
|
||||
, fold: 'folding'
|
||||
, foldi: 'folding'
|
||||
, foldin: 'folding'
|
||||
, folding: 'folding'
|
||||
, foo: 'foo'
|
||||
, fool: 'fool'
|
||||
}
|
||||
|
||||
This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
|
62
node_modules/markdown/node_modules/nopt/node_modules/abbrev/abbrev.js
generated
vendored
Normal file
62
node_modules/markdown/node_modules/nopt/node_modules/abbrev/abbrev.js
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
module.exports = exports = abbrev.abbrev = abbrev
|
||||
|
||||
abbrev.monkeyPatch = monkeyPatch
|
||||
|
||||
function monkeyPatch () {
|
||||
Object.defineProperty(Array.prototype, 'abbrev', {
|
||||
value: function () { return abbrev(this) },
|
||||
enumerable: false, configurable: true, writable: true
|
||||
})
|
||||
|
||||
Object.defineProperty(Object.prototype, 'abbrev', {
|
||||
value: function () { return abbrev(Object.keys(this)) },
|
||||
enumerable: false, configurable: true, writable: true
|
||||
})
|
||||
}
|
||||
|
||||
function abbrev (list) {
|
||||
if (arguments.length !== 1 || !Array.isArray(list)) {
|
||||
list = Array.prototype.slice.call(arguments, 0)
|
||||
}
|
||||
for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
|
||||
args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
|
||||
}
|
||||
|
||||
// sort them lexicographically, so that they're next to their nearest kin
|
||||
args = args.sort(lexSort)
|
||||
|
||||
// walk through each, seeing how much it has in common with the next and previous
|
||||
var abbrevs = {}
|
||||
, prev = ""
|
||||
for (var i = 0, l = args.length ; i < l ; i ++) {
|
||||
var current = args[i]
|
||||
, next = args[i + 1] || ""
|
||||
, nextMatches = true
|
||||
, prevMatches = true
|
||||
if (current === next) continue
|
||||
for (var j = 0, cl = current.length ; j < cl ; j ++) {
|
||||
var curChar = current.charAt(j)
|
||||
nextMatches = nextMatches && curChar === next.charAt(j)
|
||||
prevMatches = prevMatches && curChar === prev.charAt(j)
|
||||
if (!nextMatches && !prevMatches) {
|
||||
j ++
|
||||
break
|
||||
}
|
||||
}
|
||||
prev = current
|
||||
if (j === cl) {
|
||||
abbrevs[current] = current
|
||||
continue
|
||||
}
|
||||
for (var a = current.substr(0, j) ; j <= cl ; j ++) {
|
||||
abbrevs[a] = current
|
||||
a += current.charAt(j)
|
||||
}
|
||||
}
|
||||
return abbrevs
|
||||
}
|
||||
|
||||
function lexSort (a, b) {
|
||||
return a === b ? 0 : a > b ? 1 : -1
|
||||
}
|
29
node_modules/markdown/node_modules/nopt/node_modules/abbrev/package.json
generated
vendored
Normal file
29
node_modules/markdown/node_modules/nopt/node_modules/abbrev/package.json
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "abbrev",
|
||||
"version": "1.0.5",
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"author": {
|
||||
"name": "Isaac Z. Schlueter",
|
||||
"email": "i@izs.me"
|
||||
},
|
||||
"main": "abbrev.js",
|
||||
"scripts": {
|
||||
"test": "node test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/isaacs/abbrev-js"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/isaacs/abbrev-js/raw/master/LICENSE"
|
||||
},
|
||||
"readme": "# abbrev-js\n\nJust like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).\n\nUsage:\n\n var abbrev = require(\"abbrev\");\n abbrev(\"foo\", \"fool\", \"folding\", \"flop\");\n \n // returns:\n { fl: 'flop'\n , flo: 'flop'\n , flop: 'flop'\n , fol: 'folding'\n , fold: 'folding'\n , foldi: 'folding'\n , foldin: 'folding'\n , folding: 'folding'\n , foo: 'foo'\n , fool: 'fool'\n }\n\nThis is handy for command-line scripts, or other cases where you want to be able to accept shorthands.\n",
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "abbrev@1.0.5",
|
||||
"dist": {
|
||||
"shasum": "8878621df7d367d2b65a37fd163e59df351fbfa4"
|
||||
},
|
||||
"_from": "abbrev@1",
|
||||
"_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz"
|
||||
}
|
47
node_modules/markdown/node_modules/nopt/node_modules/abbrev/test.js
generated
vendored
Normal file
47
node_modules/markdown/node_modules/nopt/node_modules/abbrev/test.js
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
var abbrev = require('./abbrev.js')
|
||||
var assert = require("assert")
|
||||
var util = require("util")
|
||||
|
||||
console.log("TAP Version 13")
|
||||
var count = 0
|
||||
|
||||
function test (list, expect) {
|
||||
count++
|
||||
var actual = abbrev(list)
|
||||
assert.deepEqual(actual, expect,
|
||||
"abbrev("+util.inspect(list)+") === " + util.inspect(expect) + "\n"+
|
||||
"actual: "+util.inspect(actual))
|
||||
actual = abbrev.apply(exports, list)
|
||||
assert.deepEqual(abbrev.apply(exports, list), expect,
|
||||
"abbrev("+list.map(JSON.stringify).join(",")+") === " + util.inspect(expect) + "\n"+
|
||||
"actual: "+util.inspect(actual))
|
||||
console.log('ok - ' + list.join(' '))
|
||||
}
|
||||
|
||||
test([ "ruby", "ruby", "rules", "rules", "rules" ],
|
||||
{ rub: 'ruby'
|
||||
, ruby: 'ruby'
|
||||
, rul: 'rules'
|
||||
, rule: 'rules'
|
||||
, rules: 'rules'
|
||||
})
|
||||
test(["fool", "foom", "pool", "pope"],
|
||||
{ fool: 'fool'
|
||||
, foom: 'foom'
|
||||
, poo: 'pool'
|
||||
, pool: 'pool'
|
||||
, pop: 'pope'
|
||||
, pope: 'pope'
|
||||
})
|
||||
test(["a", "ab", "abc", "abcd", "abcde", "acde"],
|
||||
{ a: 'a'
|
||||
, ab: 'ab'
|
||||
, abc: 'abc'
|
||||
, abcd: 'abcd'
|
||||
, abcde: 'abcde'
|
||||
, ac: 'acde'
|
||||
, acd: 'acde'
|
||||
, acde: 'acde'
|
||||
})
|
||||
|
||||
console.log("0..%d", count)
|
36
node_modules/markdown/node_modules/nopt/package.json
generated
vendored
Normal file
36
node_modules/markdown/node_modules/nopt/package.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
68
node_modules/markdown/package.json
generated
vendored
Normal file
68
node_modules/markdown/package.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
5
node_modules/markdown/seed.yml
generated
vendored
Normal file
5
node_modules/markdown/seed.yml
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
name: markdown-js
|
||||
description: JavaScript implementation of Markdown
|
||||
tags: markdown parser
|
||||
version: 0.1.2
|
1
node_modules/pushover-notifications/.npmignore
generated
vendored
Normal file
1
node_modules/pushover-notifications/.npmignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
npm-debug.log
|
16
node_modules/pushover-notifications/LICENSE
generated
vendored
Normal file
16
node_modules/pushover-notifications/LICENSE
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Aaron Bieber <deftly@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
89
node_modules/pushover-notifications/README.md
generated
vendored
Normal file
89
node_modules/pushover-notifications/README.md
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||

|
||||
|
||||
Send [pushover.net](http://pushover.net) notifications from Node.JS
|
||||
|
||||
## Usage
|
||||
|
||||
### Install
|
||||
|
||||
npm install pushover-notifications
|
||||
|
||||
### Pushover API values
|
||||
|
||||
Any API paramaters, as found on https://pushover.net/api, can be passed in the object. For example, `retry` and `expire` can be added to the object being passed to `.send`! Here's an example with many different parameters.
|
||||
```javascript
|
||||
var msg = {
|
||||
message: "This is a message",
|
||||
title: "Well - this is fantastic",
|
||||
sound: 'magic',
|
||||
device: 'test_device',
|
||||
priority: 2,
|
||||
url: "http://pushover.net",
|
||||
url_title: "Pushover Website"
|
||||
};
|
||||
```
|
||||
## Examples
|
||||
|
||||
### Sending a message
|
||||
```javascript
|
||||
|
||||
var push = require( 'pushover-notifications' );
|
||||
|
||||
var p = new push( {
|
||||
user: process.env['PUSHOVER_USER'],
|
||||
token: process.env['PUSHOVER_TOKEN'],
|
||||
// onerror: function(error) {},
|
||||
// update_sounds: true // update the list of sounds every day - will
|
||||
// prevent app from exiting.
|
||||
});
|
||||
|
||||
var msg = {
|
||||
// These values correspond to the parameters detailed on https://pushover.net/api
|
||||
// 'message' is required. All other values are optional.
|
||||
message: 'omg node test', // required
|
||||
title: "Well - this is fantastic",
|
||||
sound: 'magic',
|
||||
device: 'devicename',
|
||||
priority: 1
|
||||
};
|
||||
|
||||
p.send( msg, function( err, result ) {
|
||||
if ( err ) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
console.log( result );
|
||||
});
|
||||
```
|
||||
|
||||
### Sending a message to multiple users
|
||||
```javascript
|
||||
|
||||
var users = [
|
||||
'token1',
|
||||
'token2',
|
||||
'token3'
|
||||
];
|
||||
|
||||
var msg = {
|
||||
message: 'omg node test',
|
||||
title: "Well - this is fantastic",
|
||||
sound: 'magic' // optional
|
||||
priority: 1 // optional,
|
||||
};
|
||||
|
||||
for ( var i = 0, l = users.length; i < l; i++ ) {
|
||||
|
||||
msg.user = users[i];
|
||||
// token can be overwritten as well.
|
||||
|
||||
p.send( msg, function( err, result ) {
|
||||
if ( err ) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
console.log( result );
|
||||
});
|
||||
}
|
||||
|
||||
```
|
1
node_modules/pushover-notifications/index.js
generated
vendored
Normal file
1
node_modules/pushover-notifications/index.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require( './lib/pushover' );
|
180
node_modules/pushover-notifications/lib/pushover.js
generated
vendored
Normal file
180
node_modules/pushover-notifications/lib/pushover.js
generated
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
var https = require('https'),
|
||||
url = require('url'),
|
||||
qs = require('querystring'),
|
||||
p_url = 'https://api.pushover.net/1/messages.json';
|
||||
|
||||
function setDefaults(o) {
|
||||
var def = [
|
||||
'device',
|
||||
'title',
|
||||
'url',
|
||||
'url_title',
|
||||
'priority',
|
||||
'timestamp',
|
||||
'sound'
|
||||
];
|
||||
|
||||
var i = 0; l = def.length;
|
||||
for (; i < l; i++) {
|
||||
if (!o[def[i]]) {
|
||||
o[def[i]] = '';
|
||||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
function Pushover(opts) {
|
||||
var self = this;
|
||||
this.token = opts.token;
|
||||
this.user = opts.user;
|
||||
this.httpOptions = opts.httpOptions;
|
||||
this.sounds = {
|
||||
"pushover":"Pushover (default)",
|
||||
"bike":"Bike",
|
||||
"bugle":"Bugle",
|
||||
"cashregister":"Cash Register",
|
||||
"classical":"Classical",
|
||||
"cosmic":"Cosmic",
|
||||
"falling":"Falling",
|
||||
"gamelan":"Gamelan",
|
||||
"incoming":"Incoming",
|
||||
"intermission":"Intermission",
|
||||
"magic":"Magic",
|
||||
"mechanical":"Mechanical",
|
||||
"pianobar":"Piano Bar",
|
||||
"siren":"Siren",
|
||||
"spacealarm":"Space Alarm",
|
||||
"tugboat":"Tug Boat",
|
||||
"alien":"Alien Alarm (long)",
|
||||
"climb":"Climb (long)",
|
||||
"persistent":"Persistent (long)",
|
||||
"echo":"Pushover Echo (long)",
|
||||
"updown":"Up Down (long)",
|
||||
"none":"None (silent)"
|
||||
};
|
||||
|
||||
if (opts.debug) {
|
||||
this.debug = opts.debug;
|
||||
}
|
||||
|
||||
if (opts.onerror) {
|
||||
this.onerror = opts.onerror;
|
||||
}
|
||||
|
||||
if (opts.update_sounds) {
|
||||
self.updateSounds();
|
||||
setInterval(function() {
|
||||
self.updateSounds();
|
||||
}, 86400000);
|
||||
}
|
||||
}
|
||||
|
||||
Pushover.prototype.errors = function(d) {
|
||||
if (typeof d === 'string') {
|
||||
d = JSON.parse(d);
|
||||
}
|
||||
|
||||
if (d.errors) {
|
||||
if (this.onerror) {
|
||||
this.onerror.call(null, d.errors[0]);
|
||||
} else {
|
||||
throw new Error(d.errors[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Pushover.prototype.updateSounds = function() {
|
||||
var self = this, data = '';
|
||||
var surl = 'https://api.pushover.net/1/sounds.json?token=' + self.token;
|
||||
var req = https.request(url.parse(surl) , function(res) {
|
||||
res.on('end', function() {
|
||||
var j = JSON.parse(data);
|
||||
self.errors(data);
|
||||
self.sounds = j.sounds;
|
||||
});
|
||||
|
||||
res.on('data', function(chunk) {
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
req.on('error', function(e) {
|
||||
err = e;
|
||||
});
|
||||
|
||||
req.write('');
|
||||
req.end();
|
||||
};
|
||||
|
||||
Pushover.prototype.send = function(obj, fn) {
|
||||
var self = this;
|
||||
var o = url.parse(p_url);
|
||||
o.method = "POST";
|
||||
|
||||
obj = setDefaults(obj);
|
||||
|
||||
if (! self.sounds[ obj.sound ]) {
|
||||
obj.sound = 'pushover';
|
||||
}
|
||||
|
||||
var req_string = {
|
||||
token: self.token || obj.token,
|
||||
user: self.user || obj.user
|
||||
};
|
||||
|
||||
var p;
|
||||
for (p in obj) {
|
||||
req_string[ p ] = obj[p];
|
||||
}
|
||||
|
||||
req_string = qs.stringify(req_string);
|
||||
|
||||
o.headers = {
|
||||
'Content-Length': req_string.length
|
||||
};
|
||||
|
||||
var httpOpts = self.httpOptions;
|
||||
if (httpOpts) {
|
||||
Object.keys(httpOpts).forEach(function(key) {
|
||||
o[key] = httpOpts[key];
|
||||
});
|
||||
}
|
||||
|
||||
var req = https.request(o, function(res) {
|
||||
if (self.debug) {
|
||||
console.log(res.statusCode);
|
||||
}
|
||||
var err;
|
||||
var data = '';
|
||||
res.on('end', function() {
|
||||
self.errors(data);
|
||||
if (fn) {
|
||||
fn.call(null, err, data);
|
||||
}
|
||||
});
|
||||
|
||||
res.on('data', function(chunk) {
|
||||
data += chunk;
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', function(err) {
|
||||
if (fn) {
|
||||
fn.call(null, err);
|
||||
}
|
||||
// In the tests the "end" event did not get emitted if "error" was emitted,
|
||||
// but to be sure that the callback is not get called twice, null the callback function
|
||||
fn = null;
|
||||
});
|
||||
|
||||
|
||||
if (self.debug) {
|
||||
console.log (req_string);
|
||||
}
|
||||
req.write(req_string);
|
||||
req.end();
|
||||
};
|
||||
|
||||
exports = module.exports = Pushover;
|
28
node_modules/pushover-notifications/package.json
generated
vendored
Normal file
28
node_modules/pushover-notifications/package.json
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "Aaron Bieber",
|
||||
"email": "aaron@qbit.io"
|
||||
},
|
||||
"name": "pushover-notifications",
|
||||
"description": "Pushover API for node.js",
|
||||
"version": "0.2.2",
|
||||
"homepage": "http://github.com/qbit/node-pushover",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/qbit/node-pushover.git"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {},
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"readme": "\n\nSend [pushover.net](http://pushover.net) notifications from Node.JS\n\n## Usage\n\n### Install\n\n\tnpm install pushover-notifications\n\t\n### Pushover API values\n\nAny API paramaters, as found on https://pushover.net/api, can be passed in the object. For example, `retry` and `expire` can be added to the object being passed to `.send`! Here's an example with many different parameters.\n```javascript\nvar msg = {\n\tmessage: \"This is a message\",\n\ttitle: \"Well - this is fantastic\",\n\tsound: 'magic',\n\tdevice: 'test_device',\n\tpriority: 2,\n\turl: \"http://pushover.net\",\n\turl_title: \"Pushover Website\"\n};\n```\n## Examples\n\n### Sending a message\n```javascript\n\nvar push = require( 'pushover-notifications' );\n\nvar p = new push( {\n\tuser: process.env['PUSHOVER_USER'],\n\ttoken: process.env['PUSHOVER_TOKEN'],\n\t// onerror: function(error) {},\n\t// update_sounds: true // update the list of sounds every day - will\n\t// prevent app from exiting.\n});\n\nvar msg = {\n\t// These values correspond to the parameters detailed on https://pushover.net/api\n\t// 'message' is required. All other values are optional.\n\tmessage: 'omg node test',\t// required\n\ttitle: \"Well - this is fantastic\",\n\tsound: 'magic',\n\tdevice: 'devicename',\n\tpriority: 1\n};\n\np.send( msg, function( err, result ) {\n\tif ( err ) {\n\t\tthrow err;\n\t}\n\n\tconsole.log( result );\n});\n```\n\n### Sending a message to multiple users\n```javascript\n\nvar users = [\n 'token1',\n 'token2',\n 'token3'\n];\n\nvar msg = {\n message: 'omg node test',\n title: \"Well - this is fantastic\",\n sound: 'magic' // optional\n priority: 1 // optional,\n};\n\nfor ( var i = 0, l = users.length; i < l; i++ ) {\n\n msg.user = users[i];\n // token can be overwritten as well.\n\n p.send( msg, function( err, result ) {\n if ( err ) {\n throw err;\n }\n\n console.log( result );\n });\n}\n\n```\n",
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "pushover-notifications@0.2.2",
|
||||
"dist": {
|
||||
"shasum": "b151e5729b7014d84dcb71b1a86c247c124eb277"
|
||||
},
|
||||
"_from": "pushover-notifications@",
|
||||
"_resolved": "https://registry.npmjs.org/pushover-notifications/-/pushover-notifications-0.2.2.tgz"
|
||||
}
|
25
node_modules/pushover-notifications/test/test-onerror.js
generated
vendored
Normal file
25
node_modules/pushover-notifications/test/test-onerror.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
var push = require( '../lib/pushover.js' );
|
||||
|
||||
var p = new push( {
|
||||
user: process.env['PUSHOVER_USER'],
|
||||
token: process.env['PUSHOVER_TOKEN'],
|
||||
update_sounds: false,
|
||||
debug: true,
|
||||
onerror: function(err) {
|
||||
console.log('ERROR!', err);
|
||||
}
|
||||
});
|
||||
|
||||
var msg = {
|
||||
message: 'omg node test',
|
||||
sound: 'magic',
|
||||
title: "Well - this is fantastic",
|
||||
};
|
||||
|
||||
// console.log( p );
|
||||
|
||||
p.send( msg, function( err, result ) {
|
||||
console.log( 'error', err );
|
||||
console.log( 'result', result );
|
||||
// process.exit(0);
|
||||
});
|
22
node_modules/pushover-notifications/test/test.js
generated
vendored
Normal file
22
node_modules/pushover-notifications/test/test.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
var push = require( '../lib/pushover.js' );
|
||||
|
||||
var p = new push( {
|
||||
user: process.env['PUSHOVER_USER'],
|
||||
token: process.env['PUSHOVER_TOKEN'],
|
||||
update_sounds: false,
|
||||
debug: true
|
||||
});
|
||||
|
||||
var msg = {
|
||||
message: 'omg node test',
|
||||
sound: 'magic',
|
||||
title: "Well - this is fantastic",
|
||||
};
|
||||
|
||||
// console.log( p );
|
||||
|
||||
p.send( msg, function( err, result ) {
|
||||
console.log( 'error', err );
|
||||
console.log( 'result', result );
|
||||
// process.exit(0);
|
||||
});
|
21
node_modules/pushover-notifications/test/test_multi.js
generated
vendored
Normal file
21
node_modules/pushover-notifications/test/test_multi.js
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
var push = require( '../lib/pushover.js' );
|
||||
|
||||
var p = new push( {
|
||||
// user: process.env['PUSHOVER_USER'],
|
||||
token: process.env['PUSHOVER_TOKEN'],
|
||||
debug: true
|
||||
});
|
||||
|
||||
var msg = {
|
||||
message: 'omg node test',
|
||||
title: "Well - this is fantastic",
|
||||
user: process.env['PUSHOVER_USER']
|
||||
};
|
||||
|
||||
// console.log( p );
|
||||
|
||||
p.send( msg, function( err, result ) {
|
||||
console.log( err );
|
||||
console.log( result );
|
||||
process.exit(0);
|
||||
});
|
5
node_modules/strong-cluster-connect-store/.idea/encodings.xml
generated
vendored
Normal file
5
node_modules/strong-cluster-connect-store/.idea/encodings.xml
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
</project>
|
||||
|
9
node_modules/strong-cluster-connect-store/.idea/inspectionProfiles/Project_Default.xml
generated
vendored
Normal file
9
node_modules/strong-cluster-connect-store/.idea/inspectionProfiles/Project_Default.xml
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0" is_locked="false">
|
||||
<option name="myName" value="Project Default" />
|
||||
<option name="myLocal" value="false" />
|
||||
<inspection_tool class="JSHint" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
<inspection_tool class="JSLastCommaInArrayLiteral" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="JSLastCommaInObjectLiteral" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
7
node_modules/strong-cluster-connect-store/.idea/inspectionProfiles/profiles_settings.xml
generated
vendored
Normal file
7
node_modules/strong-cluster-connect-store/.idea/inspectionProfiles/profiles_settings.xml
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Project Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="true" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
11
node_modules/strong-cluster-connect-store/.idea/jsLibraryMappings.xml
generated
vendored
Normal file
11
node_modules/strong-cluster-connect-store/.idea/jsLibraryMappings.xml
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptLibraryMappings">
|
||||
<file url="file://$PROJECT_DIR$" libraries="{Node.js Dependencies for strong-cluster-connect-store}" />
|
||||
<file url="PROJECT" libraries="{Node.js v0.11.3 Core Modules}" />
|
||||
<includedPredefinedLibrary name="Node.js Globals" />
|
||||
<excludedPredefinedLibrary name="HTML" />
|
||||
<excludedPredefinedLibrary name="HTML5 / EcmaScript 5" />
|
||||
</component>
|
||||
</project>
|
||||
|
62
node_modules/strong-cluster-connect-store/.idea/jsLinters/jshint.xml
generated
vendored
Normal file
62
node_modules/strong-cluster-connect-store/.idea/jsLinters/jshint.xml
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JSHintConfiguration" version="2.1.4" use-config-file="true">
|
||||
<option bitwise="true" />
|
||||
<option camelcase="false" />
|
||||
<option curly="true" />
|
||||
<option eqeqeq="true" />
|
||||
<option forin="true" />
|
||||
<option immed="false" />
|
||||
<option latedef="false" />
|
||||
<option newcap="false" />
|
||||
<option noarg="true" />
|
||||
<option noempty="true" />
|
||||
<option nonew="true" />
|
||||
<option plusplus="false" />
|
||||
<option undef="true" />
|
||||
<option unused="false" />
|
||||
<option strict="true" />
|
||||
<option trailing="false" />
|
||||
<option asi="false" />
|
||||
<option boss="false" />
|
||||
<option debug="false" />
|
||||
<option eqnull="false" />
|
||||
<option esnext="false" />
|
||||
<option evil="false" />
|
||||
<option expr="false" />
|
||||
<option funcscope="false" />
|
||||
<option globalstrict="false" />
|
||||
<option iterator="false" />
|
||||
<option lastsemic="false" />
|
||||
<option laxbreak="false" />
|
||||
<option laxcomma="false" />
|
||||
<option loopfunc="false" />
|
||||
<option multistr="false" />
|
||||
<option proto="false" />
|
||||
<option scripturl="false" />
|
||||
<option smarttabs="false" />
|
||||
<option shadow="false" />
|
||||
<option sub="false" />
|
||||
<option supernew="false" />
|
||||
<option validthis="false" />
|
||||
<option browser="true" />
|
||||
<option couch="false" />
|
||||
<option devel="false" />
|
||||
<option dojo="false" />
|
||||
<option jquery="false" />
|
||||
<option mootools="false" />
|
||||
<option node="false" />
|
||||
<option nonstandard="false" />
|
||||
<option prototypejs="false" />
|
||||
<option rhino="false" />
|
||||
<option worker="false" />
|
||||
<option wsh="false" />
|
||||
<option yui="false" />
|
||||
<option nomen="false" />
|
||||
<option onevar="false" />
|
||||
<option passfail="false" />
|
||||
<option white="false" />
|
||||
<option maxerr="50" />
|
||||
</component>
|
||||
</project>
|
||||
|
13
node_modules/strong-cluster-connect-store/.idea/libraries/Node_js_Dependencies_for_strong_cluster_connect_store.xml
generated
vendored
Normal file
13
node_modules/strong-cluster-connect-store/.idea/libraries/Node_js_Dependencies_for_strong_cluster_connect_store.xml
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Node.js Dependencies for strong-cluster-connect-store" type="javaScript">
|
||||
<properties>
|
||||
<sourceFilesUrls>
|
||||
<item url="file://$PROJECT_DIR$/node_modules" />
|
||||
</sourceFilesUrls>
|
||||
</properties>
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/node_modules" />
|
||||
</CLASSES>
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
5
node_modules/strong-cluster-connect-store/.idea/misc.xml
generated
vendored
Normal file
5
node_modules/strong-cluster-connect-store/.idea/misc.xml
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" />
|
||||
</project>
|
||||
|
9
node_modules/strong-cluster-connect-store/.idea/modules.xml
generated
vendored
Normal file
9
node_modules/strong-cluster-connect-store/.idea/modules.xml
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/strong-cluster-connect-store.iml" filepath="$PROJECT_DIR$/.idea/strong-cluster-connect-store.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
5
node_modules/strong-cluster-connect-store/.idea/scopes/scope_settings.xml
generated
vendored
Normal file
5
node_modules/strong-cluster-connect-store/.idea/scopes/scope_settings.xml
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<component name="DependencyValidationManager">
|
||||
<state>
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||
</state>
|
||||
</component>
|
11
node_modules/strong-cluster-connect-store/.idea/strong-cluster-connect-store.iml
generated
vendored
Normal file
11
node_modules/strong-cluster-connect-store/.idea/strong-cluster-connect-store.iml
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Node.js v0.11.3 Core Modules" level="application" />
|
||||
<orderEntry type="library" name="Node.js Dependencies for strong-cluster-connect-store" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
7
node_modules/strong-cluster-connect-store/.idea/vcs.xml
generated
vendored
Normal file
7
node_modules/strong-cluster-connect-store/.idea/vcs.xml
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
476
node_modules/strong-cluster-connect-store/.idea/workspace.xml
generated
vendored
Normal file
476
node_modules/strong-cluster-connect-store/.idea/workspace.xml
generated
vendored
Normal file
@ -0,0 +1,476 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="c9cd60f5-0112-4cd0-aadd-d8bb05bbf943" name="Default" comment="">
|
||||
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/cluster-store.js" afterPath="$PROJECT_DIR$/test/cluster-store.js" />
|
||||
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/package.json" afterPath="$PROJECT_DIR$/package.json" />
|
||||
</list>
|
||||
<ignored path="strong-cluster-connect-store.iws" />
|
||||
<ignored path=".idea/workspace.xml" />
|
||||
<option name="TRACKING_ENABLED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
|
||||
<component name="CreatePatchCommitExecutor">
|
||||
<option name="PATCH_PATH" value="" />
|
||||
</component>
|
||||
<component name="DaemonCodeAnalyzer">
|
||||
<disable_hints />
|
||||
</component>
|
||||
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
|
||||
<component name="FavoritesManager">
|
||||
<favorites_list name="strong-cluster-connect-store" />
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file leaf-file-name="cluster-store.js" pinned="false" current="true" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/test/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.12448133" vertical-offset="1920" max-vertical-offset="2415">
|
||||
<caret line="132" column="22" selection-start-line="132" selection-start-column="22" selection-end-line="132" selection-end-column="22" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="index.js" pinned="false" current="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/express-session/index.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="3660">
|
||||
<caret line="167" column="10" selection-start-line="167" selection-start-column="10" selection-end-line="167" selection-end-column="10" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="cluster-store.js" pinned="false" current="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="945" max-vertical-offset="1815">
|
||||
<caret line="47" column="32" selection-start-line="47" selection-start-column="32" selection-end-line="47" selection-end-column="32" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="FindManager">
|
||||
<FindUsagesManager>
|
||||
<setting name="OPEN_NEW_TAB" value="false" />
|
||||
</FindUsagesManager>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="GitLogSettings">
|
||||
<option name="myDateState">
|
||||
<MyDateState />
|
||||
</option>
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="changedFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/lib/ClusterStore.js" />
|
||||
<option value="$PROJECT_DIR$/test/ClusterStore.js" />
|
||||
<option value="$PROJECT_DIR$/README.md" />
|
||||
<option value="$PROJECT_DIR$/lib/cluster-store.js" />
|
||||
<option value="$PROJECT_DIR$/test/cluster-store.js" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="NodeJsMochaPackageDirSetting">
|
||||
<data>$PROJECT_DIR$/node_modules/mocha</data>
|
||||
</component>
|
||||
<component name="ProjectFrameBounds">
|
||||
<option name="x" value="55" />
|
||||
<option name="y" value="22" />
|
||||
<option name="width" value="1385" />
|
||||
<option name="height" value="878" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectReloadState">
|
||||
<option name="STATE" value="0" />
|
||||
</component>
|
||||
<component name="ProjectView">
|
||||
<navigator currentView="ProjectPane" proportions="" version="1">
|
||||
<flattenPackages />
|
||||
<showMembers />
|
||||
<showModules />
|
||||
<showLibraryContents />
|
||||
<hideEmptyPackages />
|
||||
<abbreviatePackageNames />
|
||||
<autoscrollToSource />
|
||||
<autoscrollFromSource />
|
||||
<sortByType />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="cluster-connect-store" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="cluster-connect-store" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="cluster-connect-store" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="cluster-connect-store" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="cluster-connect-store" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="test" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="cluster-connect-store" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="cluster-connect-store" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="lib" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="Scope" />
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="options.lastSelected" value="settings.nodejs" />
|
||||
<property name="recentsLimit" value="5" />
|
||||
<property name="restartRequiresConfirmation" value="true" />
|
||||
<property name="GoToClass.includeJavaFiles" value="false" />
|
||||
</component>
|
||||
<component name="RunManager" selected="Mocha.Unit-tests">
|
||||
<configuration default="true" type="DartUnitRunConfigurationType" factoryName="DartUnit">
|
||||
<option name="VMOptions" />
|
||||
<option name="arguments" />
|
||||
<option name="filePath" />
|
||||
<option name="scope" value="ALL" />
|
||||
<option name="testName" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application">
|
||||
<option name="VMOptions" />
|
||||
<option name="arguments" />
|
||||
<option name="filePath" />
|
||||
<option name="name" value="Dart" />
|
||||
<option name="saveOutputToFile" value="false" />
|
||||
<option name="showConsoleOnStdErr" value="false" />
|
||||
<option name="showConsoleOnStdOut" value="false" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="JSTestDriver:ConfigurationType" factoryName="JsTestDriver">
|
||||
<setting name="configLocationType" value="CONFIG_FILE" />
|
||||
<setting name="settingsFile" value="" />
|
||||
<setting name="serverType" value="INTERNAL" />
|
||||
<setting name="preferredDebugBrowser" value="Chrome" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="JavaScriptTestRunnerKarma" factoryName="Karma" config-file="">
|
||||
<envs />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="CucumberJavaScriptRunConfigurationType" factoryName="Cucumber.js">
|
||||
<option name="cucumberJsArguments" />
|
||||
<option name="executablePath" />
|
||||
<option name="filePath" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="mocha-javascript-test-runner" factoryName="Mocha">
|
||||
<node-options />
|
||||
<working-directory>$PROJECT_DIR$</working-directory>
|
||||
<pass-parent-env>true</pass-parent-env>
|
||||
<envs />
|
||||
<ui>BDD</ui>
|
||||
<extra-mocha-options />
|
||||
<test-directory />
|
||||
<recursive>false</recursive>
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="NodeJSConfigurationType" factoryName="Node.js" working-dir="">
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="false" name="Unit-tests" type="mocha-javascript-test-runner" factoryName="Mocha">
|
||||
<node-options />
|
||||
<working-directory>$PROJECT_DIR$</working-directory>
|
||||
<pass-parent-env>true</pass-parent-env>
|
||||
<envs />
|
||||
<ui>BDD</ui>
|
||||
<extra-mocha-options />
|
||||
<test-directory>$PROJECT_DIR$/test</test-directory>
|
||||
<recursive>false</recursive>
|
||||
<RunnerSettings RunnerId="MochaDebugRunner" />
|
||||
<RunnerSettings RunnerId="RunnerForMochaJavaScript" />
|
||||
<ConfigurationWrapper RunnerId="MochaDebugRunner" />
|
||||
<ConfigurationWrapper RunnerId="RunnerForMochaJavaScript" />
|
||||
<method />
|
||||
</configuration>
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="Mocha.Unit-tests" />
|
||||
</list>
|
||||
</component>
|
||||
<component name="ShelveChangesManager" show_recycled="false" />
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="c9cd60f5-0112-4cd0-aadd-d8bb05bbf943" name="Default" comment="" />
|
||||
<created>1373452074532</created>
|
||||
<updated>1373452074532</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="55" y="22" width="1385" height="878" extended-state="6" />
|
||||
<editor active="true" />
|
||||
<layout>
|
||||
<window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.24926686" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3986842" sideWeight="0.7503671" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2496329" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.32894737" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32894737" sideWeight="0.7503671" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="Vcs.Log.UiProperties">
|
||||
<option name="RECENTLY_FILTERED_USER_GROUPS">
|
||||
<collection />
|
||||
</option>
|
||||
<option name="RECENTLY_FILTERED_BRANCH_GROUPS">
|
||||
<collection />
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsContentAnnotationSettings">
|
||||
<option name="myLimit" value="2678400000" />
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="myTodoPanelSettings">
|
||||
<TodoPanelSettings />
|
||||
</option>
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
<option name="time" value="1" />
|
||||
</breakpoint-manager>
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/test/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="105" max-vertical-offset="2385">
|
||||
<caret line="7" column="34" selection-start-line="7" selection-start-column="34" selection-end-line="7" selection-end-column="34" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="721" max-vertical-offset="1605">
|
||||
<caret line="25" column="40" selection-start-line="25" selection-start-column="40" selection-end-line="25" selection-end-column="40" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="2370">
|
||||
<caret line="11" column="21" selection-start-line="11" selection-start-column="21" selection-end-line="11" selection-end-column="21" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="1155" max-vertical-offset="1545">
|
||||
<caret line="77" column="9" selection-start-line="77" selection-start-column="9" selection-end-line="77" selection-end-column="9" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="1005" max-vertical-offset="2325">
|
||||
<caret line="104" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="1005" max-vertical-offset="2325">
|
||||
<caret line="104" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="360" max-vertical-offset="1170">
|
||||
<caret line="67" column="33" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="555" max-vertical-offset="2340">
|
||||
<caret line="38" column="24" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/connect/lib/middleware/session/session.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="1020" max-vertical-offset="1830">
|
||||
<caret line="99" column="18" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/index.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="105">
|
||||
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="80" max-vertical-offset="1095">
|
||||
<caret line="31" column="8" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="840" max-vertical-offset="1935">
|
||||
<caret line="81" column="4" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/connect/lib/middleware/session/store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="1350">
|
||||
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/connect/lib/middleware/session.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.2260274" vertical-offset="0" max-vertical-offset="5340">
|
||||
<caret line="16" column="28" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/connect/lib/middleware/session/session.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.6352459" vertical-offset="1020" max-vertical-offset="1830">
|
||||
<caret line="99" column="18" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/index.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="730">
|
||||
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.062586926" vertical-offset="0" max-vertical-offset="1185">
|
||||
<caret line="3" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/package.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="750">
|
||||
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="945" max-vertical-offset="1815">
|
||||
<caret line="47" column="32" selection-start-line="47" selection-start-column="32" selection-end-line="47" selection-end-column="32" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/express-session/index.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.0" vertical-offset="2330" max-vertical-offset="3660">
|
||||
<caret line="167" column="10" selection-start-line="167" selection-start-column="10" selection-end-line="167" selection-end-column="10" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/node_modules/body-parser/index.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.062240664" vertical-offset="75" max-vertical-offset="1590">
|
||||
<caret line="7" column="8" selection-start-line="7" selection-start-column="8" selection-end-line="7" selection-end-column="8" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/test/cluster-store.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state vertical-scroll-proportion="0.12448133" vertical-offset="1920" max-vertical-offset="2415">
|
||||
<caret line="132" column="22" selection-start-line="132" selection-start-column="22" selection-end-line="132" selection-end-column="22" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
||||
|
5
node_modules/strong-cluster-connect-store/.jshintrc
generated
vendored
Normal file
5
node_modules/strong-cluster-connect-store/.jshintrc
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"camelcase": true
|
||||
, "quotmark": "single"
|
||||
, "eqnull": true
|
||||
}
|
18
node_modules/strong-cluster-connect-store/.npmignore
generated
vendored
Normal file
18
node_modules/strong-cluster-connect-store/.npmignore
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
lib-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
*.pid
|
||||
*.gz
|
||||
|
||||
pids
|
||||
logs
|
||||
results
|
||||
|
||||
npm-debug.log
|
||||
|
||||
strong-cluster-connect-store-*.tgz
|
||||
coverage.html
|
||||
node_modules
|
4
node_modules/strong-cluster-connect-store/.travis.yml
generated
vendored
Normal file
4
node_modules/strong-cluster-connect-store/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.11"
|
311
node_modules/strong-cluster-connect-store/LICENSE
generated
vendored
Normal file
311
node_modules/strong-cluster-connect-store/LICENSE
generated
vendored
Normal file
@ -0,0 +1,311 @@
|
||||
Copyright (c) 2013-2014 StrongLoop, Inc.
|
||||
|
||||
strong-cluster-connect-store uses a 'dual license' model. Users may use strong-cluster-connect-store under
|
||||
the terms of the MIT license, or under the StrongLoop License. The text of both
|
||||
is included below.
|
||||
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
StrongLoop License
|
||||
|
||||
STRONGLOOP SUBSCRIPTION AGREEMENT
|
||||
PLEASE READ THIS AGREEMENT CAREFULLY BEFORE YOU AGREE TO THESE TERMS. IF YOU
|
||||
ARE ACTING ON BEHALF OF AN ENTITY, THEN YOU REPRESENT THAT YOU HAVE THE
|
||||
AUTHORITY TO ENTER INTO THIS AGREEMENT ON BEHALF OF THAT ENTITY. IF YOU DO NOT
|
||||
AGREE TO THESE TERMS, YOU SHOULD NOT AGREE TO THE TERMS OF THIS AGREEMENT OR
|
||||
INSTALL OR USE THE SOFTWARE.
|
||||
This StrongLoop Subscription Agreement ("Agreement") is made by and between
|
||||
StrongLoop, Inc. ("StrongLoop") with its principal place of business at 107 S.
|
||||
B St, Suite 220, San Mateo, CA 94401 and the person or entity entering into this
|
||||
Agreement ("Customer"). The effective date ("Effective Date") of this Agreement
|
||||
is the date Customer agrees to these terms or installs or uses the Software (as
|
||||
defined below). This Agreement applies to Customer's use of the Software but it
|
||||
shall be superseded by any signed agreement between you and StrongLoop
|
||||
concerning the Software.
|
||||
1. Subscriptions and Licenses.
|
||||
1.1 Subscriptions. StrongLoop offers five different subscription levels to its
|
||||
customers, each as more particularly described on StrongLoop's website located
|
||||
at www.strongloop.com (the "StrongLoop Site"): (1) Free; (2) Developer; (3)
|
||||
Professional; (4) Gold; and (5) Platinum. The actual subscription level
|
||||
applicable to Customer (the "Subscription") will be specified in the purchase
|
||||
order that Customer issues to StrongLoop. This Agreement applies to Customer
|
||||
regardless of the level of the Subscription selected by Customer and whether or
|
||||
not Customer upgrades or downgrades its Subscription. StrongLoop hereby agrees
|
||||
to provide the services as described on the StrongLoop Site for each
|
||||
Subscription level during the term for which Customer has purchased the
|
||||
applicable Subscription, subject to Customer paying the fees applicable to the
|
||||
Subscription level purchased, if any (the "Subscription Fees"). StrongLoop may
|
||||
modify the services to be provided under any Subscription upon notice to
|
||||
Customer.
|
||||
1.2 License Grant. Subject to the terms and conditions of this Agreement,
|
||||
StrongLoop grants to Customer, during the Subscription Term (as defined in
|
||||
Section 7.1 (Term and Termination) of this Agreement, a limited, non-exclusive,
|
||||
non-transferable right and license, to install and use the StrongLoop Suite
|
||||
software (the "Software") and the documentation made available electronically as
|
||||
part of the Software (the "Documentation"), either of which may be modified
|
||||
during the Term (as defined in Section 7.1 below), solely for development,
|
||||
production and commercial purposes so long as Customer is using the Software to
|
||||
run only one process on a given operating system at a time. This Agreement,
|
||||
including but not limited to the license and restrictions contained herein,
|
||||
apply to Customer regardless of whether Customer accesses the Software via
|
||||
download from the StrongLoop Site or through a third-party website or service,
|
||||
even if Customer acquired the Software prior to agreeing to this Agreement.
|
||||
1.3 License Restrictions. Customer shall not itself, or through any parent,
|
||||
subsidiary, affiliate, agent or other third party:
|
||||
1.3.1 sell, lease, license, distribute, sublicense or otherwise transfer
|
||||
in whole or in part, any Software or the Documentation to a third party;
|
||||
or
|
||||
1.3.2 decompile, disassemble, translate, reverse engineer or otherwise
|
||||
attempt to derive source code from the Software, in whole or in part, nor
|
||||
shall Customer use any mechanical, electronic or other method to trace,
|
||||
decompile, disassemble, or identify the source code of the Software or
|
||||
encourage others to do so, except to the limited extent, if any, that
|
||||
applicable law permits such acts notwithstanding any contractual
|
||||
prohibitions, provided, however, before Customer exercises any rights that
|
||||
Customer believes to be entitled to based on mandatory law, Customer shall
|
||||
provide StrongLoop with thirty (30) days prior written notice and provide
|
||||
all reasonably requested information to allow StrongLoop to assess
|
||||
Customer's claim and, at StrongLoop's sole discretion, to provide
|
||||
alternatives that reduce any adverse impact on StrongLoop's intellectual
|
||||
property or other rights; or
|
||||
1.3.3 allow access or permit use of the Software by any users other than
|
||||
Customer's employees or authorized third-party contractors who are
|
||||
providing services to Customer and agree in writing to abide by the terms
|
||||
of this Agreement, provided further that Customer shall be liable for any
|
||||
failure by such employees and third-party contractors to comply with the
|
||||
terms of this Agreement and no usage restrictions, if any, shall be
|
||||
exceeded; or
|
||||
1.3.4 create, develop, license, install, use, or deploy any third party
|
||||
software or services to circumvent or provide access, permissions or
|
||||
rights which violate the license keys embedded within the Software; or
|
||||
1.3.5 modify or create derivative works based upon the Software or
|
||||
Documentation; or disclose the results of any benchmark test of the
|
||||
Software to any third party without StrongLoop's prior written approval;
|
||||
or
|
||||
1.3.6 change any proprietary rights notices which appear in the Software
|
||||
or Documentation; or
|
||||
1.3.7 use the Software as part of a time sharing or service bureau
|
||||
purposes or in any other resale capacity.
|
||||
1.4 Third-Party Software. The Software may include individual certain software
|
||||
that is owned by third parties, including individual open source software
|
||||
components (the "Third-Party Software"), each of which has its own copyright and
|
||||
its own applicable license conditions. Such third-party software is licensed to
|
||||
Customer under the terms of the applicable third-party licenses and/or copyright
|
||||
notices that can be found in the LICENSES file, the Documentation or other
|
||||
materials accompanying the Software, except that Sections 5 (Warranty
|
||||
Disclaimer) and 6 (Limitation of Liability) also govern Customer's use of the
|
||||
third-party software. Customer agrees to comply with the terms and conditions
|
||||
of the relevant third-party software licenses.
|
||||
2. Support Services. StrongLoop has no obligation to provide any support for
|
||||
the Software other than the support services specifically described on the
|
||||
StrongLoop Site for the Subscription level procured by Customer. However,
|
||||
StrongLoop has endeavored to establish a community of users of the Software who
|
||||
have provided their own feedback, hints and advice regarding their experiences
|
||||
in using the Software. You can find that community and user feedback on the
|
||||
StrongLoop Site. The use of any information, content or other materials from,
|
||||
contained in or on the StrongLoop Site are subject to the StrongLoop website
|
||||
terms of use located here http://www.strongloop.com/terms-of-service.
|
||||
3. Confidentiality. For purposes of this Agreement, "Confidential Information"
|
||||
means any and all information or proprietary materials (in every form and media)
|
||||
not generally known in the relevant trade or industry and which has been or is
|
||||
hereafter disclosed or made available by StrongLoop to Customer in connection
|
||||
with the transactions contemplated under this Agreement, including (i) all trade
|
||||
secrets, (ii) existing or contemplated Software, services, designs, technology,
|
||||
processes, technical data, engineering, techniques, methodologies and concepts
|
||||
and any related information, and (iii) information relating to business plans,
|
||||
sales or marketing methods and customer lists or requirements. For a period of
|
||||
five (5) years from the date of disclosure of the applicable Confidential
|
||||
Information, Customer shall (i) hold the Confidential Information in trust and
|
||||
confidence and avoid the disclosure or release thereof to any other person or
|
||||
entity by using the same degree of care as it uses to avoid unauthorized use,
|
||||
disclosure, or dissemination of its own Confidential Information of a similar
|
||||
nature, but not less than reasonable care, and (ii) not use the Confidential
|
||||
Information for any purpose whatsoever except as expressly contemplated under
|
||||
this Agreement; provided that, to the extent the Confidential Information
|
||||
constitutes a trade secret under law, Customer agrees to protect such
|
||||
information for so long as it qualifies as a trade secret under applicable law.
|
||||
Customer shall disclose the Confidential Information only to those of its
|
||||
employees and contractors having a need to know such Confidential Information
|
||||
and shall take all reasonable precautions to ensure that such employees and
|
||||
contractors comply with the provisions of this Section. The obligations of
|
||||
Customer under this Section shall not apply to information that Customer can
|
||||
demonstrate (i) was in its possession at the time of disclosure and without
|
||||
restriction as to confidentiality, (ii) at the time of disclosure is generally
|
||||
available to the public or after disclosure becomes generally available to the
|
||||
public through no breach of agreement or other wrongful act by Customer, (iii)
|
||||
has been received from a third party without restriction on disclosure and
|
||||
without breach of agreement by Customer, or (iv) is independently developed by
|
||||
Customer without regard to the Confidential Information. In addition, Customer
|
||||
may disclose Confidential Information as required to comply with binding orders
|
||||
of governmental entities that have jurisdiction over it; provided that Customer
|
||||
gives StrongLoop reasonable written notice to allow StrongLoop to seek a
|
||||
protective order or other appropriate remedy, discloses only such Confidential
|
||||
Information as is required by the governmental entity, and uses commercially
|
||||
reasonable efforts to obtain confidential treatment for any Confidential
|
||||
Information disclosed. Notwithstanding the above, Customer agrees that
|
||||
StrongLoop, its employees and agents shall be free to use and employ their
|
||||
general skills, know-how, and expertise, and to use, disclose, and employ any
|
||||
generalized ideas, concepts, know-how, methods, techniques or skills gained or
|
||||
learned during the Term or thereafter.
|
||||
4. Ownership. StrongLoop shall retain all intellectual property and proprietary
|
||||
rights in the Software, Documentation, and related works, including but not
|
||||
limited to any derivative work of the foregoing and StrongLoop's licensors shall
|
||||
retain all intellectual property and proprietary rights in any Third-Party
|
||||
Software that may be provided with or as a part of the Software. Customer shall
|
||||
do nothing inconsistent with StrongLoop's or its licensors' title to the
|
||||
Software and the intellectual property rights embodied therein, including, but
|
||||
not limited to, transferring, loaning, selling, assigning, pledging, or
|
||||
otherwise disposing, encumbering, or suffering a lien or encumbrance upon or
|
||||
against any interest in the Software. The Software (including any Third-Party
|
||||
Software) contain copyrighted material, trade secrets and other proprietary
|
||||
material of StrongLoop and/or its licensors.
|
||||
5. Warranty Disclaimer. THE SOFTWARE (INCLUDING ANY THIRD-PARTY SOFTWARE) AND
|
||||
DOCUMENTATION MADE AVAILABLE TO CUSTOMER ARE PROVIDED "AS-IS" AND STRONGLOOP,
|
||||
ON BEHALF OF ITSELF AND ITS LICENSORS, EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY
|
||||
KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, TITLE,
|
||||
PERFORMANCE, AND ACCURACY AND ANY IMPLIED WARRANTIES ARISING FROM STATUTE,
|
||||
COURSE OF DEALING, COURSE OF PERFORMANCE, OR USAGE OF TRADE. STRONGLOOP DOES
|
||||
NOT WARRANT THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR
|
||||
ERROR-FREE, THAT DEFECTS IN THE SOFTWARE WILL BE CORRECTED OR THAT THE SOFTWARE
|
||||
WILL PROVIDE OR ENSURE ANY PARTICULAR RESULTS OR OUTCOME. NO ORAL OR WRITTEN
|
||||
INFORMATION OR ADVICE GIVEN BY STRONGLOOP OR ITS AUTHORIZED REPRESENTATIVES
|
||||
SHALL CREATE A WARRANTY OR IN ANY WAY INCREASE THE SCOPE OF THIS WARRANTY.
|
||||
STRONGLOOP IS NOT OBLIGATED TO PROVIDE CUSTOMER WITH UPGRADES TO THE SOFTWARE,
|
||||
BUT MAY ELECT TO DO SO IN ITS SOLE DISCRETION. SOME JURISDICTIONS DO NOT ALLOW
|
||||
THE EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT APPLY TO
|
||||
CUSTOMER.WITHOUT LIMITING THE GENERALITY OF THE FOREGOING DISCLAIMER, THE
|
||||
SOFTWARE AND DOCUMENTATION ARE NOT DESIGNED, MANUFACTURED OR INTENDED FOR USE IN
|
||||
THE PLANNING, CONSTRUCTION, MAINTENANCE, CONTROL, OR DIRECT OPERATION OF NUCLEAR
|
||||
FACILITIES, AIRCRAFT NAVIGATION, CONTROL OR COMMUNICATION SYSTEMS, WEAPONS
|
||||
SYSTEMS, OR DIRECT LIFE SUPPORT SYSTEMS.
|
||||
6. Limitation of Liability.
|
||||
6.1 Exclusion of Liability. IN NO EVENT WILL STRONGLOOP OR ITS LICENSORS
|
||||
BE LIABLE UNDER THIS AGREEMENT FOR ANY INDIRECT, RELIANCE, PUNITIVE,
|
||||
CONSEQUENTIAL, SPECIAL, EXEMPLARY, OR INCIDENTAL DAMAGES OF ANY KIND AND
|
||||
HOWEVER CAUSED (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
||||
BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION AND
|
||||
THE LIKE), EVEN IF STRONGLOOP HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES. CUSTOMER BEARS FULL RESPONSIBILITY FOR USE OF THE SOFTWARE AND
|
||||
THE SUBSCRIPTION AND STRONGLOOP DOES NOT GUARANTEE THAT THE USE OF THE
|
||||
SOFTWARE AND SUBSCRIPTION WILL ENSURE THAT CUSTOMER'S NETWORK WILL BE
|
||||
AVAILABLE, SECURE, MONITORED OR PROTECTED AGAINST ANY DOWNTIME, DENIAL OF
|
||||
SERVICE ATTACKS, SECUITY BREACHES, HACKERS AND THE LIKE. IN NO EVENT WILL
|
||||
STRONGLOOP'S CUMULATIVE LIABILITY FOR ANY DAMAGES, LOSSES AND CAUSES OF
|
||||
ACTION (WHETHER IN CONTRACT, TORT, INCLUDING NEGLIGENCE, OR OTHERWISE)
|
||||
ARISING OUT OF OR RELATED TO THIS AGREEMENT EXCEED THE GREATER OF ONE
|
||||
HUNDRED DOLLARS (US$100) OR THE TOTAL SUBSCRIPTION FEES PAID BY CUSTOMER
|
||||
TO STRONGLOOP IN THE TWELVE (12) MONTHS PRECEDING THE DATE THE CLAIM
|
||||
ARISES.
|
||||
6.2 Limitation of Damages. IN NO EVENT WILL STRONGLOOP'S LICENSORS HAVE
|
||||
ANY LIABILITY FOR ANY CLAIM ARISING IN CONNECTION WITH THIS AGREEMENT.
|
||||
THE PROVISIONS OF THIS SECTION 6 ALLOCATE RISKS UNDER THIS AGREEMENT
|
||||
BETWEEN CUSTOMER, STRONGLOOP AND STRONGLOOP'S SUPPLIERS. THE FOREGOING
|
||||
LIMITATIONS, EXCLUSIONS AND DISCLAIMERS APPLY TO THE MAXIMUM EXTENT
|
||||
PERMITTED BY APPLICABLE LAW, EVEN IF ANY REMEDY FAILS IN ITS ESSENTIAL
|
||||
PURPOSE.
|
||||
6.3 Failure of Essential Purpose. THE PARTIES AGREE THAT THESE
|
||||
LIMITATIONS SHALL APPLY EVEN IF THIS AGREEMENT OR ANY LIMITED REMEDY
|
||||
SPECIFIED HEREIN IS FOUND TO HAVE FAILED OF ITS ESSENTIAL PURPOSE.
|
||||
6.4 Allocation of Risk. The sections on limitation of liability and
|
||||
disclaimer of warranties allocate the risks in the Agreement between the
|
||||
parties. This allocation is an essential element of the basis of the
|
||||
bargain between the parties.
|
||||
7. Term and Termination.
|
||||
7.1 This Agreement shall commence on the Effective Date and continue for so long
|
||||
as Customer has a valid Subscription and is current on the payment of any
|
||||
Subscription Fees required to be paid for that Subscription (the "Subscription
|
||||
Term"). Either party may terminate this Agreement immediately upon written
|
||||
notice to the other party, and the Subscription and licenses granted hereunder
|
||||
automatically terminate upon the termination of this Agreement. This Agreement
|
||||
will terminate immediately without notice from StrongLoop if Customer fails to
|
||||
comply with or otherwise breaches any provision of this Agreement.
|
||||
7.2 All Sections other than Section 1.1 (Subscriptions) and 1.2 (Licenses) shall
|
||||
survive the expiration or termination of this Agreement.
|
||||
8. Subscription Fees and Payments. StrongLoop, Customer agrees to pay
|
||||
StrongLoop the Subscription Fees as described on the StrongLoop Site for the
|
||||
Subscription purchased unless a different amount has been agreed to in a
|
||||
separate agreement between Customer and StrongLoop. In addition, Customer shall
|
||||
pay all sales, use, value added, withholding, excise taxes and other tax, duty,
|
||||
custom and similar fees levied upon the delivery or use of the Software and the
|
||||
Subscriptions described in this Agreement. Fees shall be invoiced in full upon
|
||||
StrongLoop's acceptance of Customer's purchase order for the Subscription. All
|
||||
invoices shall be paid in US dollars and are due upon receipt and shall be paid
|
||||
within thirty (30) days. Payments shall be made without right of set-off or
|
||||
chargeback. If Customer does not pay the invoices when due, StrongLoop may
|
||||
charge interest at one percent (1%) per month or the highest rate permitted by
|
||||
law, whichever is lower, on the unpaid balance from the original due date. If
|
||||
Customer fails to pay fees in accordance with this Section, StrongLoop may
|
||||
suspend fulfilling its obligations under this Agreement (including but not
|
||||
limited to suspending the services under the Subscription) until payment is
|
||||
received by StrongLoop. If any applicable law requires Customer to withhold
|
||||
amounts from any payments to StrongLoop under this Agreement, (a) Customer shall
|
||||
effect such withholding, remit such amounts to the appropriate taxing
|
||||
authorities and promptly furnish StrongLoop with tax receipts evidencing the
|
||||
payments of such amounts and (b) the sum payable by Customer upon which the
|
||||
deduction or withholding is based shall be increased to the extent necessary to
|
||||
ensure that, after such deduction or withholding, StrongLoop receives and
|
||||
retains, free from liability for such deduction or withholding, a net amount
|
||||
equal to the amount StrongLoop would have received and retained absent the
|
||||
required deduction or withholding.
|
||||
9. General.
|
||||
9.1 Compliance with Laws. Customer shall abide by all local, state, federal and
|
||||
international laws, rules, regulations and orders applying to Customer's use of
|
||||
the Software, including, without limitation, the laws and regulations of the
|
||||
United States that may restrict the export and re-export of certain commodities
|
||||
and technical data of United States origin, including the Software. Customer
|
||||
agrees that it will not export or re-export the Software without the appropriate
|
||||
United States or foreign government licenses.
|
||||
9.2 Entire Agreement. This Agreement constitutes the entire agreement between
|
||||
the parties concerning the subject matter hereof. This Agreement supersedes all
|
||||
prior or contemporaneous discussions, proposals and agreements between the
|
||||
parties relating to the subject matter hereof. No amendment, modification or
|
||||
waiver of any provision of this Agreement shall be effective unless in writing
|
||||
and signed by both parties. Any additional or different terms on any purchase
|
||||
orders issued by Customer to StrongLoop shall not be binding on either party,
|
||||
are hereby rejected by StrongLoop and void.
|
||||
9.3 Severability. If any provision of this Agreement is held to be invalid or
|
||||
unenforceable, the remaining portions shall remain in full force and effect and
|
||||
such provision shall be enforced to the maximum extent possible so as to effect
|
||||
the intent of the parties and shall be reformed to the extent necessary to make
|
||||
such provision valid and enforceable.
|
||||
9.4 Waiver. No waiver of rights by either party may be implied from any actions
|
||||
or failures to enforce rights under this Agreement.
|
||||
9.5 Force Majeure. Neither party shall be liable to the other for any delay or
|
||||
failure to perform due to causes beyond its reasonable control (excluding
|
||||
payment of monies due).
|
||||
9.6 No Third Party Beneficiaries. Unless otherwise specifically stated, the
|
||||
terms of this Agreement are intended to be and are solely for the benefit of
|
||||
StrongLoop and Customer and do not create any right in favor of any third party.
|
||||
9.7 Governing Law and Jurisdiction. This Agreement shall be governed by the
|
||||
laws of the State of California, without reference to the principles of
|
||||
conflicts of law. The provisions of the Uniform Computerized Information
|
||||
Transaction Act and United Nations Convention on Contracts for the International
|
||||
Sale of Goods shall not apply to this Agreement. The parties shall attempt to
|
||||
resolve any dispute related to this Agreement informally, initially through
|
||||
their respective management, and then by non-binding mediation in San Francisco
|
||||
County, California. Any litigation related to this Agreement shall be brought
|
||||
in the state or federal courts located in San Francisco County, California, and
|
||||
only in those courts and each party irrevocably waives any objections to such
|
||||
venue.
|
||||
9.8 Notices. All notices must be in writing and shall be effective three (3)
|
||||
days after the date sent to the other party's headquarters, Attention Chief
|
||||
Financial Officer.
|
28
node_modules/strong-cluster-connect-store/README.md
generated
vendored
Normal file
28
node_modules/strong-cluster-connect-store/README.md
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
# Connect Session Store for Cluster
|
||||
|
||||
[](https://travis-ci.org/strongloop/strong-cluster-connect-store)
|
||||
[](http://badge.fury.io/js/strong-cluster-connect-store)
|
||||
|
||||
## Overview
|
||||
|
||||
Strong-cluster-connect-store is an implementation of connect session store
|
||||
using node's native cluster messaging. It provides an easy way for using
|
||||
sessions in connect/express based applications running in a node cluster.
|
||||
|
||||
Features:
|
||||
|
||||
- Supports both connect and express.
|
||||
- No dependencies on external services.
|
||||
- Module is shipped without connect, it will use *your* version of connect
|
||||
or express.
|
||||
- Covered by unit-tests.
|
||||
|
||||
## Documentation
|
||||
|
||||
For complete documentation, see [StrongLoop Documentation | Strong Cluster Connect Store](http://docs.strongloop.com/display/DOC/Strong+Cluster+Connect+Store).
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ npm install strong-cluster-connect-store
|
||||
```
|
7
node_modules/strong-cluster-connect-store/docs.json
generated
vendored
Normal file
7
node_modules/strong-cluster-connect-store/docs.json
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"content": [
|
||||
{"title": "Strong Cluster Connect Store API", "depth": 2},
|
||||
"lib/cluster-store.js"
|
||||
],
|
||||
"codeSectionDepth": 3
|
||||
}
|
1
node_modules/strong-cluster-connect-store/index.js
generated
vendored
Normal file
1
node_modules/strong-cluster-connect-store/index.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('./lib/cluster-store.js');
|
115
node_modules/strong-cluster-connect-store/lib/cluster-store.js
generated
vendored
Normal file
115
node_modules/strong-cluster-connect-store/lib/cluster-store.js
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
var inherits = require('util').inherits;
|
||||
var cluster = require('cluster');
|
||||
var NativeStore = require('strong-store-cluster');
|
||||
|
||||
/**
|
||||
* Documentation marker for explicit setup of the shared-state server
|
||||
* in the master process. The initialization happens when this module
|
||||
* is required, thus calling this function is entirely optional.
|
||||
* @private
|
||||
*/
|
||||
function setup() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the `ClusterStore` constructor that can be called to create
|
||||
* a session Store to use with
|
||||
* the [express-session](https://www.npmjs.org/package/express-session)
|
||||
* middleware.
|
||||
*
|
||||
* #### Example
|
||||
* ```
|
||||
// express v3.x
|
||||
var session = express.session;
|
||||
var SessionStore = require('strong-cluster-connect-store')(session);
|
||||
|
||||
// express v4.x
|
||||
var session = require('express-session');
|
||||
var SessionStore = require('strong-cluster-connect-store')(session);
|
||||
|
||||
// express v3.x (backwards compatibility)
|
||||
var SessionStore = require('strong-cluster-connect-store')(express);
|
||||
* ```
|
||||
*
|
||||
* @param {Object} connectOrSession express session or connect/express itself
|
||||
* @return {function} The ClusterStore constructor.
|
||||
*/
|
||||
module.exports = function(connectOrSession) {
|
||||
|
||||
var session = connectOrSession.session || connectOrSession;
|
||||
|
||||
/**
|
||||
* Connect's Store.
|
||||
* @private
|
||||
*/
|
||||
var Store = session.Store;
|
||||
|
||||
var COLLECTION_NAME = 'strong-cluster-connect-session-store';
|
||||
|
||||
/**
|
||||
* Initialize a ClusterStore object with the given `options`.
|
||||
* This is an internal constructor called by express-session middleware,
|
||||
* you should not need to call it directly.
|
||||
* @param {Object} options Options for the ClusterStore object.
|
||||
* @constructor
|
||||
* @extends {session.Store}
|
||||
*/
|
||||
function ClusterStore(options) {
|
||||
Store.call(this, options);
|
||||
this._collection = NativeStore.collection(COLLECTION_NAME);
|
||||
}
|
||||
|
||||
inherits(ClusterStore, Store);
|
||||
|
||||
/**
|
||||
* Fetch a session by an id and receive the session in the callback.
|
||||
* @param {String} sid A string id for the session.
|
||||
* @end
|
||||
* @callback {Function} fn
|
||||
* @param {Error} err if present, indicates an error condition.
|
||||
* @param value The data stored in the collection, could be any type.
|
||||
* @end
|
||||
*/
|
||||
ClusterStore.prototype.get = function(sid, fn) {
|
||||
this._collection.get(sid, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Commit the given `session` object associated with the given `sid` to the
|
||||
* session store.
|
||||
* @param {String} sid A string id identifying the session.
|
||||
* @param {Object} session The session object.
|
||||
* @end
|
||||
* @callback {Function} fn
|
||||
* @param {Error} err If defined, indicates an error occured.
|
||||
* @end
|
||||
*/
|
||||
ClusterStore.prototype.set = function(sid, session, fn) {
|
||||
this._collection.set(sid, session, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy the session associated with the given `sid`.
|
||||
* @param {String} sid A String with the id of the session.
|
||||
* @end
|
||||
* @callback {Function} fn
|
||||
* @param {Error} err If defined, indicates an error occured.
|
||||
* @end
|
||||
*
|
||||
*/
|
||||
ClusterStore.prototype.destroy = function(sid, fn){
|
||||
this._collection.del(sid, fn);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Same as `setup()` (see above).
|
||||
* @private
|
||||
*/
|
||||
ClusterStore.setup = setup;
|
||||
|
||||
return ClusterStore;
|
||||
};
|
||||
|
||||
module.exports.setup = setup;
|
55
node_modules/strong-cluster-connect-store/package.json
generated
vendored
Normal file
55
node_modules/strong-cluster-connect-store/package.json
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "strong-cluster-connect-store",
|
||||
"version": "1.0.0",
|
||||
"description": "Implementation of connect session store using node's native cluster messaging",
|
||||
"license": {
|
||||
"name": "Dual MIT/StrongLoop",
|
||||
"url": "https://github.com/strongloop/strong-cluster-connect-store/blob/master/LICENSE"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "mocha --reporter spec",
|
||||
"lint": "./node_modules/.bin/jshint *.js test lib"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/strongloop/strong-cluster-connect-store.git"
|
||||
},
|
||||
"keywords": [
|
||||
"connect",
|
||||
"express",
|
||||
"cluster",
|
||||
"session",
|
||||
"store"
|
||||
],
|
||||
"author": {
|
||||
"name": "Miroslav Bajtos",
|
||||
"email": "miroslav@strongloop.com"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"strong-store-cluster": "~0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "~1.9.0",
|
||||
"jshint": "~2.0.1",
|
||||
"chai": "~1.7.2",
|
||||
"cookie-parser": "^1.0.1",
|
||||
"strong-store-cluster": "latest",
|
||||
"request": "~2.22.0",
|
||||
"async": "~0.2.9",
|
||||
"express-session": "^1.0.2",
|
||||
"express": "^4.1.1",
|
||||
"body-parser": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"readme": "# Connect Session Store for Cluster\n\n[](https://travis-ci.org/strongloop/strong-cluster-connect-store)\n[](http://badge.fury.io/js/strong-cluster-connect-store)\n\n## Overview\n\nStrong-cluster-connect-store is an implementation of connect session store\nusing node's native cluster messaging. It provides an easy way for using\nsessions in connect/express based applications running in a node cluster.\n\nFeatures:\n\n- Supports both connect and express.\n- No dependencies on external services.\n- Module is shipped without connect, it will use *your* version of connect\n or express.\n- Covered by unit-tests.\n \n## Documentation\n\nFor complete documentation, see [StrongLoop Documentation | Strong Cluster Connect Store](http://docs.strongloop.com/display/DOC/Strong+Cluster+Connect+Store).\n\n## Installation\n\n```sh\n$ npm install strong-cluster-connect-store\n```\n",
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "strong-cluster-connect-store@1.0.0",
|
||||
"dist": {
|
||||
"shasum": "c1ee462f23b1dee4d6381fe986d83a227c32c62e"
|
||||
},
|
||||
"_from": "strong-cluster-connect-store@",
|
||||
"_resolved": "https://registry.npmjs.org/strong-cluster-connect-store/-/strong-cluster-connect-store-1.0.0.tgz"
|
||||
}
|
155
node_modules/strong-cluster-connect-store/test/cluster-store.js
generated
vendored
Normal file
155
node_modules/strong-cluster-connect-store/test/cluster-store.js
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
var cluster = require('cluster');
|
||||
var http = require('http');
|
||||
var expect = require('chai').expect;
|
||||
var express = require('express');
|
||||
var bodyParser = require('body-parser');
|
||||
var cookieParser = require('cookie-parser');
|
||||
var session = require('express-session');
|
||||
var request = require('request');
|
||||
var async = require('async');
|
||||
var ClusterStore = require('..')(session);
|
||||
|
||||
var workerUrl;
|
||||
|
||||
// verify we can call setup without connect in master and workers
|
||||
require('..').setup();
|
||||
|
||||
if (cluster.isWorker) {
|
||||
startConnectServer();
|
||||
return;
|
||||
}
|
||||
|
||||
describe('clustered connect server', function() {
|
||||
before(setupWorkers);
|
||||
after(stopWorkers);
|
||||
|
||||
var KEY = 'a-key';
|
||||
var PAYLOAD = 'a-value';
|
||||
|
||||
// NOTE We assume that the cluster does a perfect round-robin
|
||||
// distribution of requests among the workers
|
||||
|
||||
it('shares sessions between workers', function(done) {
|
||||
async.series(
|
||||
[
|
||||
save,
|
||||
load
|
||||
],
|
||||
function(err, results) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
expect(results.pop().value).to.equal(PAYLOAD);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('destroys a session shared between workers', function(done) {
|
||||
async.series(
|
||||
[
|
||||
save,
|
||||
destroy,
|
||||
load
|
||||
],
|
||||
function(err, results) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
expect(results.pop().value).to.equal(undefined);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function save(next) {
|
||||
sendCommand({ cmd: 'set', key: KEY, value: PAYLOAD }, next);
|
||||
}
|
||||
|
||||
function destroy(next) {
|
||||
sendCommand({ cmd: 'del', key: KEY }, next);
|
||||
}
|
||||
|
||||
function load(next) {
|
||||
sendCommand({ cmd: 'get', key: KEY }, next);
|
||||
}
|
||||
});
|
||||
|
||||
function sendCommand(command, cb) {
|
||||
request(
|
||||
{
|
||||
url: workerUrl,
|
||||
method: 'POST',
|
||||
json: command
|
||||
},
|
||||
function(err, res, body) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
cb(null, body);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
var WORKER_COUNT = 2;
|
||||
|
||||
function getNumberOfWorkers() {
|
||||
return Object.keys(cluster.workers).length;
|
||||
}
|
||||
|
||||
function setupWorkers(done) {
|
||||
if (getNumberOfWorkers() > 0) {
|
||||
var msg = 'Cannot setup workers: there are already other workers running.';
|
||||
return done(new Error(msg));
|
||||
}
|
||||
|
||||
cluster.setupMaster({ exec: __filename });
|
||||
ClusterStore.setup();
|
||||
|
||||
var workersListening = 0;
|
||||
cluster.on('listening', function(w, addr) {
|
||||
if (!workerUrl) workerUrl = 'http://localhost:' + addr.port;
|
||||
|
||||
workersListening++;
|
||||
if (workersListening == WORKER_COUNT) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
for (var i = 0; i < WORKER_COUNT; i++) {
|
||||
cluster.fork();
|
||||
}
|
||||
}
|
||||
|
||||
function stopWorkers(done) {
|
||||
cluster.disconnect(done);
|
||||
}
|
||||
|
||||
function startConnectServer() {
|
||||
var PORT = 0; // Let the OS pick any available port
|
||||
var app = express()
|
||||
.use(cookieParser())
|
||||
.use(session({ store: new ClusterStore(), secret: 'a-secret', key: 'sid' }))
|
||||
.use(bodyParser.json())
|
||||
.use(requestHandler);
|
||||
|
||||
var server = http.createServer(app).listen(PORT);
|
||||
|
||||
function requestHandler(req, res) {
|
||||
var result = {};
|
||||
switch (req.body.cmd) {
|
||||
case 'set':
|
||||
req.session[req.body.key] = req.body.value;
|
||||
break;
|
||||
case 'get':
|
||||
result.value = req.session[req.body.key];
|
||||
break;
|
||||
case 'del':
|
||||
req.session.destroy();
|
||||
break;
|
||||
}
|
||||
|
||||
res.setHeader('Content-Type', 'text/json');
|
||||
res.end(JSON.stringify(result));
|
||||
}
|
||||
}
|
2
node_modules/strong-store-cluster/BUG.txt
generated
vendored
Normal file
2
node_modules/strong-store-cluster/BUG.txt
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
A new Client() is created for each 'online' worker... but clients are never
|
||||
released.
|
19
node_modules/strong-store-cluster/LICENSE
generated
vendored
Normal file
19
node_modules/strong-store-cluster/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013 Strongloop, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
19
node_modules/strong-store-cluster/Makefile
generated
vendored
Normal file
19
node_modules/strong-store-cluster/Makefile
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# Makefile
|
||||
|
||||
-include local.mk
|
||||
|
||||
.PHONY: test default
|
||||
|
||||
default: test
|
||||
|
||||
test:
|
||||
@npm test
|
||||
|
||||
jenkins-build: jenkins-install jenkins-test
|
||||
|
||||
jenkins-install:
|
||||
npm install
|
||||
|
||||
jenkins-test:
|
||||
./node_modules/.bin/mocha --timeout 5000 --slow 1000 --ui tdd --reporter xunit > xunit.xml
|
||||
|
189
node_modules/strong-store-cluster/README.md
generated
vendored
Normal file
189
node_modules/strong-store-cluster/README.md
generated
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
# Strong Store Cluster
|
||||
|
||||
Strong Store for Cluster provides a key/value collection that can be accesses by
|
||||
all processes in a node cluster.
|
||||
|
||||
## Example
|
||||
|
||||
```javascript
|
||||
// get the collection and give it a name
|
||||
var collection = require('strong-store-cluster').collection('test');
|
||||
|
||||
// don't let keys expire, ever - the number represents seconds
|
||||
collection.configure({ expireKeys: 0 });
|
||||
|
||||
collection.set('ThisIsMyKey', { a: 0, b: 'Hiya', c: { d: 99}}, function(err) {
|
||||
if (err) {
|
||||
console.error('There was an error');
|
||||
return;
|
||||
}
|
||||
|
||||
collection.get('ThisIsMyKey', function(err, obj) {
|
||||
if (err) {
|
||||
console.error('There was an error in collection.get.');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('The object: ',obj);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## API documentation
|
||||
|
||||
### store.collection(name)
|
||||
|
||||
Returns a Collection object which lets you share data between node processes.
|
||||
|
||||
### Class: Collection
|
||||
|
||||
A `Collection` instance provides access to a shared key-value store
|
||||
shared by multiple node instances.
|
||||
|
||||
How collections are named and stored is determined by the storage backend. The
|
||||
`strong-store-cluster` implementation stores collections in the master process
|
||||
(if you're using cluster), and accepts any arbitrary string as a collection
|
||||
name.
|
||||
|
||||
A `Collection` object is also an `EventEmitter`.
|
||||
|
||||
|
||||
#### collection.configure([options])
|
||||
|
||||
* `options` (`Object`) contains configurations options to be changed
|
||||
* `expireKeys` (`Number`) seconds after which keys in this
|
||||
collection are to be expired.
|
||||
|
||||
Set configuration options for the collection.
|
||||
|
||||
Currently only one configurable option is supported: `expireKeys`. When set
|
||||
to a nonzero value, keys will automatically expire after they've not been
|
||||
read or updated for some time. The timeout is specified in seconds. There's no
|
||||
guarantee that the key will be discared after exactly that number of seconds
|
||||
has passed. However keys will never be automatically deleted _sooner_ than what
|
||||
the `expireKeys` setting allows.
|
||||
|
||||
It is perfectly legal to call the `configure` method from multiple node
|
||||
processes (e.g. both in a worker and in the master process). However you
|
||||
should be careful to set the _same_ option values every time, otherwise the
|
||||
effect is undefined.
|
||||
|
||||
|
||||
#### collection.get(key, callback)
|
||||
|
||||
* `key` (`String`) key to retrieve
|
||||
* `callback` (`Function`) called when the value has been retrieved
|
||||
|
||||
Read the value associated with a particular key. The callback is called with
|
||||
two arguments, `(err, value)`. When the key wasn't found in the collection, it
|
||||
is automatically created and it's `value` is set to `undefined`.
|
||||
|
||||
|
||||
#### collection.set(key, [value], [callback])
|
||||
|
||||
* `key` (`String`) key to set or update
|
||||
* `value` (`object`) value to associate with the key
|
||||
* `callback` (`Function`) called when the value has been retrieved
|
||||
|
||||
Set the value associated with `key`. The `value` must be either undefined or
|
||||
a value that can be serialized with JSON.stringify.
|
||||
|
||||
When the `value` parameter is omitted or set to `undefined`, the key is
|
||||
deleted, so effectively it's the same as calling `collection.del(key)`.
|
||||
|
||||
The `callback` function receives only one argument, `err`. When the
|
||||
callback is omitted, the master process does not send a confirmation
|
||||
after updating the key, and any errors are silently ignored.
|
||||
|
||||
|
||||
#### collection.del(key, [callback])
|
||||
|
||||
* `key` (`String`) key to delete
|
||||
* `callback` (`Function`) called when the value has been retrieved
|
||||
|
||||
Delete a key from the collection.
|
||||
|
||||
This operation is the equivalent of setting the key to `undefined`.
|
||||
|
||||
The `callback` function receives only one argument, `err`. When the
|
||||
callback is omitted, the master process does not send a confirmation
|
||||
after deleting the key, and any errors are silently ignored.
|
||||
|
||||
|
||||
#### collection.acquire(key, callback)
|
||||
|
||||
* `key` (`String`) key to delete
|
||||
* `callback` (`Function`) called when the key has been locked
|
||||
|
||||
Lock a key for exclusive read and write access.
|
||||
|
||||
The `acquire` methods waits until it can grab an exclusive lock on the
|
||||
specified key. When the lock is acquired, no other process can read, write or
|
||||
delete this particular key. When the lock is no longer needed, it should be
|
||||
relinquished with `keylock.release()`.
|
||||
|
||||
Three parameters are passed to the `callback` function:
|
||||
`(err, keylock, value)`. The `keylock` argument receives a `KeyLock` class
|
||||
instance, which lets you read and manipulate the key's value as well as
|
||||
eventually release the lock. The `value` argument is set to the initial value
|
||||
associated with the key.
|
||||
|
||||
|
||||
#### Event: 'error'
|
||||
|
||||
* `err` (`Error`)
|
||||
|
||||
The error event is emitted whenever an unrecoverable error is encountered.
|
||||
|
||||
### Class: KeyLock
|
||||
|
||||
A `KeyLock` instance represents a key that has been locked. The `KeyLock`
|
||||
class implements methods that lets you manipulate the key and release
|
||||
the lock.
|
||||
|
||||
|
||||
#### keylock.get()
|
||||
|
||||
* Returns: (`Object`) value that's currently associated with the key
|
||||
|
||||
This function returns the value that's currently associated with the locked
|
||||
key.
|
||||
|
||||
Initially this is the same as the `value` argument that was passed to the
|
||||
`collection.acquire()` callback, but it does immediately reflect changes that
|
||||
are made with `keylock.set()` and `keylock.del()`.
|
||||
|
||||
|
||||
#### keylock.set([value])
|
||||
|
||||
Updates the value associated with a locked key.
|
||||
|
||||
The change isn't pushed back to the master process immediately; the change
|
||||
is committed when the lock is released again. The change however is reflected
|
||||
immediately in the return value from `keylock.get()`.
|
||||
|
||||
After the lock has been released, the key can no longer be updated through the
|
||||
`KeyLock` instance. Any attempt to do so will make it throw.
|
||||
|
||||
Setting the value to `undefined` marks the key for deletion, e.g. it's
|
||||
equivalent to `keylock.del()`.
|
||||
|
||||
|
||||
#### keylock.del()
|
||||
|
||||
Mark a locked key for deletion. See `keylock.set()`.
|
||||
|
||||
|
||||
#### keylock.release([callback])
|
||||
|
||||
Release the lock that protects a key. If the key was updated with
|
||||
`keylock.set()` or `keylock.del()`, these changes are committed.
|
||||
|
||||
When a lock has been released, it is no longer possible to manipulate the
|
||||
key using `KeyLock` methods. Releasing the lock twice isn't allowed either.
|
||||
The `get()` method will still work but it won't reflect any value changes
|
||||
that were made after releasing.
|
||||
|
||||
The `callback` function receives only one argument, `err`. When the
|
||||
callback is omitted, the master process does not send a confirmation
|
||||
after releasing the key, and any errors are silently ignored.
|
6
node_modules/strong-store-cluster/docs.json
generated
vendored
Normal file
6
node_modules/strong-store-cluster/docs.json
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"title": "Strong Store for Cluster",
|
||||
"content": [
|
||||
"README.md"
|
||||
]
|
||||
}
|
18
node_modules/strong-store-cluster/index.js
generated
vendored
Normal file
18
node_modules/strong-store-cluster/index.js
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
var VERSION = require('./package.json').version;
|
||||
|
||||
if(cluster._strongStoreCluster) {
|
||||
assert(
|
||||
cluster._strongStoreCluster.VERSION === VERSION,
|
||||
'Multiple versions of strong-strore-cluster are being initialized.\n' +
|
||||
'This version ' + VERSION + ' is incompatible with already initialized\n' +
|
||||
'version ' + cluster._strongStoreCluster.VERSION + '.\n'
|
||||
);
|
||||
module.exports = cluster._strongStoreCluster;
|
||||
return;
|
||||
}
|
||||
|
||||
module.exports = require('./lib/lib.js');
|
||||
module.exports.VERSION = VERSION;
|
||||
cluster._strongStoreCluster = module.exports;
|
22
node_modules/strong-store-cluster/lib/collection.js
generated
vendored
Normal file
22
node_modules/strong-store-cluster/lib/collection.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
module.exports = collection;
|
||||
|
||||
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
var cluster = require('cluster');
|
||||
|
||||
if (cluster.isMaster)
|
||||
var Collection = require('./master/Collection.js');
|
||||
else
|
||||
var Collection = require('./worker/Collection.js');
|
||||
|
||||
|
||||
var collections = {};
|
||||
|
||||
function collection(name) {
|
||||
if (!hasOwnProperty.call(collections, name))
|
||||
return collections[name] = new Collection(name);
|
||||
else
|
||||
return collections[name];
|
||||
}
|
8
node_modules/strong-store-cluster/lib/lib.js
generated
vendored
Normal file
8
node_modules/strong-store-cluster/lib/lib.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
var cluster = require('cluster'),
|
||||
collection = require('./collection.js');
|
||||
|
||||
exports.collection = collection;
|
||||
|
||||
if (cluster.isMaster)
|
||||
require('./master/setup.js');
|
107
node_modules/strong-store-cluster/lib/master/Client.js
generated
vendored
Normal file
107
node_modules/strong-store-cluster/lib/master/Client.js
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
|
||||
|
||||
module.exports = Client;
|
||||
|
||||
|
||||
var collection = require('../collection.js');
|
||||
|
||||
|
||||
function Client(worker) {
|
||||
this._worker = worker;
|
||||
this._id = worker.id;
|
||||
this._locks = {};
|
||||
|
||||
this._onMessage = this.onMessage.bind(this);
|
||||
|
||||
worker.on('message', this._onMessage);
|
||||
}
|
||||
|
||||
Client.prototype.onMessage = function(msg) {
|
||||
if (msg.type === 'DSM_REQUEST')
|
||||
this[msg.method](msg);
|
||||
};
|
||||
|
||||
Client.prototype.get = function(msg) {
|
||||
var self = this,
|
||||
entry = collection(msg.collection)._entry(msg.key);
|
||||
|
||||
entry.get(this._id, function(err, json) {
|
||||
if (err) self._sendError(msg, err);
|
||||
else self._sendReply(msg, { json: json });
|
||||
});
|
||||
};
|
||||
|
||||
Client.prototype.set = function(msg) {
|
||||
var self = this,
|
||||
entry = collection(msg.collection)._entry(msg.key);
|
||||
|
||||
entry.set(msg.json, this._id, function(err) {
|
||||
if (err) self._sendError(msg, err);
|
||||
else self._sendReply(msg);
|
||||
});
|
||||
};
|
||||
|
||||
Client.prototype.acquire = function(msg) {
|
||||
var self = this,
|
||||
entry = collection(msg.collection)._entry(msg.key);
|
||||
|
||||
entry.acquire(this._id, function(err, json) {
|
||||
if (err) self._sendError(msg, err);
|
||||
else self._sendReply(msg, { json: json });
|
||||
});
|
||||
};
|
||||
|
||||
Client.prototype.release = function(msg) {
|
||||
var self = this,
|
||||
entry = collection(msg.collection)._entry(msg.key);
|
||||
|
||||
entry.release(this._id, function(err, json) {
|
||||
if (err) self._sendError(msg, err);
|
||||
else self._sendReply(msg);
|
||||
});
|
||||
};
|
||||
|
||||
Client.prototype.setRelease = function(msg) {
|
||||
var self = this,
|
||||
entry = collection(msg.collection)._entry(msg.key);
|
||||
|
||||
entry.setRelease(msg.json, this._id, function(err) {
|
||||
if (err) self._sendError(msg, err);
|
||||
else self._sendReply(msg);
|
||||
});
|
||||
};
|
||||
|
||||
Client.prototype.configure = function(msg) {
|
||||
var coll = collection(msg.collection),
|
||||
err = undefined;
|
||||
|
||||
try {
|
||||
coll._applyConfig(msg.config);
|
||||
this._sendReply(msg);
|
||||
} catch (err) {
|
||||
this._sendError(msg, err);
|
||||
}
|
||||
};
|
||||
|
||||
// This function clobbers the data argument if specified!
|
||||
Client.prototype._sendReply = function(msg, data) {
|
||||
if (!msg.requestId)
|
||||
return;
|
||||
|
||||
data = data || {};
|
||||
data.type = 'DSM_REPLY';
|
||||
data.requestId = msg.requestId;
|
||||
data.err = undefined;
|
||||
this._worker.send(data);
|
||||
};
|
||||
|
||||
Client.prototype._sendError = function(msg, err) {
|
||||
if (!msg.requestId)
|
||||
return;
|
||||
|
||||
var data = {};
|
||||
data.type = 'DSM_REPLY';
|
||||
data.requestId = msg.requestId;
|
||||
data.err = err;
|
||||
this._worker.send(data);
|
||||
};
|
153
node_modules/strong-store-cluster/lib/master/Collection.js
generated
vendored
Normal file
153
node_modules/strong-store-cluster/lib/master/Collection.js
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
|
||||
module.exports = Collection;
|
||||
|
||||
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
var assert = require('assert'),
|
||||
inherits = require('util').inherits,
|
||||
EventEmitter = require('events').EventEmitter;
|
||||
|
||||
var Entry = require('./Entry.js'),
|
||||
KeyLock = require('./KeyLock.js');
|
||||
|
||||
|
||||
function Collection(name) {
|
||||
this._name = name;
|
||||
this._entries = {};
|
||||
this._count = 0;
|
||||
this._expireKeys = null;
|
||||
this._expireKeysTimer = null;
|
||||
|
||||
this._sweep = this._sweep.bind(this);
|
||||
}
|
||||
|
||||
inherits(Collection, EventEmitter);
|
||||
|
||||
Collection.prototype._entry = function(key) {
|
||||
if (!hasOwnProperty.call(this._entries, key)) {
|
||||
if (!this._count++ && this._expireKeys)
|
||||
this._startExpireKeysTimer();
|
||||
|
||||
return this._entries[key] = new Entry(this, key);
|
||||
} else {
|
||||
return this._entries[key];
|
||||
}
|
||||
};
|
||||
|
||||
Collection.prototype._remove = function(key) {
|
||||
assert(hasOwnProperty.call(this._entries, key));
|
||||
delete this._entries[key];
|
||||
|
||||
if (!--this._count && this.expireKeys)
|
||||
this._stopExpireKeysTimer();
|
||||
};
|
||||
|
||||
Collection.prototype.get = function(key, cb) {
|
||||
this._entry(key).get(-1, function(err, json) {
|
||||
if (err)
|
||||
cb(err);
|
||||
else if (!json)
|
||||
cb(null, undefined);
|
||||
else
|
||||
cb(null, JSON.parse(json));
|
||||
});
|
||||
};
|
||||
|
||||
Collection.prototype.set = function(key, value, cb) {
|
||||
cb = cb || noop;
|
||||
this._entry(key).set(JSON.stringify(value), -1, cb);
|
||||
};
|
||||
|
||||
Collection.prototype.del = function(key, cb) {
|
||||
cb = cb || noop;
|
||||
this._entry(key).set(undefined, -1, cb);
|
||||
};
|
||||
|
||||
Collection.prototype.acquire = function(key, cb) {
|
||||
var self = this,
|
||||
entry = this._entry(key);
|
||||
|
||||
entry.acquire(-1, function(err, json) {
|
||||
var lock = new KeyLock(entry, json);
|
||||
return cb(null, lock, lock.get());
|
||||
});
|
||||
};
|
||||
|
||||
Collection.prototype._applyConfig = function(config) {
|
||||
config = config || {};
|
||||
|
||||
for (var key in config) {
|
||||
if (!hasOwnProperty.call(config, key))
|
||||
continue;
|
||||
|
||||
switch (key) {
|
||||
case 'expireKeys':
|
||||
if (config.expireKeys === this._expireKeys)
|
||||
break;
|
||||
|
||||
this._stopExpireKeysTimer();
|
||||
this._expireKeys = config.expireKeys;
|
||||
this._startExpireKeysTimer();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error('Unspported configuration option: ' + key);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Collection.prototype._startExpireKeysTimer = function() {
|
||||
assert(!this._expireKeysTimer);
|
||||
|
||||
if (!this._expireKeys || !this._count)
|
||||
return;
|
||||
|
||||
var interval = Math.ceil(this._expireKeys * 1000 / 2);
|
||||
|
||||
this._expireKeysTimer = setInterval(this._sweep, interval);
|
||||
this._expireKeysTimer.unref();
|
||||
};
|
||||
|
||||
Collection.prototype._stopExpireKeysTimer = function() {
|
||||
if (!this._expireKeysTimer)
|
||||
return;
|
||||
|
||||
clearInterval(this._expireKeysTimer);
|
||||
this._expireKeysTimer = null;
|
||||
};
|
||||
|
||||
Collection.prototype._sweep = function() {
|
||||
var entries = this._entries,
|
||||
key;
|
||||
|
||||
for (key in entries) {
|
||||
if (!hasOwnProperty.call(entries, key))
|
||||
continue;
|
||||
|
||||
if (entries[key].age(1) > 2)
|
||||
this._remove(key);
|
||||
}
|
||||
|
||||
if (!this._count)
|
||||
this._stopExpireKeysTimer();
|
||||
};
|
||||
|
||||
Collection.prototype.configure = function(config) {
|
||||
var self = this;
|
||||
|
||||
try {
|
||||
this._applyConfig(config);
|
||||
|
||||
} catch (err) {
|
||||
process.nextTick(function() {
|
||||
self.emit('error', err);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
function noop() {
|
||||
}
|
103
node_modules/strong-store-cluster/lib/master/Entry.js
generated
vendored
Normal file
103
node_modules/strong-store-cluster/lib/master/Entry.js
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
|
||||
module.exports = Entry;
|
||||
|
||||
|
||||
var assert = require('assert');
|
||||
|
||||
|
||||
function Entry(collection, key) {
|
||||
this._collection = collection;
|
||||
this._key = key;
|
||||
this._value = undefined;
|
||||
this._queue = [];
|
||||
this._age = 0;
|
||||
}
|
||||
|
||||
Entry.prototype.get = function(requestor, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!this._queue.length) {
|
||||
var value = self._value;
|
||||
self._age = 0;
|
||||
|
||||
process.nextTick(function() {
|
||||
cb(null, value);
|
||||
});
|
||||
|
||||
} else {
|
||||
this.acquire(requestor, function(err) {
|
||||
self.release(requestor, noop);
|
||||
cb(null, self._value);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Entry.prototype.set = function(newValue, requestor, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!this._queue.length) {
|
||||
this._value = newValue;
|
||||
this._age = 0;
|
||||
|
||||
if (newValue === undefined)
|
||||
this._collection._remove(this._key);
|
||||
|
||||
process.nextTick(cb);
|
||||
|
||||
} else {
|
||||
this.acquire(requestor, function() {
|
||||
self._value = newValue;
|
||||
|
||||
if (newValue !== undefined)
|
||||
self.release(requestor, cb);
|
||||
else {
|
||||
self._collection._remove(self._key);
|
||||
cb();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Entry.prototype.acquire = function(requestor, cb) {
|
||||
var self = this;
|
||||
|
||||
this._queue.push([cb, requestor]);
|
||||
|
||||
if (this._queue.length === 1) {
|
||||
process.nextTick(function() {
|
||||
cb(null, self._value);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Entry.prototype.release = function(requestor, cb) {
|
||||
var self = this,
|
||||
queue = this._queue;
|
||||
|
||||
setImmediate(function() {
|
||||
assert.strictEqual(requestor, queue.shift()[1]);
|
||||
|
||||
self._age = 0;
|
||||
cb();
|
||||
|
||||
if (queue.length)
|
||||
queue[0][0](null, self._value);
|
||||
});
|
||||
};
|
||||
|
||||
Entry.prototype.setRelease = function(newValue, requestor, cb) {
|
||||
this._value = newValue;
|
||||
this.release(requestor, cb);
|
||||
};
|
||||
|
||||
|
||||
Entry.prototype.age = function(d) {
|
||||
if (this._queue.length)
|
||||
return this._age = 0;
|
||||
else
|
||||
return this._age += (d || 0);
|
||||
};
|
||||
|
||||
|
||||
function noop() {
|
||||
}
|
51
node_modules/strong-store-cluster/lib/master/KeyLock.js
generated
vendored
Normal file
51
node_modules/strong-store-cluster/lib/master/KeyLock.js
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
|
||||
module.exports = KeyLock;
|
||||
|
||||
|
||||
function KeyLock(entry, json) {
|
||||
this._entry = entry;
|
||||
this._json = json;
|
||||
this._updated = false;
|
||||
this._released = false;
|
||||
}
|
||||
|
||||
KeyLock.prototype.get = function() {
|
||||
if (!this._json)
|
||||
return undefined;
|
||||
else
|
||||
return JSON.parse(this._json);
|
||||
};
|
||||
|
||||
KeyLock.prototype.set = function(newValue) {
|
||||
if (this._released)
|
||||
throw new Error("Can't set after releasing a lock.");
|
||||
|
||||
this._json = JSON.stringify(newValue);
|
||||
this._updated = true;
|
||||
};
|
||||
|
||||
KeyLock.prototype.del = function() {
|
||||
if (this._released)
|
||||
throw new Error("Can't delete after releasing a lock.");
|
||||
|
||||
this._json = undefined;
|
||||
this._updated = true;
|
||||
};
|
||||
|
||||
KeyLock.prototype.release = function(cb) {
|
||||
if (this._released)
|
||||
throw new Error('KeyLock has already been released.');
|
||||
|
||||
cb = cb || noop;
|
||||
this._released = true;
|
||||
|
||||
if (!this._updated)
|
||||
this._entry.release(-1, cb);
|
||||
else
|
||||
this._entry.setRelease(this._json, -1, cb);
|
||||
};
|
||||
|
||||
|
||||
function noop() {
|
||||
}
|
10
node_modules/strong-store-cluster/lib/master/setup.js
generated
vendored
Normal file
10
node_modules/strong-store-cluster/lib/master/setup.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
var cluster = require('cluster'),
|
||||
Client = require('./Client.js');
|
||||
|
||||
for (var i = 0; i < cluster.workers.length; i++)
|
||||
new Client(cluster.workers[i]);
|
||||
|
||||
cluster.on('online', function(worker) {
|
||||
new Client(worker);
|
||||
});
|
68
node_modules/strong-store-cluster/lib/worker/Collection.js
generated
vendored
Normal file
68
node_modules/strong-store-cluster/lib/worker/Collection.js
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
module.exports = Collection;
|
||||
|
||||
|
||||
var inherits = require('util').inherits,
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
KeyLock = require('./KeyLock.js'),
|
||||
request = require('./request.js');
|
||||
|
||||
|
||||
function Collection(name) {
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
inherits(Collection, EventEmitter);
|
||||
|
||||
Collection.prototype.get = function(key, cb) {
|
||||
this._request('get', key, null, function(err, msg) {
|
||||
if (err)
|
||||
return cb(err);
|
||||
else if (!msg.json)
|
||||
return cb(null, undefined);
|
||||
else
|
||||
return cb(null, JSON.parse(msg.json));
|
||||
});
|
||||
};
|
||||
|
||||
Collection.prototype.set = function(key, value, cb) {
|
||||
var data = { json: JSON.stringify(value) };
|
||||
this._request('set', key, data, cb && function(err, msg) {
|
||||
return cb(err);
|
||||
});
|
||||
};
|
||||
|
||||
Collection.prototype.del = function(key, cb) {
|
||||
return this._request('set', key, null, cb && function(err, msg) {
|
||||
return cb(err);
|
||||
});
|
||||
};
|
||||
|
||||
Collection.prototype.acquire = function(key, cb) {
|
||||
var self = this;
|
||||
|
||||
this._request('acquire', key, null, function(err, msg) {
|
||||
if (err)
|
||||
return cb(err);
|
||||
|
||||
var json = msg.json;
|
||||
var lock = new KeyLock(self, key, json);
|
||||
cb(null, lock, lock.get());
|
||||
});
|
||||
};
|
||||
|
||||
Collection.prototype.configure = function(config) {
|
||||
var self = this;
|
||||
|
||||
this._request('configure', null, { config: config }, function(err, msg) {
|
||||
if (err)
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// This function clobbers `data` if specified
|
||||
Collection.prototype._request = function(method, key, data, cb) {
|
||||
request(method, this._name, key, data, cb);
|
||||
};
|
56
node_modules/strong-store-cluster/lib/worker/KeyLock.js
generated
vendored
Normal file
56
node_modules/strong-store-cluster/lib/worker/KeyLock.js
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
module.exports = KeyLock;
|
||||
|
||||
|
||||
var request = require('./request.js');
|
||||
|
||||
|
||||
function KeyLock(collection, key, json) {
|
||||
this._collection = collection;
|
||||
this._key = key;
|
||||
this._json = json;
|
||||
this._updated = false;
|
||||
this._released = false;
|
||||
}
|
||||
|
||||
KeyLock.prototype.get = function() {
|
||||
if (!this._json)
|
||||
return undefined;
|
||||
else
|
||||
return JSON.parse(this._json);
|
||||
};
|
||||
|
||||
KeyLock.prototype.set = function(newValue) {
|
||||
if (this._released)
|
||||
throw new Error("Can't set after releasing a lock.");
|
||||
|
||||
this._json = JSON.stringify(newValue);
|
||||
this._updated = true;
|
||||
};
|
||||
|
||||
KeyLock.prototype.del = function() {
|
||||
if (this._released)
|
||||
throw new Error("Can't delete after releasing a lock.");
|
||||
|
||||
this._json = undefined;
|
||||
this._updated = true;
|
||||
};
|
||||
|
||||
KeyLock.prototype.release = function(cb) {
|
||||
if (this._released)
|
||||
throw new Error('KeyLock has already been released.');
|
||||
|
||||
this._released = true;
|
||||
|
||||
if (!this._updated)
|
||||
this._collection._request('release', this._key, null, cb && afterRelease);
|
||||
else
|
||||
this._collection._request('setRelease',
|
||||
this._key,
|
||||
{ json: this._json },
|
||||
cb && afterRelease);
|
||||
|
||||
function afterRelease(err, msg) {
|
||||
return cb(err);
|
||||
}
|
||||
};
|
51
node_modules/strong-store-cluster/lib/worker/request.js
generated
vendored
Normal file
51
node_modules/strong-store-cluster/lib/worker/request.js
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
|
||||
module.exports = request;
|
||||
process.on('message', onMessage);
|
||||
|
||||
|
||||
var requestIdCounter = 0;
|
||||
var requestCallbacks = {};
|
||||
|
||||
|
||||
// This function clobbers `data` if specified
|
||||
function request(method, collection, key, data, cb) {
|
||||
data = data || {};
|
||||
|
||||
data.type = 'DSM_REQUEST';
|
||||
data.method = method;
|
||||
data.collection = collection;
|
||||
data.key = key;
|
||||
|
||||
if (cb) {
|
||||
var requestId = getRequestId();
|
||||
requestCallbacks[requestId] = cb;
|
||||
data.requestId = requestId;
|
||||
}
|
||||
|
||||
process.send(data);
|
||||
}
|
||||
|
||||
|
||||
function onMessage(msg) {
|
||||
if (msg.type !== 'DSM_REPLY')
|
||||
return;
|
||||
|
||||
var requestId = msg.requestId;
|
||||
var cb = requestCallbacks[requestId];
|
||||
delete requestCallbacks[requestId];
|
||||
|
||||
if (msg.err) {
|
||||
var err = new Error('Master error: ' + msg.err);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
cb(null, msg);
|
||||
}
|
||||
|
||||
|
||||
function getRequestId() {
|
||||
return ++requestIdCounter;
|
||||
}
|
||||
|
||||
|
44
node_modules/strong-store-cluster/package.json
generated
vendored
Normal file
44
node_modules/strong-store-cluster/package.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
17
node_modules/strong-store-cluster/test/concurrent-inc.js
generated
vendored
Normal file
17
node_modules/strong-store-cluster/test/concurrent-inc.js
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
var helper = require('./helper/cluster-helper');
|
||||
|
||||
suite('concurrent increment', function() {
|
||||
test('master only', function(cb) {
|
||||
helper.run('do-concurrent-inc', true, 0, 4, cb);
|
||||
});
|
||||
|
||||
test('four workers', function(cb) {
|
||||
helper.run('do-concurrent-inc', false, 4, 4, cb);
|
||||
});
|
||||
|
||||
test('master and four workers', function(cb) {
|
||||
helper.run('do-concurrent-inc', true, 4, 4, cb);
|
||||
});
|
||||
});
|
||||
|
12
node_modules/strong-store-cluster/test/get-set-del.js
generated
vendored
Normal file
12
node_modules/strong-store-cluster/test/get-set-del.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
var helper = require('./helper/cluster-helper');
|
||||
|
||||
suite('get-set-del', function() {
|
||||
test('master', function(cb) {
|
||||
helper.run('do-get-set-del', true, 0, 1, cb);
|
||||
});
|
||||
|
||||
test('worker', function(cb) {
|
||||
helper.run('do-get-set-del', false, 1, 1, cb);
|
||||
});
|
||||
});
|
83
node_modules/strong-store-cluster/test/helper/cluster-helper.js
generated
vendored
Normal file
83
node_modules/strong-store-cluster/test/helper/cluster-helper.js
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
|
||||
|
||||
var assert = require('assert'),
|
||||
cluster = require('cluster');
|
||||
|
||||
|
||||
if (!process.env.CLUSTER_TEST) {
|
||||
// We're require()'d by the test harness. Export a function that start
|
||||
// the test.
|
||||
|
||||
exports.run = function(filename, inMaster, workers, concurrency, cb) {
|
||||
assert(filename);
|
||||
assert(inMaster || workers);
|
||||
assert(concurrency > 0);
|
||||
|
||||
var env = {};
|
||||
for (var key in process.env)
|
||||
env[key] = process.env[key];
|
||||
|
||||
env.CLUSTER_TEST = require.resolve('./' + filename);
|
||||
env.CLUSTER_TEST_IN_MASTER = inMaster;
|
||||
env.CLUSTER_TEST_WORKERS = workers;
|
||||
env.CLUSTER_TEST_CONCURRENCY = concurrency;
|
||||
|
||||
var cp = require('child_process').fork(module.filename,
|
||||
{env: env, stdio: 'inherit'});
|
||||
|
||||
cp.on('exit', function(exitCode, termSig) {
|
||||
assert(exitCode === 0);
|
||||
assert(!termSig);
|
||||
|
||||
cb();
|
||||
});
|
||||
};
|
||||
|
||||
} else {
|
||||
// We're being spawned as a standalone process. Execute the test and/or spawn
|
||||
// cluster workers that do.
|
||||
|
||||
var filename = process.env.CLUSTER_TEST,
|
||||
inMaster = !!+process.env.CLUSTER_TEST_IN_MASTER,
|
||||
workers = ~~ + process.env.CLUSTER_TEST_WORKERS,
|
||||
concurrency = ~~ + process.env.CLUSTER_TEST_CONCURRENCY;
|
||||
|
||||
var test = require(filename);
|
||||
|
||||
// Both the master and the worker have .setup() always called once.
|
||||
test.setup && test.setup();
|
||||
|
||||
var waiting = 0;
|
||||
|
||||
// If we're the master process, spawn a number of workers.
|
||||
if (cluster.isMaster && workers) {
|
||||
for (var i = 0; i < workers; i++)
|
||||
var worker = cluster.fork();
|
||||
|
||||
waiting += workers;
|
||||
|
||||
cluster.on('exit', function(worker, exitCode, termSig) {
|
||||
assert(exitCode === 0);
|
||||
assert(!termSig);
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
// If we're either a worker, or the master is supposed to run the tests,
|
||||
// run the test cases.
|
||||
if (cluster.isWorker || inMaster) {
|
||||
waiting += concurrency;
|
||||
|
||||
for (var i = 0; i < concurrency; i++)
|
||||
test.run(done);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function done() {
|
||||
assert(--waiting >= 0);
|
||||
if (waiting === 0)
|
||||
return test.teardown && test.teardown();
|
||||
}
|
||||
|
51
node_modules/strong-store-cluster/test/helper/do-concurrent-inc.js
generated
vendored
Normal file
51
node_modules/strong-store-cluster/test/helper/do-concurrent-inc.js
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
exports.run = run;
|
||||
exports.teardown = teardown;
|
||||
|
||||
|
||||
var ROUNDS = 100;
|
||||
assert = require('assert'),
|
||||
cluster = require('cluster'),
|
||||
store = require('../..');
|
||||
|
||||
|
||||
function run(cb) {
|
||||
var left = ROUNDS,
|
||||
coll = store.collection('counter');
|
||||
|
||||
increment();
|
||||
|
||||
function increment() {
|
||||
coll.acquire('counter', function(err, lock, val) {
|
||||
assert(!err);
|
||||
|
||||
if (!val)
|
||||
val = 1;
|
||||
else
|
||||
val++;
|
||||
|
||||
lock.set(val);
|
||||
lock.release();
|
||||
|
||||
if (--left > 0)
|
||||
increment();
|
||||
else
|
||||
cb();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function teardown() {
|
||||
if (cluster.isWorker)
|
||||
process._channel.unref();
|
||||
|
||||
if (cluster.isMaster) {
|
||||
store.collection('counter').get('counter', function(err, value) {
|
||||
assert(value % ROUNDS === 0);
|
||||
assert(value >= ROUNDS);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
60
node_modules/strong-store-cluster/test/helper/do-get-set-del.js
generated
vendored
Normal file
60
node_modules/strong-store-cluster/test/helper/do-get-set-del.js
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
|
||||
exports.run = run;
|
||||
exports.teardown = teardown;
|
||||
|
||||
|
||||
var assert = require('assert'),
|
||||
cluster = require('cluster'),
|
||||
store = require('../..');
|
||||
|
||||
|
||||
function run(cb) {
|
||||
var testsRun = 0;
|
||||
|
||||
testWith('test1', 'key1', 'zulis', onDone);
|
||||
testWith('test2', 'quux', 'stoll', onDone);
|
||||
testWith('test2', 'key1', 'urals', onDone);
|
||||
testWith('test2', 'key2', 'quipp', onDone);
|
||||
|
||||
function onDone() {
|
||||
if (++testsRun === 4)
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testWith(collectionName, key, testValue, cb) {
|
||||
var coll = store.collection(collectionName);
|
||||
|
||||
coll.get(key, function(err, value) {
|
||||
assert(!err);
|
||||
assert(value === undefined);
|
||||
|
||||
coll.set(key, testValue, function(err) {
|
||||
assert(!err);
|
||||
|
||||
coll.get(key, function(err, value) {
|
||||
assert(!err);
|
||||
assert(value === testValue);
|
||||
|
||||
coll.del(key, function(err) {
|
||||
assert(!err);
|
||||
|
||||
coll.get(key, function(err, value) {
|
||||
assert(!err);
|
||||
assert(value === undefined);
|
||||
|
||||
cb();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function teardown() {
|
||||
if (cluster.isWorker)
|
||||
process._channel.unref();
|
||||
}
|
80
node_modules/strong-store-cluster/test/helper/do-lock-get-set-del.js
generated
vendored
Normal file
80
node_modules/strong-store-cluster/test/helper/do-lock-get-set-del.js
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
|
||||
exports.run = run;
|
||||
exports.teardown = teardown;
|
||||
|
||||
|
||||
var assert = require('assert'),
|
||||
cluster = require('cluster'),
|
||||
store = require('../..');
|
||||
|
||||
|
||||
function run(cb) {
|
||||
var testsRun = 0;
|
||||
|
||||
testWith('test1', 'key1', {foo: 'zulis'}, onDone);
|
||||
testWith('test2', 'quux', ['stoll'], onDone);
|
||||
testWith('test2', 'key1', 'urals', onDone);
|
||||
testWith('test2', 'key2', 42, onDone);
|
||||
|
||||
function onDone() {
|
||||
if (++testsRun === 4)
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testWith(collectionName, key, testValue, cb) {
|
||||
var coll = store.collection(collectionName);
|
||||
|
||||
coll.set(key, testValue, function(err, value) {
|
||||
assert(!err);
|
||||
|
||||
coll.acquire(key, function(err, lock, value) {
|
||||
assert(!err);
|
||||
|
||||
assert.deepEqual(testValue, value);
|
||||
assert.deepEqual(testValue, lock.get());
|
||||
|
||||
// Non-primitive values should be deep-cloned.
|
||||
if (typeof testValue === 'object') {
|
||||
assert(testValue !== value);
|
||||
assert(testValue !== lock.get());
|
||||
}
|
||||
|
||||
lock.set('other');
|
||||
assert('other' === lock.get());
|
||||
|
||||
lock.release(function(err) {
|
||||
assert(!err);
|
||||
});
|
||||
|
||||
coll.acquire(key, function(err, lock, value) {
|
||||
assert(!err);
|
||||
|
||||
assert('other' === value);
|
||||
assert('other' === lock.get());
|
||||
|
||||
lock.del();
|
||||
assert(undefined === lock.get());
|
||||
|
||||
lock.release(function(err) {
|
||||
assert(!err);
|
||||
});
|
||||
|
||||
coll.get(key, function(err, value) {
|
||||
assert(!err);
|
||||
assert(undefined === value);
|
||||
|
||||
// That was it!
|
||||
cb();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function teardown() {
|
||||
if (cluster.isWorker)
|
||||
process._channel.unref();
|
||||
}
|
12
node_modules/strong-store-cluster/test/lock-get-set-del.js
generated
vendored
Normal file
12
node_modules/strong-store-cluster/test/lock-get-set-del.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
var helper = require('./helper/cluster-helper');
|
||||
|
||||
suite('lock-get-set-del', function() {
|
||||
test('master', function(cb) {
|
||||
helper.run('do-lock-get-set-del', true, 0, 1, cb);
|
||||
});
|
||||
|
||||
test('worker', function(cb) {
|
||||
helper.run('do-lock-get-set-del', false, 1, 1, cb);
|
||||
});
|
||||
});
|
@ -20,8 +20,10 @@
|
||||
"moment": "",
|
||||
"async": "",
|
||||
"passport-oauth": "",
|
||||
"markdown": "",
|
||||
"node-uuid": "~1.4.1",
|
||||
"MD5": "~1.2.1"
|
||||
"MD5": "~1.2.1",
|
||||
"pushover-notifications": "~0.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"supervisor": ""
|
||||
|
@ -46,6 +46,10 @@
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav > li {
|
||||
border-right: 1px solid #41bedd;
|
||||
}
|
||||
@ -76,3 +80,13 @@
|
||||
background-color: @navbarSecondaryLinkBackgroundActive;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.day-of-year {
|
||||
float: right !important;
|
||||
position: relative;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
@ -288,6 +288,10 @@ header {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.tech-current {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.enteries {
|
||||
margin-left: 150px;
|
||||
position: relative;
|
||||
@ -719,3 +723,33 @@ header {
|
||||
background-position: -7px -400px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
th.sort-true::after {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 8px solid transparent;
|
||||
border-right: 8px solid transparent;
|
||||
|
||||
border-top: 8px solid #000;
|
||||
content: "";
|
||||
top: 12px;
|
||||
left: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
th.sort-false::after {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 8px solid transparent;
|
||||
border-right: 8px solid transparent;
|
||||
|
||||
border-bottom: 8px solid #000;
|
||||
content: "";
|
||||
bottom: 11px;
|
||||
left: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ angular.module('biomed', ['biomed.filters', 'biomed.services', 'biomed.directive
|
||||
sales: 'Sales',
|
||||
other: 'Others'
|
||||
};
|
||||
$rootScope.dayOfYear = moment().dayOfYear();
|
||||
})
|
||||
.config(function($routeProvider, $locationProvider, $httpProvider) {
|
||||
|
||||
|
@ -18,9 +18,10 @@ biomed.TechScheduleCtrl = function($scope, $routeParams, $location, Schedule, Us
|
||||
function updateDate() {
|
||||
Schedule.index({
|
||||
tech: $routeParams.id,
|
||||
start: $scope.date.toJSON(),
|
||||
end: moment($scope.date).add('days', 7).toDate().toJSON()
|
||||
start: moment($scope.date).subtract('days', 10).toDate().toJSON(),
|
||||
end: moment($scope.date).add('days', 21).toDate().toJSON()
|
||||
}, function(result) {
|
||||
console.log(result);
|
||||
$scope.schedule = result;
|
||||
});
|
||||
}
|
||||
@ -85,6 +86,25 @@ biomed.SchedulePmsCtrl = function($scope, Clients) {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.sort = {
|
||||
column: 'client.name',
|
||||
descending: false
|
||||
};
|
||||
|
||||
$scope.selectedCls = function(column) {
|
||||
return column == $scope.sort.column && 'sort-' + $scope.sort.descending;
|
||||
}
|
||||
|
||||
$scope.changeSorting = function(column) {
|
||||
var sort = $scope.sort;
|
||||
if (sort.column == column) {
|
||||
sort.descending = !sort.descending;
|
||||
} else {
|
||||
sort.column = column;
|
||||
sort.descending = false;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$watch('month', filter);
|
||||
};
|
||||
|
||||
@ -181,17 +201,60 @@ biomed.UserClockCtrl = function($scope, $routeParams, Users) {
|
||||
};
|
||||
|
||||
biomed.PostIndexCtrl = function($scope, $routeParams, Posts, LocationBinder) {
|
||||
$scope.loading = true;
|
||||
var updatePosts = function() {
|
||||
$scope.loading = true;
|
||||
|
||||
$scope.posts = Posts.index(function() {
|
||||
$scope.loading = false;
|
||||
});
|
||||
$scope.posts = Posts.index(
|
||||
{page: $scope.page},
|
||||
function() {
|
||||
$scope.loading = false;
|
||||
|
||||
$scope.posted = 0;
|
||||
|
||||
angular.forEach($scope.posts, function(value) {
|
||||
if (value.status === "posted") {
|
||||
$scope.posted += 1;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.selectPage = function(page) {
|
||||
$scope.page = page;
|
||||
};
|
||||
|
||||
$scope.$watch('page', updatePosts);
|
||||
};
|
||||
|
||||
biomed.PostAddCtrl = function($scope, Posts, $location) {
|
||||
|
||||
$scope.tagOptions = {
|
||||
'multiple': true,
|
||||
'simple_tags': true,
|
||||
'tags': [],
|
||||
'formatNoMatches': function() { return 'Type a tag and press return to add it.'; }
|
||||
};
|
||||
|
||||
$scope.pages = [
|
||||
{ value: 'front', label: 'Front Page' },
|
||||
{ value: 'about-us', label: 'About Us' },
|
||||
{ value: 'sales', label: 'Sales' },
|
||||
{ value: 'service', label: 'Service' }
|
||||
];
|
||||
|
||||
$scope.togglePage = function(page) {
|
||||
var idx = $scope.model.pages.indexOf(page.value);
|
||||
if (idx > -1) {
|
||||
$scope.model.pages.splice(idx, 1);
|
||||
} else {
|
||||
$scope.model.pages.push(page.value);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.model = {
|
||||
gallery: []
|
||||
gallery: [],
|
||||
pages: [],
|
||||
postedOn: new Date()
|
||||
};
|
||||
|
||||
$scope.titleImageOptions = {
|
||||
@ -255,10 +318,6 @@ biomed.PostAddCtrl = function($scope, Posts, $location) {
|
||||
$scope.model.status = status;
|
||||
$scope.model.createdOn = new Date();
|
||||
|
||||
if (status === 'posted') {
|
||||
$scope.model.postedOn = new Date();
|
||||
}
|
||||
|
||||
Posts.create($scope.model, function(result) {
|
||||
$location.path("/posts/" + result._id);
|
||||
});
|
||||
@ -276,9 +335,34 @@ biomed.PostAddCtrl = function($scope, Posts, $location) {
|
||||
biomed.PostEditCtrl = function($scope, Posts, $routeParams, $location) {
|
||||
var galleryImages = {};
|
||||
|
||||
$scope.tagOptions = {
|
||||
'multiple': true,
|
||||
'simple_tags': true,
|
||||
'tags': [],
|
||||
'formatNoMatches': function() { return 'Type a tag and press return to add it.'; }
|
||||
};
|
||||
|
||||
$scope.pages = [
|
||||
{ value: 'front', label: 'Front Page' },
|
||||
{ value: 'about-us', label: 'About Us' },
|
||||
{ value: 'sales', label: 'Sales' },
|
||||
{ value: 'service', label: 'Service' }
|
||||
];
|
||||
|
||||
$scope.togglePage = function(page) {
|
||||
var idx = $scope.model.pages.indexOf(page.value);
|
||||
if (idx > -1) {
|
||||
$scope.model.pages.splice(idx, 1);
|
||||
} else {
|
||||
$scope.model.pages.push(page.value);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.model = Posts.get($routeParams, function() {
|
||||
$scope.loading = false;
|
||||
|
||||
console.log($scope.model);
|
||||
|
||||
if ($scope.model.image) {
|
||||
$scope.existingTitleImages = [$scope.model.image];
|
||||
}
|
||||
@ -287,6 +371,10 @@ biomed.PostEditCtrl = function($scope, Posts, $routeParams, $location) {
|
||||
for (var i = 0; i < $scope.model.gallery.length; i++) {
|
||||
galleryImages[$scope.model.gallery[i]] = 1;
|
||||
}
|
||||
|
||||
if (!$scope.model.postedOn) {
|
||||
$scope.model.postedOn = new Date();
|
||||
}
|
||||
});
|
||||
|
||||
$scope.titleImageOptions = {
|
||||
@ -349,11 +437,7 @@ biomed.PostEditCtrl = function($scope, Posts, $routeParams, $location) {
|
||||
$scope.model.gallery = Object.keys(galleryImages);
|
||||
$scope.model.status = status;
|
||||
|
||||
if (status === 'posted') {
|
||||
$scope.model.postedOn = new Date();
|
||||
} else {
|
||||
$scope.model.postedOn = null;
|
||||
}
|
||||
console.log($scope.model);
|
||||
|
||||
Posts.update({id: $scope.model._id}, $scope.model, function(result) {
|
||||
$location.path("/posts/");
|
||||
@ -396,7 +480,7 @@ biomed.ClientIndexCtrl = function($scope, $filter, $routeParams, Clients, Locati
|
||||
LocationBinder($scope, ['query']);
|
||||
|
||||
$scope.filter = function() {
|
||||
filteredData = $filter('filter')(allData, $scope.query);
|
||||
filteredData = $filter('orderBy')($filter('filter')(allData, $scope.query), $scope.sort.column, $scope.sort.descending);
|
||||
index = initialPageSize;
|
||||
$scope.canLoad = true;
|
||||
$scope.clients = filteredData.slice(0, initialPageSize);
|
||||
@ -407,6 +491,27 @@ biomed.ClientIndexCtrl = function($scope, $filter, $routeParams, Clients, Locati
|
||||
index += pageSize;
|
||||
$scope.canLoad = index < filteredData.length;
|
||||
}
|
||||
|
||||
$scope.sort = {
|
||||
column: 'name',
|
||||
descending: false
|
||||
};
|
||||
|
||||
$scope.selectedCls = function(column) {
|
||||
return column == $scope.sort.column && 'sort-' + $scope.sort.descending;
|
||||
}
|
||||
|
||||
$scope.changeSorting = function(column) {
|
||||
var sort = $scope.sort;
|
||||
if (sort.column == column) {
|
||||
sort.descending = !sort.descending;
|
||||
} else {
|
||||
sort.column = column;
|
||||
sort.descending = false;
|
||||
}
|
||||
|
||||
$scope.filter();
|
||||
};
|
||||
};
|
||||
|
||||
biomed.ClientAddCtrl = function($scope, Clients, $location) {
|
||||
@ -578,6 +683,10 @@ biomed.WorkorderIndexCtrl = function($scope, $filter, $routeParams, Workorders,
|
||||
|
||||
$scope.$watch('end', fetchData);
|
||||
|
||||
$scope.sort = {
|
||||
column: 'scheduling.start',
|
||||
descending: true
|
||||
};
|
||||
|
||||
$scope.addItems = function() {
|
||||
$scope.workorders = $scope.workorders.concat(filteredData.slice(index, index + pageSize));
|
||||
@ -592,6 +701,20 @@ biomed.WorkorderIndexCtrl = function($scope, $filter, $routeParams, Workorders,
|
||||
$scope.workorders = filteredData.slice(0, initialPageSize);
|
||||
};
|
||||
|
||||
$scope.selectedCls = function(column) {
|
||||
return column == $scope.sort.column && 'sort-' + $scope.sort.descending;
|
||||
}
|
||||
|
||||
$scope.changeSorting = function(column) {
|
||||
var sort = $scope.sort;
|
||||
if (sort.column == column) {
|
||||
sort.descending = !sort.descending;
|
||||
} else {
|
||||
sort.column = column;
|
||||
sort.descending = false;
|
||||
}
|
||||
};
|
||||
|
||||
function fetchData() {
|
||||
$scope.loading = true;
|
||||
|
||||
@ -657,6 +780,10 @@ biomed.WorkorderAddCtrl = function($scope, $location, Workorders, Schedule, Clie
|
||||
|
||||
$scope.$watch('group', updateUsers);
|
||||
|
||||
$scope.$watch('model.client', function() {
|
||||
$scope.currentClient = Clients.get({ id: $scope.model.client });
|
||||
});
|
||||
|
||||
Clients.index(function(result) {
|
||||
$scope.clients = result;
|
||||
});
|
||||
|
@ -89,10 +89,17 @@ angular.module('biomed.directives', [])
|
||||
|
||||
attr.$observe('value', update)();
|
||||
attr.$observe('title', function(){ update(); a.text(tab.title); })();
|
||||
attr.$observe('visible', function(){
|
||||
update();
|
||||
tab.tabElement[0].style.display = (tab.visible === "false") ? 'none' : 'block';
|
||||
})();
|
||||
|
||||
function update() {
|
||||
console.log(attr.visible);
|
||||
tab.title = attr.title;
|
||||
tab.value = attr.value || attr.title;
|
||||
tab.visible = attr.visible;
|
||||
|
||||
if (!ngModel.$setViewValue && (!ngModel.$viewValue || tab == selectedTab)) {
|
||||
// we are not part of angular
|
||||
ngModel.$viewValue = tab.value;
|
||||
@ -235,17 +242,17 @@ angular.module('biomed.directives', [])
|
||||
function setupScale() {
|
||||
x = d3.scale.linear()
|
||||
.range([0, 100])
|
||||
.domain([420, 1320])
|
||||
.domain([420, 1140])
|
||||
.clamp(true);
|
||||
}
|
||||
|
||||
setupScale();
|
||||
|
||||
var color = d3.scale.category20();
|
||||
var hourWidth = 100 / 15;
|
||||
var hourWidth = 100 / 12;
|
||||
|
||||
$scope.hourMarkers = [];
|
||||
for (var i = 7; i < 22; i++) {
|
||||
for (var i = 7; i < 19; i++) {
|
||||
$scope.hourMarkers.push({
|
||||
date: moment({ hour: i }).toDate(),
|
||||
style: {
|
||||
@ -266,13 +273,16 @@ angular.module('biomed.directives', [])
|
||||
function generateDate() {
|
||||
var range = moment($scope.date);
|
||||
var data = {};
|
||||
var current = range.format('ddd MMM Do YYYY');
|
||||
|
||||
for (var i = 0; i < 7; i++) {
|
||||
for (var i = -7; i < 22; i++) {
|
||||
var day = range.clone().add(i, 'days');
|
||||
var key = day.format('MM-DD-YYYY');
|
||||
var label = day.format('ddd MMM Do YYYY');
|
||||
|
||||
data[key] = {
|
||||
order: i,
|
||||
current: current == label,
|
||||
label: label,
|
||||
values: []
|
||||
};
|
||||
@ -345,7 +355,12 @@ angular.module('biomed.directives', [])
|
||||
})
|
||||
});
|
||||
|
||||
$scope.data = data;
|
||||
var dataArray = [];
|
||||
for (var o in data) {
|
||||
dataArray.push(data[o]);
|
||||
}
|
||||
|
||||
$scope.data = dataArray;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -374,7 +389,7 @@ angular.module('biomed.directives', [])
|
||||
rangeDate = moment($scope.date).startOf('day');
|
||||
|
||||
rangeStart = moment(rangeDate).add('hours', 7);
|
||||
rangeEnd = moment(rangeDate).add('hours', 22);
|
||||
rangeEnd = moment(rangeDate).add('hours', 19);
|
||||
|
||||
x = d3.time.scale()
|
||||
.range([0, 100])
|
||||
|
@ -257,7 +257,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" title="Frequency">
|
||||
<div class="tab-pane" title="Frequency" visible="{{accountHasPermission('client.frequency')}}">
|
||||
<table class="table frequency">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -20,10 +20,10 @@
|
||||
<table class="biomed-table" infinite-scroll="addItems()" can-load="canLoad" threshold="300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20%"></th>
|
||||
<th style="width: 48%">Client Name</th>
|
||||
<th style="width: 20%">Contact</th>
|
||||
<th style="width: 12%">Phone</th>
|
||||
<th style="width: 20%" ng-class="selectedCls('identifier')" ng-click="changeSorting('identifier')">ID</th>
|
||||
<th style="width: 48%" ng-class="selectedCls('name')" ng-click="changeSorting('name')">Client Name</th>
|
||||
<th style="width: 20%" ng-class="selectedCls('contacts[0].name')" ng-click="changeSorting('contacts[0].name')">Contact</th>
|
||||
<th style="width: 12%" ng-class="selectedCls('contacts[0].phone')" ng-click="changeSorting('contacts[0].phone')">Phone</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -29,6 +29,32 @@
|
||||
<textarea ng-model="model.details" class="input-xlarge"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Posted On</label>
|
||||
<div class="controls">
|
||||
<span><input ng-model="model.postedOn" datepicker type="text" class="input-small"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Pages</label>
|
||||
<div class="controls">
|
||||
<label ng-repeat="page in pages">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="model.pages[]"
|
||||
value="page.value"
|
||||
ng-checked="model.pages.indexOf(page.value) > -1"
|
||||
ng-click="togglePage(page)"
|
||||
>{{page.label}}</input>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Tags</label>
|
||||
<div class="controls">
|
||||
<input type="text" ui-select2="tagOptions" ng-model="model.tags" class="input-xxlarge" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -42,7 +68,7 @@
|
||||
<div class="dropzone" dropzone="titleImageOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="control-group" ng-show="model.image">
|
||||
<label class="control-label">Gallery</label>
|
||||
<div class="controls">
|
||||
<div class="dropzone" dropzone="galleryImageOptions"></div>
|
||||
|
@ -29,6 +29,32 @@
|
||||
<textarea ng-model="model.details" class="input-xlarge"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Posted On</label>
|
||||
<div class="controls">
|
||||
<span><input ng-model="model.postedOn" datepicker type="text" class="input-small"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Pages</label>
|
||||
<div class="controls">
|
||||
<label ng-repeat="page in pages">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="model.pages[]"
|
||||
value="page.value"
|
||||
ng-checked="model.pages.indexOf(page.value) > -1"
|
||||
ng-click="togglePage(page)"
|
||||
>{{page.label}}</input>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Tags</label>
|
||||
<div class="controls">
|
||||
<input type="text" ui-select2="tagOptions" ng-model="model.tags" class="input-xxlarge" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -42,7 +68,7 @@
|
||||
<div class="dropzone" dropzone="titleImageOptions" existing="existingTitleImages"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="control-group" ng-show="model.image">
|
||||
<label class="control-label">Gallery</label>
|
||||
<div class="controls">
|
||||
<div class="dropzone" dropzone="galleryImageOptions" existing="existingGalleryImages"></div>
|
||||
|
@ -9,20 +9,28 @@
|
||||
<div class="span12">
|
||||
<div class="toolbelt">
|
||||
<a href="/posts/add" class="btn btn-primary">Create new Post</a>
|
||||
<a ng-click="selectPage('')" class="btn">All</a>
|
||||
<a ng-click="selectPage('front')" class="btn">Front Page</a>
|
||||
<a ng-click="selectPage('about-us')" class="btn">About Us</a>
|
||||
<a ng-click="selectPage('sales')" class="btn">Sales</a>
|
||||
<a ng-click="selectPage('service')" class="btn">Service</a>
|
||||
<div class="pull-right">
|
||||
<span class="toolbelt-text">Total Published: {{posted}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<table class="biomed-table" infinite-scroll="addItems()" can-load="canLoad" threshold="300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%">Title</th>
|
||||
<th style="width: 5%">Author</th>
|
||||
<th style="width: 5%">Created on</th>
|
||||
<th style="width: 5%">Posted on</th>
|
||||
<th style="width: 5%">Status</th>
|
||||
<th style="width: 45%">Title</th>
|
||||
<th style="width: 15%">Author</th>
|
||||
<th style="width: 15%">Created on</th>
|
||||
<th style="width: 15%">Posted on</th>
|
||||
<th style="width: 10%">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-show="loading"><td colspan="4" class="table-loading"><i class="loader"></i></td></tr>
|
||||
<tr ng-hide="loading || posts.length"><td colspan="4" class="table-message">There is no information to display.</td></tr>
|
||||
<tr ng-show="loading"><td colspan="5" class="table-loading"><i class="loader"></i></td></tr>
|
||||
<tr ng-hide="loading || posts.length"><td colspan="5" class="table-message">There is no information to display.</td></tr>
|
||||
<tr ng-hide="loading" ng-repeat="post in posts">
|
||||
<td>
|
||||
<a href="/posts/{{post._id}}">
|
||||
|
@ -33,20 +33,20 @@
|
||||
<table class="biomed-table" infinite-scroll="addItems()" can-load="canLoad" threshold="300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 48%">Client Name</th>
|
||||
<th style="width: 20%">Reason</th>
|
||||
<th style="width: 20%">Contact</th>
|
||||
<th style="width: 12%">Phone</th>
|
||||
<th style="width: 48%" ng-class="selectedCls('client.name')" ng-click="changeSorting('client.name')">Client Name</th>
|
||||
<th style="width: 20%" ng-class="selectedCls('reason')" ng-click="changeSorting('reason')">Reason</th>
|
||||
<th style="width: 20%" ng-class="selectedCls('client.contacts[0].name')" ng-click="changeSorting('client.contacts[0].name')">Contact</th>
|
||||
<th style="width: 12%" ng-class="selectedCls('client.contacts[0].phone')" ng-click="changeSorting('client.contacts[0].phone')">Phone</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-show="loading"><td colspan="4" class="table-loading"><i class="loader"></i></td></tr>
|
||||
<tr ng-hide="loading || pms.length"><td colspan="4" class="table-message">There is no information to display.</td></tr>
|
||||
<tr ng-hide="loading" ng-repeat="pm in pms">
|
||||
<tr ng-hide="loading" ng-repeat="pm in pms | orderBy : sort.column : sort.descending">
|
||||
<td><a ng-href="/workorders/add?workorderType=pm&clientId={{pm.client._id}}&type={{pm.reason}}">{{pm.client.name}} ({{pm.client.identifier | uppercase}})</a><br>
|
||||
<td>{{pm.reason}}</td>
|
||||
<td>{{pm.client.contacts[0].name}}</td>
|
||||
<td>{{pm.lient.contacts[0].phone}}</td>
|
||||
<td>{{pm.client.contacts[0].phone}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user