├── .eslintignore
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── Makefile
├── README.md
├── bower.json
├── coffeelint.json
├── dist
├── markdown-it-checkbox.js
└── markdown-it-checkbox.min.js
├── gulpfile.coffee
├── index.coffee
├── index.js
├── package.json
└── test
├── fixtures
├── checkbox.txt
└── checkbox_with_options.txt
└── test.coffee
/.eslintignore:
--------------------------------------------------------------------------------
1 | coverage/
2 | demo/
3 | dist/
4 | node_modules
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .coveralls.yml
3 | node_modules/
4 | coverage/
5 | build/
6 | *.log
7 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | coverage/
2 | support/
3 | test/
4 | Makefile
5 | .*
6 | *.log
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '0.10'
4 | - '0.11'
5 | before_script:
6 | - npm config set coverage true
7 | script: npm test
8 | after_success:
9 | - npm run-script coveralls
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | 1.0.1 / 2015-03-17
2 | ------------------
3 |
4 | - Fixed Documentation.
5 |
6 | 1.0.0 / 2015-03-17
7 | ------------------
8 |
9 | - Initial release.
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Markus Cecot
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | NPM_PACKAGE := $(shell node -e 'process.stdout.write(require("./package.json").name)')
2 | NPM_VERSION := $(shell node -e 'process.stdout.write(require("./package.json").version)')
3 |
4 | TMP_PATH := /tmp/${NPM_PACKAGE}-$(shell date +%s)
5 |
6 | REMOTE_NAME ?= origin
7 | REMOTE_REPO ?= $(shell git config --get remote.${REMOTE_NAME}.url)
8 |
9 | CURR_HEAD := $(firstword $(shell git show-ref --hash HEAD | cut -b -6) master)
10 | GITHUB_PROJ := https://github.com//mcecot/${NPM_PACKAGE}
11 |
12 |
13 | lint:
14 | ./node_modules/.bin/eslint --reset .
15 |
16 | test: lint
17 | ./node_modules/.bin/mocha -R spec
18 |
19 | coverage:
20 | rm -rf coverage
21 | ./node_modules/.bin/istanbul cover node_modules/.bin/_mocha
22 |
23 | test-ci: lint
24 | istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage
25 |
26 | browserify:
27 | rm -rf ./dist
28 | mkdir dist
29 | # Browserify
30 | ( printf "/*! ${NPM_PACKAGE} ${NPM_VERSION} ${GITHUB_PROJ} @license MIT */" ; \
31 | ./node_modules/.bin/browserify ./ -s markdownitCheckbox \
32 | ) > dist/markdown-it-checkbox.js
33 | # Minify
34 | ./node_modules/.bin/uglifyjs dist/markdown-it-checkbox.js -b beautify=false,ascii-only=true -c -m \
35 | --preamble "/*! ${NPM_PACKAGE} ${NPM_VERSION} ${GITHUB_PROJ} @license MIT */" \
36 | > dist/markdown-it-checkbox.min.js
37 |
38 | .PHONY: lint test coverage
39 | .SILENT: lint test
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # markdown-it-checkbox [![NPM version][npm-image]][npm-url]
2 | [![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Dependency Status][depstat-image]][depstat-url] [![devDependency Status][devdepstat-image]][devdepstat-url]
3 |
4 | > Plugin to create checkboxes for [markdown-it](https://github.com/markdown-it/markdown-it) markdown parser.
5 |
6 | This plugin allows to create checkboxes for tasklists as discussed [here](http://talk.commonmark.org/t/task-lists-in-standard-markdown/41).
7 |
8 |
9 |
10 | ## Usage
11 |
12 | ## Install
13 |
14 | node.js, browser:
15 |
16 | ```bash
17 | npm install markdown-it-checkbox --save
18 | bower install markdown-it-checkbox --save
19 | ```
20 |
21 | ## Use
22 |
23 | ```js
24 | var md = require('markdown-it')()
25 | .use(require('markdown-it-checkbox'));
26 |
27 | md.render('[ ] unchecked') // =>
28 | //
29 | //
30 | //
31 | //
32 |
33 | md.render('[x] checked') // =>
34 | //
35 | //
36 | //
37 | //
38 | ```
39 |
40 | _Differences in browser._ If you load script directly into the page, without
41 | package system, module will add itself globally as `window.markdownitCheckbox`.
42 |
43 | ## Options
44 |
45 | ```js
46 | var md = require('markdown-it')()
47 | .use(require('markdown-it-checkbox'),{
48 | divWrap: true,
49 | divClass: 'cb',
50 | idPrefix: 'cbx_'
51 | });
52 |
53 | md.render('[ ] unchecked') // =>
54 | //
55 | //
56 | //
57 | //
58 | //
59 | //
60 | ```
61 |
62 | ## divWrap
63 |
64 | * **Type:** `Boolean`
65 | * **Default:** `false`
66 |
67 | wrap div arround checkbox. this makes it possible to use it for example with [Awesome Bootstrap Checkbox](https://github.com/flatlogic/awesome-bootstrap-checkbox/).
68 |
69 | ## divClass
70 |
71 | * **Type:** `String`
72 | * **Default:** `checkbox`
73 |
74 | classname of div wrapper. will only be used if `divWrap` is enanbled.
75 |
76 | ## idPrefix
77 |
78 | * **Type:** `String`
79 | * **Default:** `checkbox`
80 |
81 | the id of the checkboxs input contains the prefix and an incremental number starting with `0`. i.e. `checkbox1` for the 2nd checkbox.
82 |
83 |
84 | ## License
85 |
86 | [MIT License](https://github.com/mcecot/markdown-it-checkbox/blob/master/LICENSE) © 2015 Markus Cecot
87 |
88 | [npm-url]: https://npmjs.org/package/markdown-it-checkbox
89 | [npm-image]: https://img.shields.io/npm/v/markdown-it-checkbox.svg
90 |
91 | [travis-url]: http://travis-ci.org/mcecot/markdown-it-checkbox
92 | [travis-image]: https://secure.travis-ci.org/mcecot/markdown-it-checkbox.svg?branch=master
93 |
94 | [coveralls-url]: https://coveralls.io/r/mcecot/markdown-it-checkbox
95 | [coveralls-image]: https://img.shields.io/coveralls/mcecot/markdown-it-checkbox.svg
96 |
97 | [depstat-url]: https://david-dm.org/mcecot/markdown-it-checkbox
98 | [depstat-image]: https://david-dm.org/mcecot/markdown-it-checkbox.svg
99 |
100 | [devdepstat-url]: https://david-dm.org/mcecot/markdown-it-checkbox#info=devDependencies
101 | [devdepstat-image]: https://david-dm.org/mcecot/markdown-it-checkbox/dev-status.svg
102 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "markdown-it-checkbox",
3 | "main": "dist/markdown-it-checkbox.js",
4 | "homepage": "https://github.com/mcecot/markdown-it-checkbox",
5 | "version": "1.1.1",
6 | "description": "Plugin to create checkboxes in markdown-it markdown parser",
7 | "keywords": [
8 | "markdown-it-plugin",
9 | "markdown-it",
10 | "markdown"
11 | ],
12 | "license": "MIT",
13 | "ignore": [
14 | "**/.*",
15 | "benchmark",
16 | "bower_components",
17 | "coverage",
18 | "demo",
19 | "docs",
20 | "lib",
21 | "node_modules",
22 | "support",
23 | "test",
24 | "Makefile",
25 | "index*"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/coffeelint.json:
--------------------------------------------------------------------------------
1 | {
2 | "indentation": {
3 | "value": 2
4 | },
5 | "line_endings": {
6 | "level": "error",
7 | "value": "unix"
8 | },
9 | "colon_assignment_spacing": {
10 | "name": "colon_assignment_spacing",
11 | "level": "error",
12 | "spacing": {
13 | "left": 0,
14 | "right": 1
15 | }
16 | },
17 | "space_operators": {
18 | "level": "error"
19 | },
20 | "newlines_after_classes": {
21 | "value": 3,
22 | "level": "error"
23 | },
24 | "no_stand_alone_at": {
25 | "level": "error"
26 | },
27 | "arrow_spacing": {
28 | "level": "error"
29 | },
30 | "cyclomatic_complexity": {
31 | "level": "error"
32 | },
33 | "empty_constructor_needs_parens": {
34 | "level": "error"
35 | },
36 | "no_empty_param_list": {
37 | "level": "error"
38 | },
39 | "no_unnecessary_fat_arrows": {
40 | "level": "error"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/dist/markdown-it-checkbox.js:
--------------------------------------------------------------------------------
1 | /*! markdown-it-checkbox 1.1.1 https://github.com//mcecot/markdown-it-checkbox @license MIT */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.markdownitCheckbox = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0 && length <= MAX_ARRAY_INDEX;
141 | };
142 |
143 | // Collection Functions
144 | // --------------------
145 |
146 | // The cornerstone, an `each` implementation, aka `forEach`.
147 | // Handles raw objects in addition to array-likes. Treats all
148 | // sparse array-likes as if they were dense.
149 | _.each = _.forEach = function(obj, iteratee, context) {
150 | iteratee = optimizeCb(iteratee, context);
151 | var i, length;
152 | if (isArrayLike(obj)) {
153 | for (i = 0, length = obj.length; i < length; i++) {
154 | iteratee(obj[i], i, obj);
155 | }
156 | } else {
157 | var keys = _.keys(obj);
158 | for (i = 0, length = keys.length; i < length; i++) {
159 | iteratee(obj[keys[i]], keys[i], obj);
160 | }
161 | }
162 | return obj;
163 | };
164 |
165 | // Return the results of applying the iteratee to each element.
166 | _.map = _.collect = function(obj, iteratee, context) {
167 | iteratee = cb(iteratee, context);
168 | var keys = !isArrayLike(obj) && _.keys(obj),
169 | length = (keys || obj).length,
170 | results = Array(length);
171 | for (var index = 0; index < length; index++) {
172 | var currentKey = keys ? keys[index] : index;
173 | results[index] = iteratee(obj[currentKey], currentKey, obj);
174 | }
175 | return results;
176 | };
177 |
178 | // Create a reducing function iterating left or right.
179 | function createReduce(dir) {
180 | // Optimized iterator function as using arguments.length
181 | // in the main function will deoptimize the, see #1991.
182 | function iterator(obj, iteratee, memo, keys, index, length) {
183 | for (; index >= 0 && index < length; index += dir) {
184 | var currentKey = keys ? keys[index] : index;
185 | memo = iteratee(memo, obj[currentKey], currentKey, obj);
186 | }
187 | return memo;
188 | }
189 |
190 | return function(obj, iteratee, memo, context) {
191 | iteratee = optimizeCb(iteratee, context, 4);
192 | var keys = !isArrayLike(obj) && _.keys(obj),
193 | length = (keys || obj).length,
194 | index = dir > 0 ? 0 : length - 1;
195 | // Determine the initial value if none is provided.
196 | if (arguments.length < 3) {
197 | memo = obj[keys ? keys[index] : index];
198 | index += dir;
199 | }
200 | return iterator(obj, iteratee, memo, keys, index, length);
201 | };
202 | }
203 |
204 | // **Reduce** builds up a single result from a list of values, aka `inject`,
205 | // or `foldl`.
206 | _.reduce = _.foldl = _.inject = createReduce(1);
207 |
208 | // The right-associative version of reduce, also known as `foldr`.
209 | _.reduceRight = _.foldr = createReduce(-1);
210 |
211 | // Return the first value which passes a truth test. Aliased as `detect`.
212 | _.find = _.detect = function(obj, predicate, context) {
213 | var key;
214 | if (isArrayLike(obj)) {
215 | key = _.findIndex(obj, predicate, context);
216 | } else {
217 | key = _.findKey(obj, predicate, context);
218 | }
219 | if (key !== void 0 && key !== -1) return obj[key];
220 | };
221 |
222 | // Return all the elements that pass a truth test.
223 | // Aliased as `select`.
224 | _.filter = _.select = function(obj, predicate, context) {
225 | var results = [];
226 | predicate = cb(predicate, context);
227 | _.each(obj, function(value, index, list) {
228 | if (predicate(value, index, list)) results.push(value);
229 | });
230 | return results;
231 | };
232 |
233 | // Return all the elements for which a truth test fails.
234 | _.reject = function(obj, predicate, context) {
235 | return _.filter(obj, _.negate(cb(predicate)), context);
236 | };
237 |
238 | // Determine whether all of the elements match a truth test.
239 | // Aliased as `all`.
240 | _.every = _.all = function(obj, predicate, context) {
241 | predicate = cb(predicate, context);
242 | var keys = !isArrayLike(obj) && _.keys(obj),
243 | length = (keys || obj).length;
244 | for (var index = 0; index < length; index++) {
245 | var currentKey = keys ? keys[index] : index;
246 | if (!predicate(obj[currentKey], currentKey, obj)) return false;
247 | }
248 | return true;
249 | };
250 |
251 | // Determine if at least one element in the object matches a truth test.
252 | // Aliased as `any`.
253 | _.some = _.any = function(obj, predicate, context) {
254 | predicate = cb(predicate, context);
255 | var keys = !isArrayLike(obj) && _.keys(obj),
256 | length = (keys || obj).length;
257 | for (var index = 0; index < length; index++) {
258 | var currentKey = keys ? keys[index] : index;
259 | if (predicate(obj[currentKey], currentKey, obj)) return true;
260 | }
261 | return false;
262 | };
263 |
264 | // Determine if the array or object contains a given item (using `===`).
265 | // Aliased as `includes` and `include`.
266 | _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
267 | if (!isArrayLike(obj)) obj = _.values(obj);
268 | if (typeof fromIndex != 'number' || guard) fromIndex = 0;
269 | return _.indexOf(obj, item, fromIndex) >= 0;
270 | };
271 |
272 | // Invoke a method (with arguments) on every item in a collection.
273 | _.invoke = function(obj, method) {
274 | var args = slice.call(arguments, 2);
275 | var isFunc = _.isFunction(method);
276 | return _.map(obj, function(value) {
277 | var func = isFunc ? method : value[method];
278 | return func == null ? func : func.apply(value, args);
279 | });
280 | };
281 |
282 | // Convenience version of a common use case of `map`: fetching a property.
283 | _.pluck = function(obj, key) {
284 | return _.map(obj, _.property(key));
285 | };
286 |
287 | // Convenience version of a common use case of `filter`: selecting only objects
288 | // containing specific `key:value` pairs.
289 | _.where = function(obj, attrs) {
290 | return _.filter(obj, _.matcher(attrs));
291 | };
292 |
293 | // Convenience version of a common use case of `find`: getting the first object
294 | // containing specific `key:value` pairs.
295 | _.findWhere = function(obj, attrs) {
296 | return _.find(obj, _.matcher(attrs));
297 | };
298 |
299 | // Return the maximum element (or element-based computation).
300 | _.max = function(obj, iteratee, context) {
301 | var result = -Infinity, lastComputed = -Infinity,
302 | value, computed;
303 | if (iteratee == null && obj != null) {
304 | obj = isArrayLike(obj) ? obj : _.values(obj);
305 | for (var i = 0, length = obj.length; i < length; i++) {
306 | value = obj[i];
307 | if (value > result) {
308 | result = value;
309 | }
310 | }
311 | } else {
312 | iteratee = cb(iteratee, context);
313 | _.each(obj, function(value, index, list) {
314 | computed = iteratee(value, index, list);
315 | if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
316 | result = value;
317 | lastComputed = computed;
318 | }
319 | });
320 | }
321 | return result;
322 | };
323 |
324 | // Return the minimum element (or element-based computation).
325 | _.min = function(obj, iteratee, context) {
326 | var result = Infinity, lastComputed = Infinity,
327 | value, computed;
328 | if (iteratee == null && obj != null) {
329 | obj = isArrayLike(obj) ? obj : _.values(obj);
330 | for (var i = 0, length = obj.length; i < length; i++) {
331 | value = obj[i];
332 | if (value < result) {
333 | result = value;
334 | }
335 | }
336 | } else {
337 | iteratee = cb(iteratee, context);
338 | _.each(obj, function(value, index, list) {
339 | computed = iteratee(value, index, list);
340 | if (computed < lastComputed || computed === Infinity && result === Infinity) {
341 | result = value;
342 | lastComputed = computed;
343 | }
344 | });
345 | }
346 | return result;
347 | };
348 |
349 | // Shuffle a collection, using the modern version of the
350 | // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
351 | _.shuffle = function(obj) {
352 | var set = isArrayLike(obj) ? obj : _.values(obj);
353 | var length = set.length;
354 | var shuffled = Array(length);
355 | for (var index = 0, rand; index < length; index++) {
356 | rand = _.random(0, index);
357 | if (rand !== index) shuffled[index] = shuffled[rand];
358 | shuffled[rand] = set[index];
359 | }
360 | return shuffled;
361 | };
362 |
363 | // Sample **n** random values from a collection.
364 | // If **n** is not specified, returns a single random element.
365 | // The internal `guard` argument allows it to work with `map`.
366 | _.sample = function(obj, n, guard) {
367 | if (n == null || guard) {
368 | if (!isArrayLike(obj)) obj = _.values(obj);
369 | return obj[_.random(obj.length - 1)];
370 | }
371 | return _.shuffle(obj).slice(0, Math.max(0, n));
372 | };
373 |
374 | // Sort the object's values by a criterion produced by an iteratee.
375 | _.sortBy = function(obj, iteratee, context) {
376 | iteratee = cb(iteratee, context);
377 | return _.pluck(_.map(obj, function(value, index, list) {
378 | return {
379 | value: value,
380 | index: index,
381 | criteria: iteratee(value, index, list)
382 | };
383 | }).sort(function(left, right) {
384 | var a = left.criteria;
385 | var b = right.criteria;
386 | if (a !== b) {
387 | if (a > b || a === void 0) return 1;
388 | if (a < b || b === void 0) return -1;
389 | }
390 | return left.index - right.index;
391 | }), 'value');
392 | };
393 |
394 | // An internal function used for aggregate "group by" operations.
395 | var group = function(behavior) {
396 | return function(obj, iteratee, context) {
397 | var result = {};
398 | iteratee = cb(iteratee, context);
399 | _.each(obj, function(value, index) {
400 | var key = iteratee(value, index, obj);
401 | behavior(result, value, key);
402 | });
403 | return result;
404 | };
405 | };
406 |
407 | // Groups the object's values by a criterion. Pass either a string attribute
408 | // to group by, or a function that returns the criterion.
409 | _.groupBy = group(function(result, value, key) {
410 | if (_.has(result, key)) result[key].push(value); else result[key] = [value];
411 | });
412 |
413 | // Indexes the object's values by a criterion, similar to `groupBy`, but for
414 | // when you know that your index values will be unique.
415 | _.indexBy = group(function(result, value, key) {
416 | result[key] = value;
417 | });
418 |
419 | // Counts instances of an object that group by a certain criterion. Pass
420 | // either a string attribute to count by, or a function that returns the
421 | // criterion.
422 | _.countBy = group(function(result, value, key) {
423 | if (_.has(result, key)) result[key]++; else result[key] = 1;
424 | });
425 |
426 | // Safely create a real, live array from anything iterable.
427 | _.toArray = function(obj) {
428 | if (!obj) return [];
429 | if (_.isArray(obj)) return slice.call(obj);
430 | if (isArrayLike(obj)) return _.map(obj, _.identity);
431 | return _.values(obj);
432 | };
433 |
434 | // Return the number of elements in an object.
435 | _.size = function(obj) {
436 | if (obj == null) return 0;
437 | return isArrayLike(obj) ? obj.length : _.keys(obj).length;
438 | };
439 |
440 | // Split a collection into two arrays: one whose elements all satisfy the given
441 | // predicate, and one whose elements all do not satisfy the predicate.
442 | _.partition = function(obj, predicate, context) {
443 | predicate = cb(predicate, context);
444 | var pass = [], fail = [];
445 | _.each(obj, function(value, key, obj) {
446 | (predicate(value, key, obj) ? pass : fail).push(value);
447 | });
448 | return [pass, fail];
449 | };
450 |
451 | // Array Functions
452 | // ---------------
453 |
454 | // Get the first element of an array. Passing **n** will return the first N
455 | // values in the array. Aliased as `head` and `take`. The **guard** check
456 | // allows it to work with `_.map`.
457 | _.first = _.head = _.take = function(array, n, guard) {
458 | if (array == null) return void 0;
459 | if (n == null || guard) return array[0];
460 | return _.initial(array, array.length - n);
461 | };
462 |
463 | // Returns everything but the last entry of the array. Especially useful on
464 | // the arguments object. Passing **n** will return all the values in
465 | // the array, excluding the last N.
466 | _.initial = function(array, n, guard) {
467 | return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
468 | };
469 |
470 | // Get the last element of an array. Passing **n** will return the last N
471 | // values in the array.
472 | _.last = function(array, n, guard) {
473 | if (array == null) return void 0;
474 | if (n == null || guard) return array[array.length - 1];
475 | return _.rest(array, Math.max(0, array.length - n));
476 | };
477 |
478 | // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
479 | // Especially useful on the arguments object. Passing an **n** will return
480 | // the rest N values in the array.
481 | _.rest = _.tail = _.drop = function(array, n, guard) {
482 | return slice.call(array, n == null || guard ? 1 : n);
483 | };
484 |
485 | // Trim out all falsy values from an array.
486 | _.compact = function(array) {
487 | return _.filter(array, _.identity);
488 | };
489 |
490 | // Internal implementation of a recursive `flatten` function.
491 | var flatten = function(input, shallow, strict, startIndex) {
492 | var output = [], idx = 0;
493 | for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
494 | var value = input[i];
495 | if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
496 | //flatten current level of array or arguments object
497 | if (!shallow) value = flatten(value, shallow, strict);
498 | var j = 0, len = value.length;
499 | output.length += len;
500 | while (j < len) {
501 | output[idx++] = value[j++];
502 | }
503 | } else if (!strict) {
504 | output[idx++] = value;
505 | }
506 | }
507 | return output;
508 | };
509 |
510 | // Flatten out an array, either recursively (by default), or just one level.
511 | _.flatten = function(array, shallow) {
512 | return flatten(array, shallow, false);
513 | };
514 |
515 | // Return a version of the array that does not contain the specified value(s).
516 | _.without = function(array) {
517 | return _.difference(array, slice.call(arguments, 1));
518 | };
519 |
520 | // Produce a duplicate-free version of the array. If the array has already
521 | // been sorted, you have the option of using a faster algorithm.
522 | // Aliased as `unique`.
523 | _.uniq = _.unique = function(array, isSorted, iteratee, context) {
524 | if (!_.isBoolean(isSorted)) {
525 | context = iteratee;
526 | iteratee = isSorted;
527 | isSorted = false;
528 | }
529 | if (iteratee != null) iteratee = cb(iteratee, context);
530 | var result = [];
531 | var seen = [];
532 | for (var i = 0, length = getLength(array); i < length; i++) {
533 | var value = array[i],
534 | computed = iteratee ? iteratee(value, i, array) : value;
535 | if (isSorted) {
536 | if (!i || seen !== computed) result.push(value);
537 | seen = computed;
538 | } else if (iteratee) {
539 | if (!_.contains(seen, computed)) {
540 | seen.push(computed);
541 | result.push(value);
542 | }
543 | } else if (!_.contains(result, value)) {
544 | result.push(value);
545 | }
546 | }
547 | return result;
548 | };
549 |
550 | // Produce an array that contains the union: each distinct element from all of
551 | // the passed-in arrays.
552 | _.union = function() {
553 | return _.uniq(flatten(arguments, true, true));
554 | };
555 |
556 | // Produce an array that contains every item shared between all the
557 | // passed-in arrays.
558 | _.intersection = function(array) {
559 | var result = [];
560 | var argsLength = arguments.length;
561 | for (var i = 0, length = getLength(array); i < length; i++) {
562 | var item = array[i];
563 | if (_.contains(result, item)) continue;
564 | for (var j = 1; j < argsLength; j++) {
565 | if (!_.contains(arguments[j], item)) break;
566 | }
567 | if (j === argsLength) result.push(item);
568 | }
569 | return result;
570 | };
571 |
572 | // Take the difference between one array and a number of other arrays.
573 | // Only the elements present in just the first array will remain.
574 | _.difference = function(array) {
575 | var rest = flatten(arguments, true, true, 1);
576 | return _.filter(array, function(value){
577 | return !_.contains(rest, value);
578 | });
579 | };
580 |
581 | // Zip together multiple lists into a single array -- elements that share
582 | // an index go together.
583 | _.zip = function() {
584 | return _.unzip(arguments);
585 | };
586 |
587 | // Complement of _.zip. Unzip accepts an array of arrays and groups
588 | // each array's elements on shared indices
589 | _.unzip = function(array) {
590 | var length = array && _.max(array, getLength).length || 0;
591 | var result = Array(length);
592 |
593 | for (var index = 0; index < length; index++) {
594 | result[index] = _.pluck(array, index);
595 | }
596 | return result;
597 | };
598 |
599 | // Converts lists into objects. Pass either a single array of `[key, value]`
600 | // pairs, or two parallel arrays of the same length -- one of keys, and one of
601 | // the corresponding values.
602 | _.object = function(list, values) {
603 | var result = {};
604 | for (var i = 0, length = getLength(list); i < length; i++) {
605 | if (values) {
606 | result[list[i]] = values[i];
607 | } else {
608 | result[list[i][0]] = list[i][1];
609 | }
610 | }
611 | return result;
612 | };
613 |
614 | // Generator function to create the findIndex and findLastIndex functions
615 | function createPredicateIndexFinder(dir) {
616 | return function(array, predicate, context) {
617 | predicate = cb(predicate, context);
618 | var length = getLength(array);
619 | var index = dir > 0 ? 0 : length - 1;
620 | for (; index >= 0 && index < length; index += dir) {
621 | if (predicate(array[index], index, array)) return index;
622 | }
623 | return -1;
624 | };
625 | }
626 |
627 | // Returns the first index on an array-like that passes a predicate test
628 | _.findIndex = createPredicateIndexFinder(1);
629 | _.findLastIndex = createPredicateIndexFinder(-1);
630 |
631 | // Use a comparator function to figure out the smallest index at which
632 | // an object should be inserted so as to maintain order. Uses binary search.
633 | _.sortedIndex = function(array, obj, iteratee, context) {
634 | iteratee = cb(iteratee, context, 1);
635 | var value = iteratee(obj);
636 | var low = 0, high = getLength(array);
637 | while (low < high) {
638 | var mid = Math.floor((low + high) / 2);
639 | if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
640 | }
641 | return low;
642 | };
643 |
644 | // Generator function to create the indexOf and lastIndexOf functions
645 | function createIndexFinder(dir, predicateFind, sortedIndex) {
646 | return function(array, item, idx) {
647 | var i = 0, length = getLength(array);
648 | if (typeof idx == 'number') {
649 | if (dir > 0) {
650 | i = idx >= 0 ? idx : Math.max(idx + length, i);
651 | } else {
652 | length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
653 | }
654 | } else if (sortedIndex && idx && length) {
655 | idx = sortedIndex(array, item);
656 | return array[idx] === item ? idx : -1;
657 | }
658 | if (item !== item) {
659 | idx = predicateFind(slice.call(array, i, length), _.isNaN);
660 | return idx >= 0 ? idx + i : -1;
661 | }
662 | for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
663 | if (array[idx] === item) return idx;
664 | }
665 | return -1;
666 | };
667 | }
668 |
669 | // Return the position of the first occurrence of an item in an array,
670 | // or -1 if the item is not included in the array.
671 | // If the array is large and already in sort order, pass `true`
672 | // for **isSorted** to use binary search.
673 | _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
674 | _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
675 |
676 | // Generate an integer Array containing an arithmetic progression. A port of
677 | // the native Python `range()` function. See
678 | // [the Python documentation](http://docs.python.org/library/functions.html#range).
679 | _.range = function(start, stop, step) {
680 | if (stop == null) {
681 | stop = start || 0;
682 | start = 0;
683 | }
684 | step = step || 1;
685 |
686 | var length = Math.max(Math.ceil((stop - start) / step), 0);
687 | var range = Array(length);
688 |
689 | for (var idx = 0; idx < length; idx++, start += step) {
690 | range[idx] = start;
691 | }
692 |
693 | return range;
694 | };
695 |
696 | // Function (ahem) Functions
697 | // ------------------
698 |
699 | // Determines whether to execute a function as a constructor
700 | // or a normal function with the provided arguments
701 | var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
702 | if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
703 | var self = baseCreate(sourceFunc.prototype);
704 | var result = sourceFunc.apply(self, args);
705 | if (_.isObject(result)) return result;
706 | return self;
707 | };
708 |
709 | // Create a function bound to a given object (assigning `this`, and arguments,
710 | // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
711 | // available.
712 | _.bind = function(func, context) {
713 | if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
714 | if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
715 | var args = slice.call(arguments, 2);
716 | var bound = function() {
717 | return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
718 | };
719 | return bound;
720 | };
721 |
722 | // Partially apply a function by creating a version that has had some of its
723 | // arguments pre-filled, without changing its dynamic `this` context. _ acts
724 | // as a placeholder, allowing any combination of arguments to be pre-filled.
725 | _.partial = function(func) {
726 | var boundArgs = slice.call(arguments, 1);
727 | var bound = function() {
728 | var position = 0, length = boundArgs.length;
729 | var args = Array(length);
730 | for (var i = 0; i < length; i++) {
731 | args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
732 | }
733 | while (position < arguments.length) args.push(arguments[position++]);
734 | return executeBound(func, bound, this, this, args);
735 | };
736 | return bound;
737 | };
738 |
739 | // Bind a number of an object's methods to that object. Remaining arguments
740 | // are the method names to be bound. Useful for ensuring that all callbacks
741 | // defined on an object belong to it.
742 | _.bindAll = function(obj) {
743 | var i, length = arguments.length, key;
744 | if (length <= 1) throw new Error('bindAll must be passed function names');
745 | for (i = 1; i < length; i++) {
746 | key = arguments[i];
747 | obj[key] = _.bind(obj[key], obj);
748 | }
749 | return obj;
750 | };
751 |
752 | // Memoize an expensive function by storing its results.
753 | _.memoize = function(func, hasher) {
754 | var memoize = function(key) {
755 | var cache = memoize.cache;
756 | var address = '' + (hasher ? hasher.apply(this, arguments) : key);
757 | if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
758 | return cache[address];
759 | };
760 | memoize.cache = {};
761 | return memoize;
762 | };
763 |
764 | // Delays a function for the given number of milliseconds, and then calls
765 | // it with the arguments supplied.
766 | _.delay = function(func, wait) {
767 | var args = slice.call(arguments, 2);
768 | return setTimeout(function(){
769 | return func.apply(null, args);
770 | }, wait);
771 | };
772 |
773 | // Defers a function, scheduling it to run after the current call stack has
774 | // cleared.
775 | _.defer = _.partial(_.delay, _, 1);
776 |
777 | // Returns a function, that, when invoked, will only be triggered at most once
778 | // during a given window of time. Normally, the throttled function will run
779 | // as much as it can, without ever going more than once per `wait` duration;
780 | // but if you'd like to disable the execution on the leading edge, pass
781 | // `{leading: false}`. To disable execution on the trailing edge, ditto.
782 | _.throttle = function(func, wait, options) {
783 | var context, args, result;
784 | var timeout = null;
785 | var previous = 0;
786 | if (!options) options = {};
787 | var later = function() {
788 | previous = options.leading === false ? 0 : _.now();
789 | timeout = null;
790 | result = func.apply(context, args);
791 | if (!timeout) context = args = null;
792 | };
793 | return function() {
794 | var now = _.now();
795 | if (!previous && options.leading === false) previous = now;
796 | var remaining = wait - (now - previous);
797 | context = this;
798 | args = arguments;
799 | if (remaining <= 0 || remaining > wait) {
800 | if (timeout) {
801 | clearTimeout(timeout);
802 | timeout = null;
803 | }
804 | previous = now;
805 | result = func.apply(context, args);
806 | if (!timeout) context = args = null;
807 | } else if (!timeout && options.trailing !== false) {
808 | timeout = setTimeout(later, remaining);
809 | }
810 | return result;
811 | };
812 | };
813 |
814 | // Returns a function, that, as long as it continues to be invoked, will not
815 | // be triggered. The function will be called after it stops being called for
816 | // N milliseconds. If `immediate` is passed, trigger the function on the
817 | // leading edge, instead of the trailing.
818 | _.debounce = function(func, wait, immediate) {
819 | var timeout, args, context, timestamp, result;
820 |
821 | var later = function() {
822 | var last = _.now() - timestamp;
823 |
824 | if (last < wait && last >= 0) {
825 | timeout = setTimeout(later, wait - last);
826 | } else {
827 | timeout = null;
828 | if (!immediate) {
829 | result = func.apply(context, args);
830 | if (!timeout) context = args = null;
831 | }
832 | }
833 | };
834 |
835 | return function() {
836 | context = this;
837 | args = arguments;
838 | timestamp = _.now();
839 | var callNow = immediate && !timeout;
840 | if (!timeout) timeout = setTimeout(later, wait);
841 | if (callNow) {
842 | result = func.apply(context, args);
843 | context = args = null;
844 | }
845 |
846 | return result;
847 | };
848 | };
849 |
850 | // Returns the first function passed as an argument to the second,
851 | // allowing you to adjust arguments, run code before and after, and
852 | // conditionally execute the original function.
853 | _.wrap = function(func, wrapper) {
854 | return _.partial(wrapper, func);
855 | };
856 |
857 | // Returns a negated version of the passed-in predicate.
858 | _.negate = function(predicate) {
859 | return function() {
860 | return !predicate.apply(this, arguments);
861 | };
862 | };
863 |
864 | // Returns a function that is the composition of a list of functions, each
865 | // consuming the return value of the function that follows.
866 | _.compose = function() {
867 | var args = arguments;
868 | var start = args.length - 1;
869 | return function() {
870 | var i = start;
871 | var result = args[start].apply(this, arguments);
872 | while (i--) result = args[i].call(this, result);
873 | return result;
874 | };
875 | };
876 |
877 | // Returns a function that will only be executed on and after the Nth call.
878 | _.after = function(times, func) {
879 | return function() {
880 | if (--times < 1) {
881 | return func.apply(this, arguments);
882 | }
883 | };
884 | };
885 |
886 | // Returns a function that will only be executed up to (but not including) the Nth call.
887 | _.before = function(times, func) {
888 | var memo;
889 | return function() {
890 | if (--times > 0) {
891 | memo = func.apply(this, arguments);
892 | }
893 | if (times <= 1) func = null;
894 | return memo;
895 | };
896 | };
897 |
898 | // Returns a function that will be executed at most one time, no matter how
899 | // often you call it. Useful for lazy initialization.
900 | _.once = _.partial(_.before, 2);
901 |
902 | // Object Functions
903 | // ----------------
904 |
905 | // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
906 | var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
907 | var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
908 | 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
909 |
910 | function collectNonEnumProps(obj, keys) {
911 | var nonEnumIdx = nonEnumerableProps.length;
912 | var constructor = obj.constructor;
913 | var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
914 |
915 | // Constructor is a special case.
916 | var prop = 'constructor';
917 | if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
918 |
919 | while (nonEnumIdx--) {
920 | prop = nonEnumerableProps[nonEnumIdx];
921 | if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
922 | keys.push(prop);
923 | }
924 | }
925 | }
926 |
927 | // Retrieve the names of an object's own properties.
928 | // Delegates to **ECMAScript 5**'s native `Object.keys`
929 | _.keys = function(obj) {
930 | if (!_.isObject(obj)) return [];
931 | if (nativeKeys) return nativeKeys(obj);
932 | var keys = [];
933 | for (var key in obj) if (_.has(obj, key)) keys.push(key);
934 | // Ahem, IE < 9.
935 | if (hasEnumBug) collectNonEnumProps(obj, keys);
936 | return keys;
937 | };
938 |
939 | // Retrieve all the property names of an object.
940 | _.allKeys = function(obj) {
941 | if (!_.isObject(obj)) return [];
942 | var keys = [];
943 | for (var key in obj) keys.push(key);
944 | // Ahem, IE < 9.
945 | if (hasEnumBug) collectNonEnumProps(obj, keys);
946 | return keys;
947 | };
948 |
949 | // Retrieve the values of an object's properties.
950 | _.values = function(obj) {
951 | var keys = _.keys(obj);
952 | var length = keys.length;
953 | var values = Array(length);
954 | for (var i = 0; i < length; i++) {
955 | values[i] = obj[keys[i]];
956 | }
957 | return values;
958 | };
959 |
960 | // Returns the results of applying the iteratee to each element of the object
961 | // In contrast to _.map it returns an object
962 | _.mapObject = function(obj, iteratee, context) {
963 | iteratee = cb(iteratee, context);
964 | var keys = _.keys(obj),
965 | length = keys.length,
966 | results = {},
967 | currentKey;
968 | for (var index = 0; index < length; index++) {
969 | currentKey = keys[index];
970 | results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
971 | }
972 | return results;
973 | };
974 |
975 | // Convert an object into a list of `[key, value]` pairs.
976 | _.pairs = function(obj) {
977 | var keys = _.keys(obj);
978 | var length = keys.length;
979 | var pairs = Array(length);
980 | for (var i = 0; i < length; i++) {
981 | pairs[i] = [keys[i], obj[keys[i]]];
982 | }
983 | return pairs;
984 | };
985 |
986 | // Invert the keys and values of an object. The values must be serializable.
987 | _.invert = function(obj) {
988 | var result = {};
989 | var keys = _.keys(obj);
990 | for (var i = 0, length = keys.length; i < length; i++) {
991 | result[obj[keys[i]]] = keys[i];
992 | }
993 | return result;
994 | };
995 |
996 | // Return a sorted list of the function names available on the object.
997 | // Aliased as `methods`
998 | _.functions = _.methods = function(obj) {
999 | var names = [];
1000 | for (var key in obj) {
1001 | if (_.isFunction(obj[key])) names.push(key);
1002 | }
1003 | return names.sort();
1004 | };
1005 |
1006 | // Extend a given object with all the properties in passed-in object(s).
1007 | _.extend = createAssigner(_.allKeys);
1008 |
1009 | // Assigns a given object with all the own properties in the passed-in object(s)
1010 | // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
1011 | _.extendOwn = _.assign = createAssigner(_.keys);
1012 |
1013 | // Returns the first key on an object that passes a predicate test
1014 | _.findKey = function(obj, predicate, context) {
1015 | predicate = cb(predicate, context);
1016 | var keys = _.keys(obj), key;
1017 | for (var i = 0, length = keys.length; i < length; i++) {
1018 | key = keys[i];
1019 | if (predicate(obj[key], key, obj)) return key;
1020 | }
1021 | };
1022 |
1023 | // Return a copy of the object only containing the whitelisted properties.
1024 | _.pick = function(object, oiteratee, context) {
1025 | var result = {}, obj = object, iteratee, keys;
1026 | if (obj == null) return result;
1027 | if (_.isFunction(oiteratee)) {
1028 | keys = _.allKeys(obj);
1029 | iteratee = optimizeCb(oiteratee, context);
1030 | } else {
1031 | keys = flatten(arguments, false, false, 1);
1032 | iteratee = function(value, key, obj) { return key in obj; };
1033 | obj = Object(obj);
1034 | }
1035 | for (var i = 0, length = keys.length; i < length; i++) {
1036 | var key = keys[i];
1037 | var value = obj[key];
1038 | if (iteratee(value, key, obj)) result[key] = value;
1039 | }
1040 | return result;
1041 | };
1042 |
1043 | // Return a copy of the object without the blacklisted properties.
1044 | _.omit = function(obj, iteratee, context) {
1045 | if (_.isFunction(iteratee)) {
1046 | iteratee = _.negate(iteratee);
1047 | } else {
1048 | var keys = _.map(flatten(arguments, false, false, 1), String);
1049 | iteratee = function(value, key) {
1050 | return !_.contains(keys, key);
1051 | };
1052 | }
1053 | return _.pick(obj, iteratee, context);
1054 | };
1055 |
1056 | // Fill in a given object with default properties.
1057 | _.defaults = createAssigner(_.allKeys, true);
1058 |
1059 | // Creates an object that inherits from the given prototype object.
1060 | // If additional properties are provided then they will be added to the
1061 | // created object.
1062 | _.create = function(prototype, props) {
1063 | var result = baseCreate(prototype);
1064 | if (props) _.extendOwn(result, props);
1065 | return result;
1066 | };
1067 |
1068 | // Create a (shallow-cloned) duplicate of an object.
1069 | _.clone = function(obj) {
1070 | if (!_.isObject(obj)) return obj;
1071 | return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
1072 | };
1073 |
1074 | // Invokes interceptor with the obj, and then returns obj.
1075 | // The primary purpose of this method is to "tap into" a method chain, in
1076 | // order to perform operations on intermediate results within the chain.
1077 | _.tap = function(obj, interceptor) {
1078 | interceptor(obj);
1079 | return obj;
1080 | };
1081 |
1082 | // Returns whether an object has a given set of `key:value` pairs.
1083 | _.isMatch = function(object, attrs) {
1084 | var keys = _.keys(attrs), length = keys.length;
1085 | if (object == null) return !length;
1086 | var obj = Object(object);
1087 | for (var i = 0; i < length; i++) {
1088 | var key = keys[i];
1089 | if (attrs[key] !== obj[key] || !(key in obj)) return false;
1090 | }
1091 | return true;
1092 | };
1093 |
1094 |
1095 | // Internal recursive comparison function for `isEqual`.
1096 | var eq = function(a, b, aStack, bStack) {
1097 | // Identical objects are equal. `0 === -0`, but they aren't identical.
1098 | // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
1099 | if (a === b) return a !== 0 || 1 / a === 1 / b;
1100 | // A strict comparison is necessary because `null == undefined`.
1101 | if (a == null || b == null) return a === b;
1102 | // Unwrap any wrapped objects.
1103 | if (a instanceof _) a = a._wrapped;
1104 | if (b instanceof _) b = b._wrapped;
1105 | // Compare `[[Class]]` names.
1106 | var className = toString.call(a);
1107 | if (className !== toString.call(b)) return false;
1108 | switch (className) {
1109 | // Strings, numbers, regular expressions, dates, and booleans are compared by value.
1110 | case '[object RegExp]':
1111 | // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
1112 | case '[object String]':
1113 | // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
1114 | // equivalent to `new String("5")`.
1115 | return '' + a === '' + b;
1116 | case '[object Number]':
1117 | // `NaN`s are equivalent, but non-reflexive.
1118 | // Object(NaN) is equivalent to NaN
1119 | if (+a !== +a) return +b !== +b;
1120 | // An `egal` comparison is performed for other numeric values.
1121 | return +a === 0 ? 1 / +a === 1 / b : +a === +b;
1122 | case '[object Date]':
1123 | case '[object Boolean]':
1124 | // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1125 | // millisecond representations. Note that invalid dates with millisecond representations
1126 | // of `NaN` are not equivalent.
1127 | return +a === +b;
1128 | }
1129 |
1130 | var areArrays = className === '[object Array]';
1131 | if (!areArrays) {
1132 | if (typeof a != 'object' || typeof b != 'object') return false;
1133 |
1134 | // Objects with different constructors are not equivalent, but `Object`s or `Array`s
1135 | // from different frames are.
1136 | var aCtor = a.constructor, bCtor = b.constructor;
1137 | if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
1138 | _.isFunction(bCtor) && bCtor instanceof bCtor)
1139 | && ('constructor' in a && 'constructor' in b)) {
1140 | return false;
1141 | }
1142 | }
1143 | // Assume equality for cyclic structures. The algorithm for detecting cyclic
1144 | // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1145 |
1146 | // Initializing stack of traversed objects.
1147 | // It's done here since we only need them for objects and arrays comparison.
1148 | aStack = aStack || [];
1149 | bStack = bStack || [];
1150 | var length = aStack.length;
1151 | while (length--) {
1152 | // Linear search. Performance is inversely proportional to the number of
1153 | // unique nested structures.
1154 | if (aStack[length] === a) return bStack[length] === b;
1155 | }
1156 |
1157 | // Add the first object to the stack of traversed objects.
1158 | aStack.push(a);
1159 | bStack.push(b);
1160 |
1161 | // Recursively compare objects and arrays.
1162 | if (areArrays) {
1163 | // Compare array lengths to determine if a deep comparison is necessary.
1164 | length = a.length;
1165 | if (length !== b.length) return false;
1166 | // Deep compare the contents, ignoring non-numeric properties.
1167 | while (length--) {
1168 | if (!eq(a[length], b[length], aStack, bStack)) return false;
1169 | }
1170 | } else {
1171 | // Deep compare objects.
1172 | var keys = _.keys(a), key;
1173 | length = keys.length;
1174 | // Ensure that both objects contain the same number of properties before comparing deep equality.
1175 | if (_.keys(b).length !== length) return false;
1176 | while (length--) {
1177 | // Deep compare each member
1178 | key = keys[length];
1179 | if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
1180 | }
1181 | }
1182 | // Remove the first object from the stack of traversed objects.
1183 | aStack.pop();
1184 | bStack.pop();
1185 | return true;
1186 | };
1187 |
1188 | // Perform a deep comparison to check if two objects are equal.
1189 | _.isEqual = function(a, b) {
1190 | return eq(a, b);
1191 | };
1192 |
1193 | // Is a given array, string, or object empty?
1194 | // An "empty" object has no enumerable own-properties.
1195 | _.isEmpty = function(obj) {
1196 | if (obj == null) return true;
1197 | if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
1198 | return _.keys(obj).length === 0;
1199 | };
1200 |
1201 | // Is a given value a DOM element?
1202 | _.isElement = function(obj) {
1203 | return !!(obj && obj.nodeType === 1);
1204 | };
1205 |
1206 | // Is a given value an array?
1207 | // Delegates to ECMA5's native Array.isArray
1208 | _.isArray = nativeIsArray || function(obj) {
1209 | return toString.call(obj) === '[object Array]';
1210 | };
1211 |
1212 | // Is a given variable an object?
1213 | _.isObject = function(obj) {
1214 | var type = typeof obj;
1215 | return type === 'function' || type === 'object' && !!obj;
1216 | };
1217 |
1218 | // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
1219 | _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
1220 | _['is' + name] = function(obj) {
1221 | return toString.call(obj) === '[object ' + name + ']';
1222 | };
1223 | });
1224 |
1225 | // Define a fallback version of the method in browsers (ahem, IE < 9), where
1226 | // there isn't any inspectable "Arguments" type.
1227 | if (!_.isArguments(arguments)) {
1228 | _.isArguments = function(obj) {
1229 | return _.has(obj, 'callee');
1230 | };
1231 | }
1232 |
1233 | // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
1234 | // IE 11 (#1621), and in Safari 8 (#1929).
1235 | if (typeof /./ != 'function' && typeof Int8Array != 'object') {
1236 | _.isFunction = function(obj) {
1237 | return typeof obj == 'function' || false;
1238 | };
1239 | }
1240 |
1241 | // Is a given object a finite number?
1242 | _.isFinite = function(obj) {
1243 | return isFinite(obj) && !isNaN(parseFloat(obj));
1244 | };
1245 |
1246 | // Is the given value `NaN`? (NaN is the only number which does not equal itself).
1247 | _.isNaN = function(obj) {
1248 | return _.isNumber(obj) && obj !== +obj;
1249 | };
1250 |
1251 | // Is a given value a boolean?
1252 | _.isBoolean = function(obj) {
1253 | return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
1254 | };
1255 |
1256 | // Is a given value equal to null?
1257 | _.isNull = function(obj) {
1258 | return obj === null;
1259 | };
1260 |
1261 | // Is a given variable undefined?
1262 | _.isUndefined = function(obj) {
1263 | return obj === void 0;
1264 | };
1265 |
1266 | // Shortcut function for checking if an object has a given property directly
1267 | // on itself (in other words, not on a prototype).
1268 | _.has = function(obj, key) {
1269 | return obj != null && hasOwnProperty.call(obj, key);
1270 | };
1271 |
1272 | // Utility Functions
1273 | // -----------------
1274 |
1275 | // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1276 | // previous owner. Returns a reference to the Underscore object.
1277 | _.noConflict = function() {
1278 | root._ = previousUnderscore;
1279 | return this;
1280 | };
1281 |
1282 | // Keep the identity function around for default iteratees.
1283 | _.identity = function(value) {
1284 | return value;
1285 | };
1286 |
1287 | // Predicate-generating functions. Often useful outside of Underscore.
1288 | _.constant = function(value) {
1289 | return function() {
1290 | return value;
1291 | };
1292 | };
1293 |
1294 | _.noop = function(){};
1295 |
1296 | _.property = property;
1297 |
1298 | // Generates a function for a given object that returns a given property.
1299 | _.propertyOf = function(obj) {
1300 | return obj == null ? function(){} : function(key) {
1301 | return obj[key];
1302 | };
1303 | };
1304 |
1305 | // Returns a predicate for checking whether an object has a given set of
1306 | // `key:value` pairs.
1307 | _.matcher = _.matches = function(attrs) {
1308 | attrs = _.extendOwn({}, attrs);
1309 | return function(obj) {
1310 | return _.isMatch(obj, attrs);
1311 | };
1312 | };
1313 |
1314 | // Run a function **n** times.
1315 | _.times = function(n, iteratee, context) {
1316 | var accum = Array(Math.max(0, n));
1317 | iteratee = optimizeCb(iteratee, context, 1);
1318 | for (var i = 0; i < n; i++) accum[i] = iteratee(i);
1319 | return accum;
1320 | };
1321 |
1322 | // Return a random integer between min and max (inclusive).
1323 | _.random = function(min, max) {
1324 | if (max == null) {
1325 | max = min;
1326 | min = 0;
1327 | }
1328 | return min + Math.floor(Math.random() * (max - min + 1));
1329 | };
1330 |
1331 | // A (possibly faster) way to get the current timestamp as an integer.
1332 | _.now = Date.now || function() {
1333 | return new Date().getTime();
1334 | };
1335 |
1336 | // List of HTML entities for escaping.
1337 | var escapeMap = {
1338 | '&': '&',
1339 | '<': '<',
1340 | '>': '>',
1341 | '"': '"',
1342 | "'": ''',
1343 | '`': '`'
1344 | };
1345 | var unescapeMap = _.invert(escapeMap);
1346 |
1347 | // Functions for escaping and unescaping strings to/from HTML interpolation.
1348 | var createEscaper = function(map) {
1349 | var escaper = function(match) {
1350 | return map[match];
1351 | };
1352 | // Regexes for identifying a key that needs to be escaped
1353 | var source = '(?:' + _.keys(map).join('|') + ')';
1354 | var testRegexp = RegExp(source);
1355 | var replaceRegexp = RegExp(source, 'g');
1356 | return function(string) {
1357 | string = string == null ? '' : '' + string;
1358 | return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
1359 | };
1360 | };
1361 | _.escape = createEscaper(escapeMap);
1362 | _.unescape = createEscaper(unescapeMap);
1363 |
1364 | // If the value of the named `property` is a function then invoke it with the
1365 | // `object` as context; otherwise, return it.
1366 | _.result = function(object, property, fallback) {
1367 | var value = object == null ? void 0 : object[property];
1368 | if (value === void 0) {
1369 | value = fallback;
1370 | }
1371 | return _.isFunction(value) ? value.call(object) : value;
1372 | };
1373 |
1374 | // Generate a unique integer id (unique within the entire client session).
1375 | // Useful for temporary DOM ids.
1376 | var idCounter = 0;
1377 | _.uniqueId = function(prefix) {
1378 | var id = ++idCounter + '';
1379 | return prefix ? prefix + id : id;
1380 | };
1381 |
1382 | // By default, Underscore uses ERB-style template delimiters, change the
1383 | // following template settings to use alternative delimiters.
1384 | _.templateSettings = {
1385 | evaluate : /<%([\s\S]+?)%>/g,
1386 | interpolate : /<%=([\s\S]+?)%>/g,
1387 | escape : /<%-([\s\S]+?)%>/g
1388 | };
1389 |
1390 | // When customizing `templateSettings`, if you don't want to define an
1391 | // interpolation, evaluation or escaping regex, we need one that is
1392 | // guaranteed not to match.
1393 | var noMatch = /(.)^/;
1394 |
1395 | // Certain characters need to be escaped so that they can be put into a
1396 | // string literal.
1397 | var escapes = {
1398 | "'": "'",
1399 | '\\': '\\',
1400 | '\r': 'r',
1401 | '\n': 'n',
1402 | '\u2028': 'u2028',
1403 | '\u2029': 'u2029'
1404 | };
1405 |
1406 | var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
1407 |
1408 | var escapeChar = function(match) {
1409 | return '\\' + escapes[match];
1410 | };
1411 |
1412 | // JavaScript micro-templating, similar to John Resig's implementation.
1413 | // Underscore templating handles arbitrary delimiters, preserves whitespace,
1414 | // and correctly escapes quotes within interpolated code.
1415 | // NB: `oldSettings` only exists for backwards compatibility.
1416 | _.template = function(text, settings, oldSettings) {
1417 | if (!settings && oldSettings) settings = oldSettings;
1418 | settings = _.defaults({}, settings, _.templateSettings);
1419 |
1420 | // Combine delimiters into one regular expression via alternation.
1421 | var matcher = RegExp([
1422 | (settings.escape || noMatch).source,
1423 | (settings.interpolate || noMatch).source,
1424 | (settings.evaluate || noMatch).source
1425 | ].join('|') + '|$', 'g');
1426 |
1427 | // Compile the template source, escaping string literals appropriately.
1428 | var index = 0;
1429 | var source = "__p+='";
1430 | text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
1431 | source += text.slice(index, offset).replace(escaper, escapeChar);
1432 | index = offset + match.length;
1433 |
1434 | if (escape) {
1435 | source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
1436 | } else if (interpolate) {
1437 | source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
1438 | } else if (evaluate) {
1439 | source += "';\n" + evaluate + "\n__p+='";
1440 | }
1441 |
1442 | // Adobe VMs need the match returned to produce the correct offest.
1443 | return match;
1444 | });
1445 | source += "';\n";
1446 |
1447 | // If a variable is not specified, place data values in local scope.
1448 | if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
1449 |
1450 | source = "var __t,__p='',__j=Array.prototype.join," +
1451 | "print=function(){__p+=__j.call(arguments,'');};\n" +
1452 | source + 'return __p;\n';
1453 |
1454 | try {
1455 | var render = new Function(settings.variable || 'obj', '_', source);
1456 | } catch (e) {
1457 | e.source = source;
1458 | throw e;
1459 | }
1460 |
1461 | var template = function(data) {
1462 | return render.call(this, data, _);
1463 | };
1464 |
1465 | // Provide the compiled source as a convenience for precompilation.
1466 | var argument = settings.variable || 'obj';
1467 | template.source = 'function(' + argument + '){\n' + source + '}';
1468 |
1469 | return template;
1470 | };
1471 |
1472 | // Add a "chain" function. Start chaining a wrapped Underscore object.
1473 | _.chain = function(obj) {
1474 | var instance = _(obj);
1475 | instance._chain = true;
1476 | return instance;
1477 | };
1478 |
1479 | // OOP
1480 | // ---------------
1481 | // If Underscore is called as a function, it returns a wrapped object that
1482 | // can be used OO-style. This wrapper holds altered versions of all the
1483 | // underscore functions. Wrapped objects may be chained.
1484 |
1485 | // Helper function to continue chaining intermediate results.
1486 | var result = function(instance, obj) {
1487 | return instance._chain ? _(obj).chain() : obj;
1488 | };
1489 |
1490 | // Add your own custom functions to the Underscore object.
1491 | _.mixin = function(obj) {
1492 | _.each(_.functions(obj), function(name) {
1493 | var func = _[name] = obj[name];
1494 | _.prototype[name] = function() {
1495 | var args = [this._wrapped];
1496 | push.apply(args, arguments);
1497 | return result(this, func.apply(_, args));
1498 | };
1499 | });
1500 | };
1501 |
1502 | // Add all of the Underscore functions to the wrapper object.
1503 | _.mixin(_);
1504 |
1505 | // Add all mutator Array functions to the wrapper.
1506 | _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1507 | var method = ArrayProto[name];
1508 | _.prototype[name] = function() {
1509 | var obj = this._wrapped;
1510 | method.apply(obj, arguments);
1511 | if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
1512 | return result(this, obj);
1513 | };
1514 | });
1515 |
1516 | // Add all accessor Array functions to the wrapper.
1517 | _.each(['concat', 'join', 'slice'], function(name) {
1518 | var method = ArrayProto[name];
1519 | _.prototype[name] = function() {
1520 | return result(this, method.apply(this._wrapped, arguments));
1521 | };
1522 | });
1523 |
1524 | // Extracts the result from a wrapped and chained object.
1525 | _.prototype.value = function() {
1526 | return this._wrapped;
1527 | };
1528 |
1529 | // Provide unwrapping proxy for some methods used in engine operations
1530 | // such as arithmetic and JSON stringification.
1531 | _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
1532 |
1533 | _.prototype.toString = function() {
1534 | return '' + this._wrapped;
1535 | };
1536 |
1537 | // AMD registration happens at the end for compatibility with AMD loaders
1538 | // that may not enforce next-turn semantics on modules. Even though general
1539 | // practice for AMD registration is to be anonymous, underscore registers
1540 | // as a named module because, like jQuery, it is a base library that is
1541 | // popular enough to be bundled in a third party lib, but not be part of
1542 | // an AMD load request. Those cases could generate an error when an
1543 | // anonymous define() is called outside of a loader request.
1544 | if (typeof define === 'function' && define.amd) {
1545 | define('underscore', [], function() {
1546 | return _;
1547 | });
1548 | }
1549 | }.call(this));
1550 |
1551 | },{}],2:[function(require,module,exports){
1552 | var _, checkboxReplace;
1553 |
1554 | _ = require('underscore');
1555 |
1556 | checkboxReplace = function(md, options, Token) {
1557 | "use strict";
1558 | var arrayReplaceAt, createTokens, defaults, lastId, pattern, splitTextToken;
1559 | arrayReplaceAt = md.utils.arrayReplaceAt;
1560 | lastId = 0;
1561 | defaults = {
1562 | divWrap: false,
1563 | divClass: 'checkbox',
1564 | idPrefix: 'checkbox'
1565 | };
1566 | options = _.extend(defaults, options);
1567 | pattern = /\[(X|\s|\_|\-)\]\s(.*)/i;
1568 | createTokens = function(checked, label, Token) {
1569 | var id, nodes, token;
1570 | nodes = [];
1571 |
1572 | /**
1573 | *
1574 | */
1575 | if (options.divWrap) {
1576 | token = new Token("checkbox_open", "div", 1);
1577 | token.attrs = [["class", options.divClass]];
1578 | nodes.push(token);
1579 | }
1580 |
1581 | /**
1582 | *
1583 | */
1584 | id = options.idPrefix + lastId;
1585 | lastId += 1;
1586 | token = new Token("checkbox_input", "input", 0);
1587 | token.attrs = [["type", "checkbox"], ["id", id]];
1588 | if (checked === true) {
1589 | token.attrs.push(["checked", "true"]);
1590 | }
1591 | nodes.push(token);
1592 |
1593 | /**
1594 | *