diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8e5962e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+out
+node_modules
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..c821977
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,16 @@
+// A launch configuration that compiles the extension and then opens it inside a new window
+{
+ "version": "0.1.0",
+ "configurations": [
+ {
+ "name": "Launch Extension",
+ "type": "extensionHost",
+ "runtimeExecutable": "${execPath}",
+ "args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
+ "stopOnEntry": false,
+ "sourceMaps": true,
+ "outDir": "out",
+ "preLaunchTask": "npm"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..d9e74db
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+// Place your settings in this file to overwrite default and user settings.
+{
+ "spellMD.enable": true,
+ "files.exclude": {
+ "out": false // set this to true to hide the "out" folder with the compiled JS files
+ }
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..7c53714
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,30 @@
+// Available variables which can be used inside of strings.
+// ${workspaceRoot}: the root folder of the team
+// ${file}: the current opened file
+// ${fileBasename}: the current opened file's basename
+// ${fileDirname}: the current opened file's dirname
+// ${fileExtname}: the current opened file's extension
+// ${cwd}: the current working directory of the spawned process
+
+// A task runner that calls a custom npm script that compiles the extension.
+{
+ "version": "0.1.0",
+
+ // we want to run npm
+ "command": "npm",
+
+ // the command is a shell script
+ "isShellCommand": true,
+
+ // show the output window only if unrecognized errors occur.
+ "showOutput": "silent",
+
+ // we run the custom script "compile" as defined in package.json
+ "args": ["run", "compile"],
+
+ // The tsc compiler is started in watching mode
+ "isWatching": true,
+
+ // use the standard tsc in watch mode problem matcher to find compile problems in the output.
+ "problemMatcher": "$tsc-watch"
+}
\ No newline at end of file
diff --git a/.vscodeignore b/.vscodeignore
new file mode 100644
index 0000000..0fe46dd
--- /dev/null
+++ b/.vscodeignore
@@ -0,0 +1,6 @@
+.vscode/**
+typings/**
+**/*.ts
+.gitignore
+tsconfig.json
+vsc-extension-quickstart.md
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7c2b864
--- /dev/null
+++ b/README.md
@@ -0,0 +1,52 @@
+# README
+
+This extension does the following:
+
+## WordCount File Watcher
+Whenever a `markdown` file is loaded a status bar message is added which includes the current word count - this live updates as you type and move from file to file:
+
+![Status](images/StatusWordCount.gif)
+
+### Issues: Word Count
+the events for opening and closing a file don't seam to fire predictably:
+
+Repro:
+1. run extension
+2. open a folder w/ moced filed
+3. open a `.md` file status bar _may_ activate
+4. once activzated navigate to another file e.g. `.js`
+5. status bar stay stay active
+6. navigate to another `.md` status bar will probably activate but may have a stale count
+
+## Keybinding 'Alt+T' - Test Tools
+Also available as `command`.
+
+Hit `Alt+T` to get some text replacement tools e.g.
+* toUpper
+* toLower
+* Reverse
+* HTML Encode
+* ..
+
+![Tools](images/commands.gif)
+
+Will replace all selections in the current editor.
+
+### Issues: Ugly Code
+Lots of copy and paste can abstract [my] common code.
+
+### Issues: Encode HTML
+This function will replace the selection(s) with more text than they had orriginally e.g.
+
+* `hello
world`
+* Results in `hello >div< world`
+
+In the code I attempt to handle this with some simple re-writing of the selection range from the replacement `txt.length`. However the resulting selection is much longer.
+
+Repro:
+1. Open a doc
+2. select some text w/ html in it
+3. `Alt+T' select Encode HTML
+4. Resulting selection will be to long and the status bar indication of 'selected' will be incorrect
+
+I see some debug style output in the console for sections as well.
\ No newline at end of file
diff --git a/extension.ts b/extension.ts
new file mode 100644
index 0000000..65b2ad4
--- /dev/null
+++ b/extension.ts
@@ -0,0 +1,220 @@
+import * as vscode from 'vscode';
+
+import window = vscode.window;
+import workspace = vscode.workspace;
+import EditorOptions = vscode.TextEditorOptions;
+import QuickPickItem = vscode.QuickPickItem;
+import QuickPickOptions = vscode.QuickPickOptions;
+import Document = vscode.TextDocument;
+import Position = vscode.Position;
+import Range = vscode.Range;
+import InputBoxOptions = vscode.InputBoxOptions;
+
+import us = require('underscore.string');
+
+
+export function activate() {
+ console.log('Congratulations, your extension "TextTools" is now active!');
+
+ let wordCountStatus = new WordCountStatus();
+
+ vscode.commands.registerCommand('extension.textFunctions', textFunctions);
+}
+
+
+
+// Word Count /////////////////////////////////////
+class WordCountStatus {
+ constructor() {
+ window.onDidChangeTextEditorSelection((textEditor) => {
+ if (!textEditor) {
+ // No more open editors
+ return;
+ }
+ let doc = textEditor.textEditor.getTextDocument();
+
+ // Only update status if an MD file
+ if (doc.getLanguageId() === "markdown") {
+ window.setStatusBarMessage("Word Count [" + calcWordCount(doc.getText()) + "]");
+ } else {
+ window.setStatusBarMessage("");
+ }
+
+ });
+ }
+}
+
+function calcWordCount(text): number {
+ text = text.replace(/(< ([^>]+)<)/g, '').replace(/\s+/g, ' ');
+ text = text.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+
+ return text.split(" ").length;
+}
+
+// Selections test /////////////////////////////////////
+function workWithSelections() {
+ var e = window.getActiveTextEditor();
+ var d = e.getTextDocument();
+
+ // Subset of text
+ var start = new Position(1, 1);
+ var end = new Position(10, 3);
+ var range = new Range(start, end);
+ console.log("Range: " + d.getTextInRange(range));
+
+ // All text
+ console.log("All: " + d.getText());
+}
+
+// String Functions Helper//////////////////////////////
+function toUpper(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
+ // itterate through the elections and convert all text to Upper
+ for (var x = 0; x < sel.length; x++) {
+ e.edit(function(edit) {
+ let txt: string = d.getTextInRange(new Range(sel[x].start, sel[x].end));
+ edit.replace(sel[x], txt.toUpperCase());
+ });
+ e.setSelections(sel)
+ }
+}
+
+function toLower(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
+ // itterate through the elections and convert all text to Upper
+ for (var x = 0; x < sel.length; x++) {
+ e.edit(function(edit) {
+ let txt: string = d.getTextInRange(new Range(sel[x].start, sel[x].end));
+ edit.replace(sel[x], txt.toLowerCase());
+ });
+ e.setSelections(sel)
+ }
+}
+
+function swapCase(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
+ // itterate through the elections and convert all text to Upper
+ for (var x = 0; x < sel.length; x++) {
+ e.edit(function(edit) {
+ let txt: string = d.getTextInRange(new Range(sel[x].start, sel[x].end));
+ edit.replace(sel[x], us.swapCase(txt));
+ });
+ e.setSelections(sel)
+ }
+}
+
+
+function cleanString(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
+ // itterate through the elections and convert all text to Upper
+ for (var x = 0; x < sel.length; x++) {
+ e.edit(function(edit) {
+ let txt: string = d.getTextInRange(new Range(sel[x].start, sel[x].end));
+ edit.replace(sel[x], us.clean(txt));
+ });
+ e.setSelections(sel)
+ }
+}
+
+
+function titleize(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
+ // itterate through the elections and convert all text to Upper
+ for (var x = 0; x < sel.length; x++) {
+ e.edit(function(edit) {
+ let txt: string = d.getTextInRange(new Range(sel[x].start, sel[x].end));
+ edit.replace(sel[x], us.titleize(txt));
+ });
+ e.setSelections(sel)
+ }
+}
+
+function escapeHTML(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
+ // itterate through the selections
+ for (var x = 0; x < sel.length; x++) {
+ e.edit(function(edit) {
+ // process the selection and replace in editor
+ var txt: string = us.escapeHTML(d.getTextInRange(new Range(sel[x].start, sel[x].end)));
+ edit.replace(sel[x], txt);
+
+ // fix the selection as it could now be longer or shorter
+ let startPos: Position = new Position(sel[x].start.line, sel[x].start.column);
+ let endPos: Position = new Position(sel[x].end.line,sel[x].start.column + txt.length);
+ let replaceRange : Range = new Range(startPos, endPos);
+
+ e.setSelection(replaceRange);
+ });
+ }
+}
+
+function unescapeHTML(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
+ // itterate through the elections and convert all text to Upper
+ for (var x = 0; x < sel.length; x++) {
+ e.edit(function(edit) {
+ let txt: string = d.getTextInRange(new Range(sel[x].start, sel[x].end));
+ edit.replace(sel[x], us.unescapeHTML(txt));
+ });
+ e.setSelections(sel)
+ }
+}
+
+function reverse(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
+ // itterate through the elections and convert all text to Upper
+ for (var x = 0; x < sel.length; x++) {
+ e.edit(function(edit) {
+ edit.replace(sel[x], us.reverse(d.getTextInRange(new Range(sel[x].start, sel[x].end))));
+ });
+ e.setSelections(sel)
+ }
+}
+
+// Text Functions /////////////////////////////////////
+function textFunctions() {
+ var opts: QuickPickOptions = { matchOnDescription: true, placeHolder: "What do you want to do to the selection(s)?" };
+
+ var items: QuickPickItem[] = [];
+ items.push({ label: "toUpper", description: "Convert [aBc] to [ABC]" });
+ items.push({ label: "toLower", description: "Convert [aBc] to [abc]" });
+ items.push({ label: "swapCase", description: "Convert [aBc] to [AbC]" });
+ items.push({ label: "Titleize", description: "Convert [hello world] to [Hello World]" });
+ items.push({ label: "Clean String", description: "Convert [hello world] to [hello world]" });
+ items.push({ label: "Reverse", description: "Convert [hello world] to [world hello]" });
+ items.push({ label: "Escape HTML", description: "Convert [
hello] to [<div>hello]" });
+ items.push({ label: "UnEscape HTML", description: "Convert [<div>hello] to [
hello]" });
+
+
+ window.showQuickPick(items).then((selection) => {
+ let e = window.getActiveTextEditor();
+ let d = e.getTextDocument();
+ let sel = e.getSelections();
+
+ switch (selection.label) {
+ case "toUpper":
+ toUpper(e, d, sel);
+ break;
+ case "toLower":
+ toLower(e, d, sel);
+ break;
+ case "swapCase":
+ swapCase(e, d, sel);
+ break;
+ case "Titleize":
+ titleize(e, d, sel);
+ break;
+ case "Clean String":
+ cleanString(e, d, sel);
+ break;
+ case "Reverse":
+ reverse(e, d, sel);
+ break;
+ case "Escape HTML":
+ escapeHTML(e, d, sel);
+ break;
+ case "UnEscape HTML":
+ unescapeHTML(e, d, sel);
+ break;
+ default:
+ console.log("hum this should not have happend - no selction")
+ break;
+ }
+
+ });
+}
+
+
+
diff --git a/images/Commands.gif b/images/Commands.gif
new file mode 100644
index 0000000..cba72e7
Binary files /dev/null and b/images/Commands.gif differ
diff --git a/images/StatusWordCount.gif b/images/StatusWordCount.gif
new file mode 100644
index 0000000..8f1bb08
Binary files /dev/null and b/images/StatusWordCount.gif differ
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..1310aa4
--- /dev/null
+++ b/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "30-Command",
+ "version": "0.0.1",
+ "publisher": "Sean",
+ "activationEvents": [
+ "onLanguage:markdown"
+ ],
+ "engines": {
+ "vscode": ">=0.9.0-pre.1"
+ },
+ "main": "./out/extension",
+ "contributes": {
+ "commands": [
+ {
+ "command": "extension.textFunctions",
+ "title": "Text Functions",
+ "description": "Text Functions on selections"
+ }
+ ],
+ "keybindings": [
+ {
+ "command": "extension.textFunctions",
+ "key": "Alt+T"
+ }
+ ]
+ },
+ "scripts": {
+ "vscode:prepublish": "node ./node_modules/vscode/bin/compile",
+ "compile": "node ./node_modules/vscode/bin/compile -watch -p ./"
+ },
+ "dependencies": {
+ "underscore.string": "^3.2.2"
+ },
+ "devDependencies": {
+ "vscode": ">=0.9.0-pre.1"
+ }
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..2366b76
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "outDir": "out",
+ "noLib": true,
+ "sourceMap": true,
+ "moduleResolution": "node"
+ },
+ "exclude": [
+ "node_modules"
+ ]
+}
\ No newline at end of file
diff --git a/typings/underscore.string/underscore.string.d.ts b/typings/underscore.string/underscore.string.d.ts
new file mode 100644
index 0000000..1b08dcf
--- /dev/null
+++ b/typings/underscore.string/underscore.string.d.ts
@@ -0,0 +1,573 @@
+// Type definitions for underscore.string
+// Project: https://github.com/epeli/underscore.string
+// Definitions by: Ry Racherbaumer
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+interface UnderscoreStatic {
+ str: UnderscoreStringStatic;
+ string: UnderscoreStringStatic;
+}
+
+declare var s : UnderscoreStringStatic;
+
+interface UnderscoreStringStatic extends UnderscoreStringStaticExports {
+ /**
+ * Tests if string contains a substring.
+ * ('foobar', 'ob') => true
+ * @param str
+ * @param needle
+ */
+ include(str: string, needle: string): boolean;
+
+ /**
+ * Tests if string contains a substring.
+ * ('foobar', 'ob') => true
+ * @param str
+ * @param needle
+ */
+ contains(str: string, needle: string): boolean;
+
+ /**
+ * Return reversed string.
+ * ('foobar') => 'raboof'
+ * @param str
+ */
+ reverse(str: string): string;
+}
+
+/**
+ * Functions exported for mixing with underscore object.
+ *
+ * Usage:
+ * _.mixin(_.string.exports());
+ * interface UnderscoreStatic extends UnderscoreStringStaticExports { }
+ */
+interface UnderscoreStringStaticExports {
+
+ exports(): UnderscoreStringStaticExports;
+
+ /**
+ * Determine if a string is 'blank.'
+ * @param str
+ */
+ isBlank(str: string): boolean;
+
+ /**
+ * Removes all html tags from string.
+ * @param str
+ */
+ stripTags(str: string): string;
+
+ /**
+ * Converts first letter of the string to uppercase.
+ * ('foo Bar') => 'Foo Bar'
+ * @param str
+ */
+ capitalize(str: string): string;
+
+ /**
+ * Chop a string into pieces.
+ * ('whitespace', 3) => ['whi','tes','pac','e']
+ * @param str String to chop
+ * @param step Size of the pieces
+ */
+ chop(str: string, step: number): any[];
+
+ /**
+ * Compress some whitespaces to one.
+ * (' foo bar ') => 'foo bar'
+ * @param str
+ */
+ clean(str: string): string;
+
+ /**
+ * Count occurences of a sub string.
+ * ('Hello world', 'l') => 3
+ * @param str
+ * @param substr
+ */
+ count(str: string, substr: string): number;
+
+ /**
+ * Convert string to an array of characters.
+ * ('Hello') => ['H','e','l','l','o']
+ * @param str
+ */
+ chars(str: string): any[];
+
+ /**
+ * Returns a copy of the string in which all the case-based characters have had their case swapped.
+ * ('hELLO') => 'Hello'
+ * @param str
+ */
+ swapCase(str: string): string;
+
+ /**
+ * Converts HTML special characters to their entity equivalents.
+ * ('Blah blah blah
') => '<div>Blah blah blah</div>'
+ * @param str
+ */
+ escapeHTML(str: string): string;
+
+ /**
+ * Converts entity characters to HTML equivalents.
+ * ('<div>Blah blah blah</div>') => 'Blah blah blah
'
+ * @param str
+ */
+ unescapeHTML(str: string): string;
+
+ /**
+ * Escape a string for use in a regular expression.
+ * @param str
+ */
+ escapeRegExp(str: string): string;
+
+ /**
+ * Splice a string like an array.
+ * @param str
+ * @param i
+ * @param howmany
+ * @param substr
+ */
+ splice(str: string, i: number, howmany: number, substr?: string): string;
+
+ /**
+ * Insert a string at index.
+ * @param str
+ * @param i
+ * @param substr
+ */
+ insert(str: string, i: number, substr: string): string;
+
+ /**
+ * Joins strings together with given separator.
+ * (' ', 'foo', 'bar') => 'foo bar'
+ * @param separator
+ * @param args
+ */
+ join(separator: string, ...args: string[]): string;
+
+ /**
+ * Split string by newlines character.
+ * ('Hello\nWorld') => ['Hello', 'World']
+ * @param str
+ */
+ lines(str: string): any[];
+
+ /**
+ * Checks if string starts with another string.
+ * ('image.gif', 'image') => true
+ * @param str
+ * @param starts
+ */
+ startsWith(str: string, starts: string): boolean;
+
+ /**
+ * Checks if string ends with another string.
+ * ('image.gif', 'gif') => true
+ * @param value
+ * @param starts
+ */
+ endsWith(value: string, starts: string): boolean;
+
+ /**
+ * Returns the successor to passed string.
+ * ('a') => 'b'
+ * @param str
+ */
+ succ(str: string): string;
+
+ /**
+ * Capitalize first letter of every word in the string.
+ * ('my name is epeli') => 'My Name Is Epeli'
+ * @param str
+ */
+ titleize(str: string): string;
+
+ /**
+ * Converts underscored or dasherized string to a camelized one.
+ * ('-moz-transform') => 'MozTransform'
+ * @param str
+ */
+ camelize(str: string): string;
+
+ /**
+ * Converts a camelized or dasherized string into an underscored one.
+ * ('MozTransform') => 'moz_transform'
+ * @param str
+ */
+ underscored(str: string): string;
+
+ /**
+ * Converts a underscored or camelized string into an dasherized one.
+ * ('MozTransform') => '-moz-transform'
+ * @param str
+ */
+ dasherize(str: string): string;
+
+ /**
+ * Converts string to camelized class name.
+ * ('some_class_name') => 'SomeClassName'
+ * @param str
+ */
+ classify(str: string): string;
+
+ /**
+ * Converts an underscored, camelized, or dasherized string into a humanized one.
+ * Also removes beginning and ending whitespace, and removes the postfix '_id'.
+ * (' capitalize dash-CamelCase_underscore trim ') => 'Capitalize dash camel case underscore trim'
+ * @param str
+ */
+ humanize(str: string): string;
+
+ /**
+ * Trims defined characters from begining and ending of the string.
+ * Defaults to whitespace characters.
+ * (' foobar ') => 'foobar'
+ * ('_-foobar-_', '_-') => 'foobar'
+ * @param str
+ * @param characters
+ */
+ trim(str: string, characters?: string): string;
+
+ /**
+ * Trims defined characters from begining and ending of the string.
+ * Defaults to whitespace characters.
+ * (' foobar ') => 'foobar'
+ * ('_-foobar-_', '_-') => 'foobar'
+ * @param str
+ * @param characters
+ */
+ strip(str: string, characters?: string): string;
+
+ /**
+ * Left trim. Similar to trim, but only for left side.
+ * @param str
+ * @param characters
+ */
+ ltrim(str: string, characters?: string): string;
+
+ /**
+ * Left trim. Similar to trim, but only for left side.
+ * @param str
+ * @param characters
+ */
+ lstrip(str: string, characters?: string): string;
+
+ /**
+ * Right trim. Similar to trim, but only for right side.
+ * @param str
+ * @param characters
+ */
+ rtrim(str: string, characters?: string): string;
+
+ /**
+ * Right trim. Similar to trim, but only for right side.
+ * @param str
+ * @param characters
+ */
+ rstrip(str: string, characters?: string): string;
+
+ /**
+ * Truncate string to specified length.
+ * ('Hello world').truncate(5) => 'Hello...'
+ * ('Hello').truncate(10) => 'Hello'
+ * @param str
+ * @param length
+ * @param truncateStr
+ */
+ truncate(str: string, length: number, truncateStr?: string): string;
+
+ /**
+ * Elegant version of truncate.
+ * Makes sure the pruned string does not exceed the original length.
+ * Avoid half-chopped words when truncating.
+ * ('Hello, cruel world', 15) => 'Hello, cruel...'
+ * @param str
+ * @param length
+ * @param pruneStr
+ */
+ prune(str: string, length: number, pruneStr?: string): string;
+
+ /**
+ * Split string by delimiter (String or RegExp).
+ * /\s+/ by default.
+ * (' I love you ') => ['I','love','you']
+ * ('I_love_you', '_') => ['I','love','you']
+ * @param str
+ * @param delimiter
+ */
+ words(str: string): string[];
+
+ /**
+ * Split string by delimiter (String or RegExp).
+ * /\s+/ by default.
+ * (' I love you ') => ['I','love','you']
+ * ('I_love_you', '_') => ['I','love','you']
+ * @param str
+ * @param delimiter
+ */
+ words(str: string, delimiter: string): string[];
+
+ /**
+ * Split string by delimiter (String or RegExp).
+ * /\s+/ by default.
+ * (' I love you ') => ['I','love','you']
+ * ('I_love_you', '_') => ['I','love','you']
+ * @param str
+ * @param delimiter
+ */
+ words(str: string, delimiter: RegExp): string[];
+
+ /**
+ * Pads a string with characters until the total string length is equal to the passed length parameter.
+ * By default, pads on the left with the space char (' ').
+ * padStr is truncated to a single character if necessary.
+ * ('1', 8) => ' 1'
+ * ('1', 8, '0') => '00000001'
+ * ('1', 8, '0', 'right') => '10000000'
+ * ('1', 8, '0', 'both') => '00001000'
+ * ('1', 8, 'bleepblorp', 'both') => 'bbbb1bbb'
+ * @param str
+ * @param length
+ * @param padStr
+ * @param type
+ */
+ pad(str: string, length: number, padStr?:string, type?: string): string;
+
+ /**
+ * Left-pad a string.
+ * Alias for pad(str, length, padStr, 'left')
+ * ('1', 8, '0') => '00000001'
+ * @param str
+ * @param length
+ * @param padStr
+ */
+ lpad(str: string, length: number, padStr?: string): string;
+
+ /**
+ * Left-pad a string.
+ * Alias for pad(str, length, padStr, 'left')
+ * ('1', 8, '0') => '00000001'
+ * @param str
+ * @param length
+ * @param padStr
+ */
+ rjust(str: string, length: number, padStr?: string): string;
+
+ /**
+ * Right-pad a string.
+ * Alias for pad(str, length, padStr, 'right')
+ * ('1', 8, '0') => '10000000'
+ * @param str
+ * @param length
+ * @param padStr
+ */
+ rpad(str: string, length: number, padStr?: string): string;
+
+ /**
+ * Right-pad a string.
+ * Alias for pad(str, length, padStr, 'right')
+ * ('1', 8, '0') => '10000000'
+ * @param str
+ * @param length
+ * @param padStr
+ */
+ ljust(str: string, length: number, padStr?: string): string;
+
+ /**
+ * Left/right-pad a string.
+ * Alias for pad(str, length, padStr, 'both')
+ * ('1', 8, '0') => '00001000'
+ * @param str
+ * @param length
+ * @param padStr
+ */
+ lrpad(str: string, length: number, padStr?: string): string;
+
+ /**
+ * Left/right-pad a string.
+ * Alias for pad(str, length, padStr, 'both')
+ * ('1', 8, '0') => '00001000'
+ * @param str
+ * @param length
+ * @param padStr
+ */
+ center(str: string, length: number, padStr?: string): string;
+
+ /**
+ * C like string formatting.
+ * _.sprintf('%.1f', 1.17) => '1.2'
+ * @param format
+ * @param args
+ */
+ sprintf(format: string, ...args: any[]): string;
+
+ /**
+ * Parse string to number.
+ * Returns NaN if string can't be parsed to number.
+ * ('2.556').toNumber() => 3
+ * ('2.556').toNumber(1) => 2.6
+ * @param str
+ * @param decimals
+ */
+ toNumber(str: string, decimals?: number): number;
+
+ /**
+ * Formats the numbers.
+ * (1000, 2) => '1,000.00'
+ * (123456789.123, 5, '.', ',') => '123,456,789.12300'
+ * @param number
+ * @param dec
+ * @param dsep
+ * @param tsep
+ */
+ numberFormat(number: number, dec?: number, dsep?: string, tsep?: string): string;
+
+ /**
+ * Searches a string from left to right for a pattern.
+ * Returns a substring consisting of the characters in the string that are to the right of the pattern.
+ * If no match found, returns entire string.
+ * ('This_is_a_test_string').strRight('_') => 'is_a_test_string'
+ * @param str
+ * @param sep
+ */
+ strRight(str: string, sep: string): string;
+
+ /**
+ * Searches a string from right to left for a pattern.
+ * Returns a substring consisting of the characters in the string that are to the right of the pattern.
+ * If no match found, returns entire string.
+ * ('This_is_a_test_string').strRightBack('_') => 'string'
+ * @param str
+ * @param sep
+ */
+ strRightBack(str: string, sep: string): string;
+
+ /**
+ * Searches a string from left to right for a pattern.
+ * Returns a substring consisting of the characters in the string that are to the left of the pattern.
+ * If no match found, returns entire string.
+ * ('This_is_a_test_string').strLeft('_') => 'This'
+ * @param str
+ * @param sep
+ */
+ strLeft(str: string, sep: string): string;
+
+ /**
+ * Searches a string from right to left for a pattern.
+ * Returns a substring consisting of the characters in the string that are to the left of the pattern.
+ * If no match found, returns entire string.
+ * ('This_is_a_test_string').strLeftBack('_') => 'This_is_a_test'
+ * @param str
+ * @param sep
+ */
+ strLeftBack(str: string, sep: string): string;
+
+ /**
+ * Join an array into a human readable sentence.
+ * (['jQuery', 'Mootools', 'Prototype']) => 'jQuery, Mootools and Prototype'
+ * (['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ') => 'jQuery, Mootools unt Prototype'
+ * @param array
+ * @param separator
+ * @param lastSeparator
+ * @param serial
+ */
+ toSentence(array: any[], separator?: string, lastSeparator?: string, serial?: boolean): string;
+
+ /**
+ * The same as toSentence, but uses ', ' as default for lastSeparator.
+ * @param array
+ * @param separator
+ * @param lastSeparator
+ */
+ toSentenceSerial(array: any[], separator?: string, lastSeparator?: string): string;
+
+ /**
+ * Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash.
+ * ('Un éléphant à l'orée du bois') => 'un-elephant-a-loree-du-bois'
+ * @param str
+ */
+ slugify(str: string): string;
+
+ /**
+ * Surround a string with another string.
+ * ('foo', 'ab') => 'abfooab'
+ * @param str
+ * @param wrapper
+ */
+ surround(str: string, wrapper: string): string;
+
+ /**
+ * Quotes a string.
+ * quoteChar defaults to "
+ * ('foo') => '"foo"'
+ * @param str
+ */
+ quote(str: string, quoteChar?: string): string;
+
+ /**
+ * Quotes a string.
+ * quoteChar defaults to "
+ * ('foo') => '"foo"'
+ * @param str
+ */
+ q(str: string, quoteChar?: string): string;
+
+ /**
+ * Unquotes a string.
+ * quoteChar defaults to "
+ * ('"foo"') => 'foo'
+ * ("'foo'", "'") => 'foo'
+ * @param str
+ */
+ unquote(str: string, quoteChar?: string): string;
+
+ /**
+ * Repeat a string with an optional separator.
+ * ('foo', 3) => 'foofoofoo'
+ * ('foo', 3, 'bar') => 'foobarfoobarfoo'
+ * @param value
+ * @param count
+ * @param separator
+ */
+ repeat(value: string, count: number, separator?:string): string;
+
+ /**
+ * Naturally sort strings like humans would do.
+ * Caution: this function is charset dependent.
+ * @param str1
+ * @param str2
+ */
+ naturalCmp(str1: string, str2: string): number;
+
+ /**
+ * Calculates Levenshtein distance between two strings.
+ * ('kitten', 'kittah') => 2
+ * @param str1
+ * @param str2
+ */
+ levenshtein(str1: string, str2: string): number;
+
+ /**
+ * Turn strings that can be commonly considered as booleans to real booleans.
+ * Such as "true", "false", "1" and "0". This function is case insensitive.
+ * ('true') => true
+ * ('FALSE') => false
+ * ('random') => undefined
+ * ('truthy', ['truthy'], ['falsy']) => true
+ * ('true only at start', [/^true/]) => true
+ * @param str
+ * @param trueValues
+ * @param falseValues
+ */
+ toBoolean(str: string, trueValues?: any[], falseValues?: any[]): boolean;
+
+}
+declare module 'underscore.string' {
+ var underscoreString: UnderscoreStringStatic;
+ export = underscoreString;
+}
+// TODO interface UnderscoreString extends Underscore
diff --git a/typings/underscore/underscore.d.ts b/typings/underscore/underscore.d.ts
new file mode 100644
index 0000000..7dea66a
--- /dev/null
+++ b/typings/underscore/underscore.d.ts
@@ -0,0 +1,3413 @@
+// Type definitions for Underscore 1.7.0
+// Project: http://underscorejs.org/
+// Definitions by: Boris Yankov , Josh Baldwin
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module _ {
+ /**
+ * underscore.js _.throttle options.
+ **/
+ interface ThrottleSettings {
+
+ /**
+ * If you'd like to disable the leading-edge call, pass this as false.
+ **/
+ leading?: boolean;
+
+ /**
+ * If you'd like to disable the execution on the trailing-edge, pass false.
+ **/
+ trailing?: boolean;
+ }
+
+ /**
+ * underscore.js template settings, set templateSettings or pass as an argument
+ * to 'template()' to override defaults.
+ **/
+ interface TemplateSettings {
+ /**
+ * Default value is '/<%([\s\S]+?)%>/g'.
+ **/
+ evaluate?: RegExp;
+
+ /**
+ * Default value is '/<%=([\s\S]+?)%>/g'.
+ **/
+ interpolate?: RegExp;
+
+ /**
+ * Default value is '/<%-([\s\S]+?)%>/g'.
+ **/
+ escape?: RegExp;
+ }
+
+ interface Collection { }
+
+ // Common interface between Arrays and jQuery objects
+ interface List extends Collection {
+ [index: number]: T;
+ length: number;
+ }
+
+ interface Dictionary extends Collection {
+ [index: string]: T;
+ }
+
+ interface ListIterator {
+ (value: T, index: number, list: List): TResult;
+ }
+
+ interface ObjectIterator {
+ (element: T, key: string, list: Dictionary): TResult;
+ }
+
+ interface MemoIterator {
+ (prev: TResult, curr: T, index: number, list: List): TResult;
+ }
+
+ interface MemoObjectIterator {
+ (prev: TResult, curr: T, key: string, list: Dictionary): TResult;
+ }
+}
+
+interface UnderscoreStatic {
+ /**
+ * Underscore OOP Wrapper, all Underscore functions that take an object
+ * as the first parameter can be invoked through this function.
+ * @param key First argument to Underscore object functions.
+ **/
+ (value: Array): Underscore;
+ (value: T): Underscore;
+
+ /* *************
+ * Collections *
+ ************* */
+
+ /**
+ * Iterates over a list of elements, yielding each in turn to an iterator function. The iterator is
+ * bound to the context object, if one is passed. Each invocation of iterator is called with three
+ * arguments: (element, index, list). If list is a JavaScript object, iterator's arguments will be
+ * (value, key, object). Delegates to the native forEach function if it exists.
+ * @param list Iterates over this list of elements.
+ * @param iterator Iterator function for each element `list`.
+ * @param context 'this' object in `iterator`, optional.
+ **/
+ each(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): _.List;
+
+ /**
+ * @see _.each
+ * @param object Iterates over properties of this object.
+ * @param iterator Iterator function for each property on `object`.
+ * @param context 'this' object in `iterator`, optional.
+ **/
+ each(
+ object: _.Dictionary,
+ iterator: _.ObjectIterator,
+ context?: any): _.Dictionary;
+
+ /**
+ * @see _.each
+ **/
+ forEach(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): _.List;
+
+ /**
+ * @see _.each
+ **/
+ forEach(
+ object: _.Dictionary,
+ iterator: _.ObjectIterator,
+ context?: any): _.Dictionary;
+
+ /**
+ * Produces a new array of values by mapping each value in list through a transformation function
+ * (iterator). If the native map method exists, it will be used instead. If list is a JavaScript
+ * object, iterator's arguments will be (value, key, object).
+ * @param list Maps the elements of this array.
+ * @param iterator Map iterator function for each element in `list`.
+ * @param context `this` object in `iterator`, optional.
+ * @return The mapped array result.
+ **/
+ map(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): TResult[];
+
+ /**
+ * @see _.map
+ * @param object Maps the properties of this object.
+ * @param iterator Map iterator function for each property on `object`.
+ * @param context `this` object in `iterator`, optional.
+ * @return The mapped object result.
+ **/
+ map(
+ object: _.Dictionary,
+ iterator: _.ObjectIterator,
+ context?: any): TResult[];
+
+ /**
+ * @see _.map
+ **/
+ collect(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): TResult[];
+
+ /**
+ * @see _.map
+ **/
+ collect(
+ object: _.Dictionary,
+ iterator: _.ObjectIterator,
+ context?: any): TResult[];
+
+ /**
+ * Also known as inject and foldl, reduce boils down a list of values into a single value.
+ * Memo is the initial state of the reduction, and each successive step of it should be
+ * returned by iterator. The iterator is passed four arguments: the memo, then the value
+ * and index (or key) of the iteration, and finally a reference to the entire list.
+ * @param list Reduces the elements of this array.
+ * @param iterator Reduce iterator function for each element in `list`.
+ * @param memo Initial reduce state.
+ * @param context `this` object in `iterator`, optional.
+ * @return Reduced object result.
+ **/
+ reduce(
+ list: _.Collection,
+ iterator: _.MemoIterator,
+ memo?: TResult,
+ context?: any): TResult;
+
+ reduce(
+ list: _.Dictionary,
+ iterator: _.MemoObjectIterator,
+ memo?: TResult,
+ context?: any): TResult;
+
+ /**
+ * @see _.reduce
+ **/
+ inject(
+ list: _.Collection,
+ iterator: _.MemoIterator,
+ memo?: TResult,
+ context?: any): TResult;
+
+ /**
+ * @see _.reduce
+ **/
+ foldl(
+ list: _.Collection,
+ iterator: _.MemoIterator,
+ memo?: TResult,
+ context?: any): TResult;
+
+ /**
+ * The right-associative version of reduce. Delegates to the JavaScript 1.8 version of
+ * reduceRight, if it exists. `foldr` is not as useful in JavaScript as it would be in a
+ * language with lazy evaluation.
+ * @param list Reduces the elements of this array.
+ * @param iterator Reduce iterator function for each element in `list`.
+ * @param memo Initial reduce state.
+ * @param context `this` object in `iterator`, optional.
+ * @return Reduced object result.
+ **/
+ reduceRight(
+ list: _.Collection,
+ iterator: _.MemoIterator,
+ memo?: TResult,
+ context?: any): TResult;
+
+ /**
+ * @see _.reduceRight
+ **/
+ foldr(
+ list: _.Collection,
+ iterator: _.MemoIterator,
+ memo?: TResult,
+ context?: any): TResult;
+
+ /**
+ * Looks through each value in the list, returning the first one that passes a truth
+ * test (iterator). The function returns as soon as it finds an acceptable element,
+ * and doesn't traverse the entire list.
+ * @param list Searches for a value in this list.
+ * @param iterator Search iterator function for each element in `list`.
+ * @param context `this` object in `iterator`, optional.
+ * @return The first acceptable found element in `list`, if nothing is found undefined/null is returned.
+ **/
+ find(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): T;
+
+ /**
+ * @see _.find
+ **/
+ find(
+ object: _.Dictionary,
+ iterator: _.ObjectIterator,
+ context?: any): T;
+
+ /**
+ * @see _.find
+ **/
+ detect(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): T;
+
+ /**
+ * @see _.find
+ **/
+ detect(
+ object: _.Dictionary,
+ iterator: _.ObjectIterator,
+ context?: any): T;
+
+ /**
+ * Looks through each value in the list, returning the index of the first one that passes a truth
+ * test (iterator). The function returns as soon as it finds an acceptable element,
+ * and doesn't traverse the entire list.
+ * @param list Searches for a value in this list.
+ * @param iterator Search iterator function for each element in `list`.
+ * @param context `this` object in `iterator`, optional.
+ * @return The index of the first acceptable found element in `list`, if nothing is found -1 is returned.
+ **/
+ findIndex(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): number;
+
+
+ /**
+ * Looks through each value in the list, returning an array of all the values that pass a truth
+ * test (iterator). Delegates to the native filter method, if it exists.
+ * @param list Filter elements out of this list.
+ * @param iterator Filter iterator function for each element in `list`.
+ * @param context `this` object in `iterator`, optional.
+ * @return The filtered list of elements.
+ **/
+ filter(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): T[];
+
+ /**
+ * @see _.filter
+ **/
+ filter(
+ object: _.Dictionary,
+ iterator: _.ObjectIterator,
+ context?: any): T[];
+
+ /**
+ * @see _.filter
+ **/
+ select(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): T[];
+
+ /**
+ * @see _.filter
+ **/
+ select(
+ object: _.Dictionary,
+ iterator: _.ObjectIterator,
+ context?: any): T[];
+
+ /**
+ * Looks through each value in the list, returning an array of all the values that contain all
+ * of the key-value pairs listed in properties.
+ * @param list List to match elements again `properties`.
+ * @param properties The properties to check for on each element within `list`.
+ * @return The elements within `list` that contain the required `properties`.
+ **/
+ where(
+ list: _.List,
+ properties: U): T[];
+
+ /**
+ * Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.
+ * @param list Search through this list's elements for the first object with all `properties`.
+ * @param properties Properties to look for on the elements within `list`.
+ * @return The first element in `list` that has all `properties`.
+ **/
+ findWhere(
+ list: _.List,
+ properties: U): T;
+
+ /**
+ * Returns the values in list without the elements that the truth test (iterator) passes.
+ * The opposite of filter.
+ * Return all the elements for which a truth test fails.
+ * @param list Reject elements within this list.
+ * @param iterator Reject iterator function for each element in `list`.
+ * @param context `this` object in `iterator`, optional.
+ * @return The rejected list of elements.
+ **/
+ reject(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): T[];
+
+ /**
+ * @see _.reject
+ **/
+ reject(
+ object: _.Dictionary,
+ iterator: _.ObjectIterator,
+ context?: any): T[];
+
+ /**
+ * Returns true if all of the values in the list pass the iterator truth test. Delegates to the
+ * native method every, if present.
+ * @param list Truth test against all elements within this list.
+ * @param iterator Trust test iterator function for each element in `list`.
+ * @param context `this` object in `iterator`, optional.
+ * @return True if all elements passed the truth test, otherwise false.
+ **/
+ every(
+ list: _.List,
+ iterator?: _.ListIterator,
+ context?: any): boolean;
+
+ /**
+ * @see _.every
+ **/
+ every(
+ list: _.Dictionary,
+ iterator?: _.ObjectIterator,
+ context?: any): boolean;
+
+ /**
+ * @see _.every
+ **/
+ all(
+ list: _.List,
+ iterator?: _.ListIterator,
+ context?: any): boolean;
+
+ /**
+ * @see _.every
+ **/
+ all(
+ list: _.Dictionary,
+ iterator?: _.ObjectIterator,
+ context?: any): boolean;
+
+ /**
+ * Returns true if any of the values in the list pass the iterator truth test. Short-circuits and
+ * stops traversing the list if a true element is found. Delegates to the native method some, if present.
+ * @param list Truth test against all elements within this list.
+ * @param iterator Trust test iterator function for each element in `list`.
+ * @param context `this` object in `iterator`, optional.
+ * @return True if any elements passed the truth test, otherwise false.
+ **/
+ some(
+ list: _.List,
+ iterator?: _.ListIterator,
+ context?: any): boolean;
+
+ /**
+ * @see _.some
+ **/
+ some(
+ object: _.Dictionary,
+ iterator?: _.ObjectIterator,
+ context?: any): boolean;
+
+ /**
+ * @see _.some
+ **/
+ any(
+ list: _.List,
+ iterator?: _.ListIterator,
+ context?: any): boolean;
+
+ /**
+ * @see _.some
+ **/
+ any(
+ object: _.Dictionary,
+ iterator?: _.ObjectIterator,
+ context?: any): boolean;
+
+ /**
+ * Returns true if the value is present in the list. Uses indexOf internally,
+ * if list is an Array.
+ * @param list Checks each element to see if `value` is present.
+ * @param value The value to check for within `list`.
+ * @return True if `value` is present in `list`, otherwise false.
+ **/
+ contains(
+ list: _.List,
+ value: T): boolean;
+
+ /**
+ * @see _.contains
+ **/
+ contains(
+ object: _.Dictionary,
+ value: T): boolean;
+
+ /**
+ * @see _.contains
+ **/
+ include(
+ list: _.Collection,
+ value: T): boolean;
+
+ /**
+ * @see _.contains
+ **/
+ include(
+ object: _.Dictionary,
+ value: T): boolean;
+
+ /**
+ * Calls the method named by methodName on each value in the list. Any extra arguments passed to
+ * invoke will be forwarded on to the method invocation.
+ * @param list The element's in this list will each have the method `methodName` invoked.
+ * @param methodName The method's name to call on each element within `list`.
+ * @param arguments Additional arguments to pass to the method `methodName`.
+ **/
+ invoke(
+ list: _.List,
+ methodName: string,
+ ...arguments: any[]): any;
+
+ /**
+ * A convenient version of what is perhaps the most common use-case for map: extracting a list of
+ * property values.
+ * @param list The list to pluck elements out of that have the property `propertyName`.
+ * @param propertyName The property to look for on each element within `list`.
+ * @return The list of elements within `list` that have the property `propertyName`.
+ **/
+ pluck(
+ list: _.List,
+ propertyName: string): any[];
+
+ /**
+ * Returns the maximum value in list.
+ * @param list Finds the maximum value in this list.
+ * @return Maximum value in `list`.
+ **/
+ max(list: _.List): number;
+
+ /**
+ * Returns the maximum value in list. If iterator is passed, it will be used on each value to generate
+ * the criterion by which the value is ranked.
+ * @param list Finds the maximum value in this list.
+ * @param iterator Compares each element in `list` to find the maximum value.
+ * @param context `this` object in `iterator`, optional.
+ * @return The maximum element within `list`.
+ **/
+ max(
+ list: _.List,
+ iterator?: _.ListIterator,
+ context?: any): T;
+
+ /**
+ * Returns the minimum value in list.
+ * @param list Finds the minimum value in this list.
+ * @return Minimum value in `list`.
+ **/
+ min(list: _.List): number;
+
+ /**
+ * Returns the minimum value in list. If iterator is passed, it will be used on each value to generate
+ * the criterion by which the value is ranked.
+ * @param list Finds the minimum value in this list.
+ * @param iterator Compares each element in `list` to find the minimum value.
+ * @param context `this` object in `iterator`, optional.
+ * @return The minimum element within `list`.
+ **/
+ min(
+ list: _.List,
+ iterator?: _.ListIterator,
+ context?: any): T;
+
+ /**
+ * Returns a sorted copy of list, ranked in ascending order by the results of running each value
+ * through iterator. Iterator may also be the string name of the property to sort by (eg. length).
+ * @param list Sorts this list.
+ * @param iterator Sort iterator for each element within `list`.
+ * @param context `this` object in `iterator`, optional.
+ * @return A sorted copy of `list`.
+ **/
+ sortBy(
+ list: _.List,
+ iterator?: _.ListIterator,
+ context?: any): T[];
+
+ /**
+ * @see _.sortBy
+ * @param iterator Sort iterator for each element within `list`.
+ **/
+ sortBy(
+ list: _.List,
+ iterator: string,
+ context?: any): T[];
+
+ /**
+ * Splits a collection into sets, grouped by the result of running each value through iterator.
+ * If iterator is a string instead of a function, groups by the property named by iterator on
+ * each of the values.
+ * @param list Groups this list.
+ * @param iterator Group iterator for each element within `list`, return the key to group the element by.
+ * @param context `this` object in `iterator`, optional.
+ * @return An object with the group names as properties where each property contains the grouped elements from `list`.
+ **/
+ groupBy(
+ list: _.List,
+ iterator?: _.ListIterator,
+ context?: any): _.Dictionary;
+
+ /**
+ * @see _.groupBy
+ * @param iterator Property on each object to group them by.
+ **/
+ groupBy(
+ list: _.List,
+ iterator: string,
+ context?: any): _.Dictionary;
+
+ /**
+ * Given a `list`, and an `iterator` function that returns a key for each element in the list (or a property name),
+ * returns an object with an index of each item. Just like _.groupBy, but for when you know your keys are unique.
+ **/
+ indexBy(
+ list: _.List,
+ iterator: _.ListIterator,
+ context?: any): _.Dictionary;
+
+ /**
+ * @see _.indexBy
+ * @param iterator Property on each object to index them by.
+ **/
+ indexBy(
+ list: _.List,
+ iterator: string,
+ context?: any): _.Dictionary;
+
+ /**
+ * Sorts a list into groups and returns a count for the number of objects in each group. Similar
+ * to groupBy, but instead of returning a list of values, returns a count for the number of values
+ * in that group.
+ * @param list Group elements in this list and then count the number of elements in each group.
+ * @param iterator Group iterator for each element within `list`, return the key to group the element by.
+ * @param context `this` object in `iterator`, optional.
+ * @return An object with the group names as properties where each property contains the number of elements in that group.
+ **/
+ countBy(
+ list: _.List,
+ iterator?: _.ListIterator,
+ context?: any): _.Dictionary;
+
+ /**
+ * @see _.countBy
+ * @param iterator Function name
+ **/
+ countBy(
+ list: _.List,
+ iterator: string,
+ context?: any): _.Dictionary;
+
+ /**
+ * Returns a shuffled copy of the list, using a version of the Fisher-Yates shuffle.
+ * @param list List to shuffle.
+ * @return Shuffled copy of `list`.
+ **/
+ shuffle(list: _.Collection): T[];
+
+ /**
+ * Produce a random sample from the `list`. Pass a number to return `n` random elements from the list. Otherwise a single random item will be returned.
+ * @param list List to sample.
+ * @return Random sample of `n` elements in `list`.
+ **/
+ sample(list: _.Collection, n: number): T[];
+
+ /**
+ * @see _.sample
+ **/
+ sample(list: _.Collection): T;
+
+ /**
+ * Converts the list (anything that can be iterated over), into a real Array. Useful for transmuting
+ * the arguments object.
+ * @param list object to transform into an array.
+ * @return `list` as an array.
+ **/
+ toArray(list: _.Collection): T[];
+
+ /**
+ * Return the number of values in the list.
+ * @param list Count the number of values/elements in this list.
+ * @return Number of values in `list`.
+ **/
+ size(list: _.Collection): number;
+
+ /**
+ * Split array into two arrays:
+ * one whose elements all satisfy predicate and one whose elements all do not satisfy predicate.
+ * @param array Array to split in two.
+ * @param iterator Filter iterator function for each element in `array`.
+ * @param context `this` object in `iterator`, optional.
+ * @return Array where Array[0] are the elements in `array` that satisfies the predicate, and Array[1] the elements that did not.
+ **/
+ partition(
+ array: Array,
+ iterator: _.ListIterator,
+ context?: any): T[][];
+
+ /*********
+ * Arrays *
+ **********/
+
+ /**
+ * Returns the first element of an array. Passing n will return the first n elements of the array.
+ * @param array Retrieves the first element of this array.
+ * @return Returns the first element of `array`.
+ **/
+ first(array: _.List): T;
+
+ /**
+ * @see _.first
+ * @param n Return more than one element from `array`.
+ **/
+ first(
+ array: _.List,
+ n: number): T[];
+
+ /**
+ * @see _.first
+ **/
+ head(array: _.List): T;
+
+ /**
+ * @see _.first
+ **/
+ head(
+ array: _.List,
+ n: number): T[];
+
+ /**
+ * @see _.first
+ **/
+ take(array: _.List): T;
+
+ /**
+ * @see _.first
+ **/
+ take(
+ array: _.List,
+ n: number): T[];
+
+ /**
+ * Returns everything but the last entry of the array. Especially useful on the arguments object.
+ * Pass n to exclude the last n elements from the result.
+ * @param array Retrieve all elements except the last `n`.
+ * @param n Leaves this many elements behind, optional.
+ * @return Returns everything but the last `n` elements of `array`.
+ **/
+ initial(
+ array: _.List,
+ n?: number): T[];
+
+ /**
+ * Returns the last element of an array. Passing n will return the last n elements of the array.
+ * @param array Retrieves the last element of this array.
+ * @return Returns the last element of `array`.
+ **/
+ last(array: _.List): T;
+
+ /**
+ * @see _.last
+ * @param n Return more than one element from `array`.
+ **/
+ last(
+ array: _.List,
+ n: number): T[];
+
+ /**
+ * Returns the rest of the elements in an array. Pass an index to return the values of the array
+ * from that index onward.
+ * @param array The array to retrieve all but the first `index` elements.
+ * @param n The index to start retrieving elements forward from, optional, default = 1.
+ * @return Returns the elements of `array` from `index` to the end of `array`.
+ **/
+ rest(
+ array: _.List,
+ n?: number): T[];
+
+ /**
+ * @see _.rest
+ **/
+ tail(
+ array: _.List,
+ n?: number): T[];
+
+ /**
+ * @see _.rest
+ **/
+ drop(
+ array: _.List,
+ n?: number): T[];
+
+ /**
+ * Returns a copy of the array with all falsy values removed. In JavaScript, false, null, 0, "",
+ * undefined and NaN are all falsy.
+ * @param array Array to compact.
+ * @return Copy of `array` without false values.
+ **/
+ compact(array: _.List): T[];
+
+ /**
+ * Flattens a nested array (the nesting can be to any depth). If you pass shallow, the array will
+ * only be flattened a single level.
+ * @param array The array to flatten.
+ * @param shallow If true then only flatten one level, optional, default = false.
+ * @return `array` flattened.
+ **/
+ flatten(
+ array: _.List,
+ shallow?: boolean): any[];
+
+ /**
+ * Returns a copy of the array with all instances of the values removed.
+ * @param array The array to remove `values` from.
+ * @param values The values to remove from `array`.
+ * @return Copy of `array` without `values`.
+ **/
+ without(
+ array: _.List,
+ ...values: T[]): T[];
+
+ /**
+ * Computes the union of the passed-in arrays: the list of unique items, in order, that are
+ * present in one or more of the arrays.
+ * @param arrays Array of arrays to compute the union of.
+ * @return The union of elements within `arrays`.
+ **/
+ union(...arrays: _.List[]): T[];
+
+ /**
+ * Computes the list of values that are the intersection of all the arrays. Each value in the result
+ * is present in each of the arrays.
+ * @param arrays Array of arrays to compute the intersection of.
+ * @return The intersection of elements within `arrays`.
+ **/
+ intersection(...arrays: _.List[]): T[];
+
+ /**
+ * Similar to without, but returns the values from array that are not present in the other arrays.
+ * @param array Keeps values that are within `others`.
+ * @param others The values to keep within `array`.
+ * @return Copy of `array` with only `others` values.
+ **/
+ difference(
+ array: _.List,
+ ...others: _.List[]): T[];
+
+ /**
+ * Produces a duplicate-free version of the array, using === to test object equality. If you know in
+ * advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If
+ * you want to compute unique items based on a transformation, pass an iterator function.
+ * @param array Array to remove duplicates from.
+ * @param isSorted True if `array` is already sorted, optional, default = false.
+ * @param iterator Transform the elements of `array` before comparisons for uniqueness.
+ * @param context 'this' object in `iterator`, optional.
+ * @return Copy of `array` where all elements are unique.
+ **/
+ uniq(
+ array: _.List,
+ isSorted?: boolean,
+ iterator?: _.ListIterator,
+ context?: any): T[];
+
+ /**
+ * @see _.uniq
+ **/
+ uniq(
+ array: _.List,
+ iterator?: _.ListIterator,
+ context?: any): T[];
+
+ /**
+ * @see _.uniq
+ **/
+ unique(
+ array: _.List,
+ iterator?: _.ListIterator,
+ context?: any): T[];
+
+ /**
+ * @see _.uniq
+ **/
+ unique(
+ array: _.List,
+ isSorted?: boolean,
+ iterator?: _.ListIterator,
+ context?: any): T[];
+
+
+ /**
+ * Merges together the values of each of the arrays with the values at the corresponding position.
+ * Useful when you have separate data sources that are coordinated through matching array indexes.
+ * If you're working with a matrix of nested arrays, zip.apply can transpose the matrix in a similar fashion.
+ * @param arrays The arrays to merge/zip.
+ * @return Zipped version of `arrays`.
+ **/
+ zip(...arrays: any[][]): any[][];
+
+ /**
+ * @see _.zip
+ **/
+ zip(...arrays: any[]): any[];
+
+ /**
+ * Converts arrays into objects. Pass either a single list of [key, value] pairs, or a
+ * list of keys, and a list of values.
+ * @param keys Key array.
+ * @param values Value array.
+ * @return An object containing the `keys` as properties and `values` as the property values.
+ **/
+ object(
+ keys: _.List,
+ values: _.List): TResult;
+
+ /**
+ * Converts arrays into objects. Pass either a single list of [key, value] pairs, or a
+ * list of keys, and a list of values.
+ * @param keyValuePairs Array of [key, value] pairs.
+ * @return An object containing the `keys` as properties and `values` as the property values.
+ **/
+ object(...keyValuePairs: any[][]): TResult;
+
+ /**
+ * @see _.object
+ **/
+ object(
+ list: _.List,
+ values?: any): TResult;
+
+ /**
+ * Returns the index at which value can be found in the array, or -1 if value is not present in the array.
+ * Uses the native indexOf function unless it's missing. If you're working with a large array, and you know
+ * that the array is already sorted, pass true for isSorted to use a faster binary search ... or, pass a number
+ * as the third argument in order to look for the first matching value in the array after the given index.
+ * @param array The array to search for the index of `value`.
+ * @param value The value to search for within `array`.
+ * @param isSorted True if the array is already sorted, optional, default = false.
+ * @return The index of `value` within `array`.
+ **/
+ indexOf(
+ array: _.List,
+ value: T,
+ isSorted?: boolean): number;
+
+ /**
+ * @see _indexof
+ **/
+ indexOf(
+ array: _.List,
+ value: T,
+ startFrom: number): number;
+
+ /**
+ * Returns the index of the last occurrence of value in the array, or -1 if value is not present. Uses the
+ * native lastIndexOf function if possible. Pass fromIndex to start your search at a given index.
+ * @param array The array to search for the last index of `value`.
+ * @param value The value to search for within `array`.
+ * @param from The starting index for the search, optional.
+ * @return The index of the last occurrence of `value` within `array`.
+ **/
+ lastIndexOf(
+ array: _.List,
+ value: T,
+ from?: number): number;
+
+ /**
+ * Uses a binary search to determine the index at which the value should be inserted into the list in order
+ * to maintain the list's sorted order. If an iterator is passed, it will be used to compute the sort ranking
+ * of each value, including the value you pass.
+ * @param list The sorted list.
+ * @param value The value to determine its index within `list`.
+ * @param iterator Iterator to compute the sort ranking of each value, optional.
+ * @return The index where `value` should be inserted into `list`.
+ **/
+ sortedIndex(
+ list: _.List,
+ value: T,
+ iterator?: (x: T) => TSort, context?: any): number;
+
+ /**
+ * A function to create flexibly-numbered lists of integers, handy for each and map loops. start, if omitted,
+ * defaults to 0; step defaults to 1. Returns a list of integers from start to stop, incremented (or decremented)
+ * by step, exclusive.
+ * @param start Start here.
+ * @param stop Stop here.
+ * @param step The number to count up by each iteration, optional, default = 1.
+ * @return Array of numbers from `start` to `stop` with increments of `step`.
+ **/
+
+ range(
+ start: number,
+ stop: number,
+ step?: number): number[];
+
+ /**
+ * @see _.range
+ * @param stop Stop here.
+ * @return Array of numbers from 0 to `stop` with increments of 1.
+ * @note If start is not specified the implementation will never pull the step (step = arguments[2] || 0)
+ **/
+ range(stop: number): number[];
+
+ /*************
+ * Functions *
+ *************/
+
+ /**
+ * Bind a function to an object, meaning that whenever the function is called, the value of this will
+ * be the object. Optionally, bind arguments to the function to pre-fill them, also known as partial application.
+ * @param func The function to bind `this` to `object`.
+ * @param context The `this` pointer whenever `fn` is called.
+ * @param arguments Additional arguments to pass to `fn` when called.
+ * @return `fn` with `this` bound to `object`.
+ **/
+ bind(
+ func: Function,
+ context: any,
+ ...arguments: any[]): () => any;
+
+ /**
+ * Binds a number of methods on the object, specified by methodNames, to be run in the context of that object
+ * whenever they are invoked. Very handy for binding functions that are going to be used as event handlers,
+ * which would otherwise be invoked with a fairly useless this. If no methodNames are provided, all of the
+ * object's function properties will be bound to it.
+ * @param object The object to bind the methods `methodName` to.
+ * @param methodNames The methods to bind to `object`, optional and if not provided all of `object`'s
+ * methods are bound.
+ **/
+ bindAll(
+ object: any,
+ ...methodNames: string[]): any;
+
+ /**
+ * Partially apply a function by filling in any number of its arguments, without changing its dynamic this value.
+ * A close cousin of bind. You may pass _ in your list of arguments to specify an argument that should not be
+ * pre-filled, but left open to supply at call-time.
+ * @param fn Function to partially fill in arguments.
+ * @param arguments The partial arguments.
+ * @return `fn` with partially filled in arguments.
+ **/
+ partial(
+ fn: Function,
+ ...arguments: any[]): Function;
+
+ /**
+ * Memoizes a given function by caching the computed result. Useful for speeding up slow-running computations.
+ * If passed an optional hashFunction, it will be used to compute the hash key for storing the result, based
+ * on the arguments to the original function. The default hashFunction just uses the first argument to the
+ * memoized function as the key.
+ * @param fn Computationally expensive function that will now memoized results.
+ * @param hashFn Hash function for storing the result of `fn`.
+ * @return Memoized version of `fn`.
+ **/
+ memoize(
+ fn: Function,
+ hashFn?: (...args: any[]) => string): Function;
+
+ /**
+ * Much like setTimeout, invokes function after wait milliseconds. If you pass the optional arguments,
+ * they will be forwarded on to the function when it is invoked.
+ * @param func Function to delay `waitMS` amount of ms.
+ * @param wait The amount of milliseconds to delay `fn`.
+ * @arguments Additional arguments to pass to `fn`.
+ **/
+ delay(
+ func: Function,
+ wait: number,
+ ...arguments: any[]): any;
+
+ /**
+ * @see _delay
+ **/
+ delay(
+ func: Function,
+ ...arguments: any[]): any;
+
+ /**
+ * Defers invoking the function until the current call stack has cleared, similar to using setTimeout
+ * with a delay of 0. Useful for performing expensive computations or HTML rendering in chunks without
+ * blocking the UI thread from updating. If you pass the optional arguments, they will be forwarded on
+ * to the function when it is invoked.
+ * @param fn The function to defer.
+ * @param arguments Additional arguments to pass to `fn`.
+ **/
+ defer(
+ fn: Function,
+ ...arguments: any[]): void;
+
+ /**
+ * Creates and returns a new, throttled version of the passed function, that, when invoked repeatedly,
+ * will only actually call the original function at most once per every wait milliseconds. Useful for
+ * rate-limiting events that occur faster than you can keep up with.
+ * By default, throttle will execute the function as soon as you call it for the first time, and,
+ * if you call it again any number of times during the wait period, as soon as that period is over.
+ * If you'd like to disable the leading-edge call, pass {leading: false}, and if you'd like to disable
+ * the execution on the trailing-edge, pass {trailing: false}.
+ * @param func Function to throttle `waitMS` ms.
+ * @param wait The number of milliseconds to wait before `fn` can be invoked again.
+ * @param options Allows for disabling execution of the throttled function on either the leading or trailing edge.
+ * @return `fn` with a throttle of `wait`.
+ **/
+ throttle(
+ func: T,
+ wait: number,
+ options?: _.ThrottleSettings): T;
+
+ /**
+ * Creates and returns a new debounced version of the passed function that will postpone its execution
+ * until after wait milliseconds have elapsed since the last time it was invoked. Useful for implementing
+ * behavior that should only happen after the input has stopped arriving. For example: rendering a preview
+ * of a Markdown comment, recalculating a layout after the window has stopped being resized, and so on.
+ *
+ * Pass true for the immediate parameter to cause debounce to trigger the function on the leading instead
+ * of the trailing edge of the wait interval. Useful in circumstances like preventing accidental double
+ *-clicks on a "submit" button from firing a second time.
+ * @param fn Function to debounce `waitMS` ms.
+ * @param wait The number of milliseconds to wait before `fn` can be invoked again.
+ * @param immediate True if `fn` should be invoked on the leading edge of `waitMS` instead of the trailing edge.
+ * @return Debounced version of `fn` that waits `wait` ms when invoked.
+ **/
+ debounce(
+ fn: T,
+ wait: number,
+ immediate?: boolean): T;
+
+ /**
+ * Creates a version of the function that can only be called one time. Repeated calls to the modified
+ * function will have no effect, returning the value from the original call. Useful for initialization
+ * functions, instead of having to set a boolean flag and then check it later.
+ * @param fn Function to only execute once.
+ * @return Copy of `fn` that can only be invoked once.
+ **/
+ once