(function() { 'use strict'; /** * Extend an Object with another Object's properties. * * The source objects are specified as additional arguments. * * @param dst Object the object to extend. * * @return Object the final object. */ var _extend = function(dst) { var sources = Array.prototype.slice.call(arguments, 1); for (var i=0; i tmp) { nextCol = tmp; } // deletion tmp = prevRow[j + 1] + 1; if (nextCol > tmp) { nextCol = tmp; } // copy current col value into previous (in preparation for next iteration) prevRow[j] = curCol; } // copy last col value into previous (in preparation for next iteration) prevRow[j] = nextCol; } return nextCol; }, /** * Asynchronously calculate levenshtein distance of the two strings. * * @param str1 String the first string. * @param str2 String the second string. * @param cb Function callback function with signature: function(Error err, int distance) * @param [options] Object additional options. * @param [options.progress] Function progress callback with signature: function(percentComplete) */ getAsync: function(str1, str2, cb, options) { options = _extend({}, { progress: null }, options); // base cases if (str1 === str2) return cb(null, 0); if (str1.length === 0) return cb(null, str2.length); if (str2.length === 0) return cb(null, str1.length); // two rows var prevRow = new Array(str2.length + 1), curCol, nextCol, i, j, tmp, startTime, currentTime; // initialise previous row for (i=0; i tmp) { nextCol = tmp; } // deletion tmp = prevRow[j + 1] + 1; if (nextCol > tmp) { nextCol = tmp; } // copy current into previous (in preparation for next iteration) prevRow[j] = curCol; // get current time currentTime = new Date().valueOf(); } // send a progress update? if (null !== options.progress) { try { options.progress.call(null, (i * 100.0/ str1.length)); } catch (err) { return cb('Progress callback: ' + err.toString()); } } // next iteration _defer(__calculate); }; __calculate(); } }; // amd if (typeof define !== "undefined" && define !== null && define.amd) { define(function() { return Levenshtein; }); } // commonjs else if (typeof module !== "undefined" && module !== null && typeof exports !== "undefined" && module.exports === exports) { module.exports = Levenshtein; } // web worker else if (typeof self !== "undefined" && typeof self.postMessage === 'function' && typeof self.importScripts === 'function') { self.Levenshtein = Levenshtein; } // browser main thread else if (typeof window !== "undefined" && window !== null) { window.Levenshtein = Levenshtein; } }());